1/*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the 'License');
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an 'AS IS' BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15import common from '@ohos.app.ability.common';
16import bundleManager from '@ohos.bundle.bundleManager';
17import hilog from '@ohos.hilog';
18import Want from '@ohos.app.ability.Want';
19import { BusinessError } from '@ohos.base';
20import util from '@ohos.util';
21
22const DOMAIN_ID = 0x3F3F;
23const TAG = 'TipsJump';
24const APP_BUNDLE_NAME = 'com.huawei.hmos.tips';
25const TIPS_APP_ID =
26  'com.huawei.hmos.tips_BB4oLXt8JLOw5djd42S0oLOGzO6kOnT8hZfFRAAel2gbcQBG5jIsO4genni5cn2SQpKpKvkwOA7Ajsc7qf+MZgM=';
27const MODULE_NAME_PHONE = 'phone_widget';
28const MODULE_NAME_PC = 'pc_widget';
29const URI_FORMATTER = 'hwtips://com.huawei.hmos.tips.app?funNum=%s&type=%s';
30const MODULE_NAME_APPGALLERY = 'com.huawei.hmsapp.appgallery';
31const URI_APPGALLERY = 'store://appgallery.huawei.com/app/detail?id=com.huawei.hmos.tips';
32const CODE_BUNDLE_NAME_NOT_FOUND = 17700001;
33const CODE_SUCCESS_ERROR = 0;
34const FUN_NUM_HOME = 'SF-20005815_f101';
35type startAbleContext = common.UIAbilityContext | common.ServiceExtensionContext;
36
37export class TipsJumpUtils {
38  /**
39   * Jump to Tips Home
40   *
41   * @param startAbleContext:common.UIAbilityContext | common.ServiceExtensionContext
42   * @param type: entry type ID, used for dotting
43   * @param moduleName: phone_widget: jump phone, pc_widget: jump pc
44   */
45  public static jumpHome(context: startAbleContext, type: string, moduleName: string = MODULE_NAME_PHONE) {
46    TipsJumpUtils.jumpTips(context, FUN_NUM_HOME, type, moduleName ?? MODULE_NAME_PHONE);
47  }
48
49  /**
50   * Jump to the specified page of Tips by FUN_NUM
51   *
52   * @param startAbleContext:common.UIAbilityContext | common.ServiceExtensionContext
53   * @param funNum: page FUN_NUM
54   * @param type: entry type ID, used for dotting
55   * @param moduleName: phone_widget: jump phone, pc_widget: jump pc
56   */
57  public static jumpTips(context: startAbleContext, funNum: string, type: string,
58                         moduleName: string = MODULE_NAME_PHONE) {
59    let uri = util.format(URI_FORMATTER, funNum, type);
60    TipsJumpUtils.jumpTipsByUri(context, uri, moduleName ?? MODULE_NAME_PHONE);
61  }
62
63  /**
64   * Jump to the specified page of Tips by uri
65   *
66   * @param startAbleContext:common.UIAbilityContext | common.ServiceExtensionContext
67   * @param uri: uri format:hwtips://com.huawei.hmos.tips.app?funNum=xxx&type=xxx
68   * @param moduleName: phone_widget: jump phone, pc_widget: jump pc
69   */
70  public static jumpTipsByUri(context: startAbleContext, uri: string, moduleName: string = MODULE_NAME_PHONE) {
71    if (moduleName !== MODULE_NAME_PHONE && moduleName !== MODULE_NAME_PC) {
72      hilog.error(DOMAIN_ID, TAG, `unknown moduleName, supported value:"${MODULE_NAME_PHONE}" or "${MODULE_NAME_PC}"`);
73      return;
74    }
75    TipsJumpUtils.isAppInstalled().then((isAppInstalled: boolean) => {
76      if (isAppInstalled) {
77        TipsJumpUtils.jumpAppByUri(context, uri);
78      } else {
79        TipsJumpUtils.jumpAppGallery(context);
80      }
81    })
82  }
83
84  /**
85   * Jump to Tips APP by uri
86   *
87   * @param startAbleContext:common.UIAbilityContext | common.ServiceExtensionContext
88   * @param uri: uri format:hwtips://com.huawei.hmos.tips.app?funNum=xxx&type=xxx
89   */
90  private static jumpAppByUri(context: startAbleContext, uri: string) {
91    hilog.info(DOMAIN_ID, TAG, 'try jump to tips app');
92    let want: Want = {
93      bundleName: APP_BUNDLE_NAME,
94      action: 'ohos.want.action.viewData',
95      entities: ['entity.system.browsable'],
96      uri
97    };
98    context.startAbility(want, (err: BusinessError) => {
99      if (err.code !== CODE_SUCCESS_ERROR) {
100        hilog.warn(DOMAIN_ID, TAG, 'jump to [tips app] failed, error: %{private}s', JSON.stringify(err));
101      } else {
102        hilog.info(DOMAIN_ID, TAG, 'jump to [tips app] success');
103      }
104    });
105  }
106
107  /**
108   * Jump to AppGallery by uri
109   *
110   * @param startAbleContext:common.UIAbilityContext | common.ServiceExtensionContext
111   */
112  private static jumpAppGallery(context: startAbleContext) {
113    hilog.info(DOMAIN_ID, TAG, 'try to jump to AppGallery');
114    const want: Want = { bundleName: MODULE_NAME_APPGALLERY, uri: URI_APPGALLERY };
115    context.startAbility(want).then(() => {
116      hilog.info(DOMAIN_ID, TAG, 'jump to AppGallery success');
117    }).catch(() => {
118      hilog.warn(DOMAIN_ID, TAG, 'jump to AppGallery error');
119    });
120  }
121
122  private static isAppInstalled(): Promise<boolean> {
123    return bundleManager.getBundleInfo(APP_BUNDLE_NAME, bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_SIGNATURE_INFO)
124      .then((info) => {
125        if (TIPS_APP_ID === info.signatureInfo.appId) {
126          hilog.info(DOMAIN_ID, TAG, 'tips app is installed');
127          return true;
128        } else {
129          hilog.warn(DOMAIN_ID, TAG, 'tips app is forged');
130          return false;
131        }
132      })
133      .catch((err: BusinessError) => {
134        if (err.code === CODE_BUNDLE_NAME_NOT_FOUND) {
135          hilog.info(DOMAIN_ID, TAG, 'tips app is not installed')
136        } else {
137          hilog.info(DOMAIN_ID, TAG, 'failed to check if tips app is installed, err: %{private}s', JSON.stringify(err));
138        }
139        return false;
140      })
141  }
142}