1/** 2 * Copyright (c) 2021-2022 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 */ 15 16import { Callback } from '@ohos.base'; 17import Router from '@system.router'; 18import deviceInfo from '@ohos.deviceInfo'; 19import bundle from '@ohos.bundle.bundleManager'; 20import Want from '@ohos.app.ability.Want'; 21import { BaseData } from '../../../../../../common/utils/src/main/ets/default/bean/BaseData'; 22import LogUtil from '../../../../../../common/utils/src/main/ets/default/baseUtil/LogUtil'; 23import { GlobalContext } from '../../../../../../common/utils/src/main/ets/default/baseUtil/GlobalContext'; 24import ApplicationInfoController from '../controller/application/ApplicationInfoController'; 25import ConfigData from '../../../../../../common/utils/src/main/ets/default/baseUtil/ConfigData'; 26import HeadComponent from '../../../../../../common/component/src/main/ets/default/headComponent'; 27import EntryComponent from '../../../../../../common/component/src/main/ets/default/entryComponent'; 28import { DialogButtonLayout } from '../../../../../../common/component/src/main/ets/default/dialogComponent'; 29import AppManagementModel from '../model/appManagementImpl/AppManagementModel'; 30 31const MODULE_TAG = ConfigData.TAG + 'application-> '; 32const deviceTypeInfo = deviceInfo.deviceType; 33 34/** 35 * Application Info 36 */ 37@Entry 38@Component 39struct ApplicationInfo { 40 tag: string = "ApplicationInfoSettings"; 41 @StorageLink('appInformation') appInfo: BaseData = { 42 settingIcon: "", 43 settingTitle: "", 44 settingValue: "", 45 settingArrow: "", 46 settingSummary: "", 47 settingBundleName: "", 48 settingIconId: "", 49 settingUri: "" 50 }; 51 @StorageLink('appManagement') mBundleInfoList: BaseData[] = []; 52 @State isPhoneOrRK: boolean = false; 53 @State isRemovableBundle: boolean = true; 54 @State isTouchedLeft: boolean = false; 55 @State isTouchedRight: boolean = false; 56 private controller: ApplicationInfoController = new ApplicationInfoController(); 57 private bundleName: string = " "; 58 showDialog: CustomDialogController | null = new CustomDialogController({ 59 builder: ShowDialog({ 60 action: () => { 61 this.controller.uninstall(this.bundleName); 62 } 63 }), 64 alignment: this.isPhoneOrRK ? DialogAlignment.Bottom : DialogAlignment.Center, 65 autoCancel: true, 66 offset: ({ dx: 0, dy: this.isPhoneOrRK ? '-24dp' : 0 }) 67 }); 68 69 build() { 70 Column() { 71 GridContainer({ gutter: ConfigData.GRID_CONTAINER_GUTTER_24, margin: ConfigData.GRID_CONTAINER_MARGIN_24 }) { 72 Column() { 73 HeadComponent({ headName: $r('app.string.applicationInfo'), isActive: true }); 74 75 Row() { 76 Image(this.appInfo.settingIcon) 77 .width($r('app.float.wh_value_64')) 78 .height($r('app.float.wh_value_64')) 79 .margin({ right: $r('app.float.distance_16'), left: $r('sys.float.ohos_id_card_margin_start') }) 80 81 Column() { 82 Text(this.appInfo.settingTitle) 83 .fontColor($r('app.color.font_color_182431')) 84 .fontSize($r('app.float.font_16')) 85 .margin({ top: $r('app.float.wh_value_10'), bottom: $r('app.float.wh_value_5') }) 86 87 Text(this.appInfo.settingSummary) 88 .fontColor($r('app.color.font_color_182431')) 89 .fontSize($r('app.float.font_14')) 90 .maxLines(ConfigData.MAX_LINES_1) 91 .margin({ bottom: $r('app.float.distance_11') }); 92 } 93 .alignItems(HorizontalAlign.Start) 94 .width(ConfigData.WH_100_100) 95 .height($r('app.float.wh_value_64')) 96 } 97 .width(ConfigData.WH_100_100) 98 .margin({ top: $r("app.float.distance_8") }) 99 100 Row() { 101 Button($r('app.string.uninstall')) 102 .fontSize($r('app.float.application_button_subtitle_size')) 103 .fontColor($r('app.color.font_color_007DFF')) 104 .layoutWeight(ConfigData.LAYOUT_WEIGHT_1) 105 .height($r('app.float.application_button_height')) 106 .visibility(this.isRemovableBundle ? Visibility.Visible : Visibility.Hidden) 107 .borderRadius($r('app.float.radius_20')) 108 .backgroundColor($r('sys.color.ohos_id_color_button_normal')) 109 .onClick(() => { 110 this.showDialog?.open(); 111 }) 112 113 Column() 114 .width($r('app.float.distance_24')) 115 .height($r('app.float.application_button_height')) 116 117 Button($r('app.string.forcedStop')) 118 .fontSize($r('app.float.application_button_subtitle_size')) 119 .fontColor($r('app.color.font_color_007DFF')) 120 .layoutWeight(ConfigData.LAYOUT_WEIGHT_1) 121 .height($r('app.float.application_button_height')) 122 .borderRadius($r('app.float.radius_20')) 123 .backgroundColor($r('sys.color.ohos_id_color_button_normal')) 124 .onClick(() => { 125 this.showPromptDialog(() => { 126 this.controller.killProcessesByBundleName(this.bundleName); 127 }); 128 }) 129 } 130 .alignItems(VerticalAlign.Center) 131 .width(ConfigData.WH_100_100) 132 .padding({ 133 top: $r('app.float.distance_24'), 134 bottom: $r('app.float.distance_36'), 135 left: $r('app.float.distance_24'), 136 right: $r('app.float.distance_24') 137 }) 138 139 Row() { 140 EntryComponent({ 141 settingIcon: '', 142 settingTitle: $r('app.string.storageTab'), 143 settingSummary: JSON.parse(JSON.stringify($r('app.string.store_description_information', ''))), 144 settingValue: '', 145 settingArrow: $r("app.string.ic_settings_arrow").toString(), 146 settingArrowStyle: '', 147 settingUri: '', 148 fontSize: $r('app.float.font_16'), 149 valueFontSize: $r('app.float.font_14') 150 }) 151 } 152 .padding({ top: $r('app.float.distance_4'), bottom: $r('app.float.distance_4') }) 153 .borderRadius($r('sys.float.ohos_id_corner_radius_default_l')) 154 .backgroundColor($r('app.color.white_bg_color')) 155 .onClick(() => { 156 Router.push({ uri: 'pages/applicationStorage', params: this.appInfo }); 157 }) 158 } 159 .useSizeType({ 160 sm: { span: 4, offset: 0 }, 161 md: { span: 6, offset: 1 }, 162 lg: { span: 8, offset: 2 } 163 }) 164 } 165 .width(ConfigData.WH_100_100) 166 .height(ConfigData.WH_100_100) 167 } 168 .backgroundColor($r("sys.color.ohos_id_color_sub_background")) 169 .width(ConfigData.WH_100_100) 170 .height(ConfigData.WH_100_100) 171 } 172 173 aboutToAppear(): void { 174 LogUtil.info(this.tag + " aboutToAppear start "); 175 if (deviceTypeInfo === 'phone' || deviceTypeInfo === 'default') { 176 this.isPhoneOrRK = true; 177 } else { 178 this.isPhoneOrRK = false; 179 } 180 181 this.getBundleName(); 182 this.updateRemovableStatus(this.bundleName); 183 LogUtil.info(this.tag + " aboutToAppear end "); 184 } 185 186 aboutToDisappear(): void { 187 this.showDialog = null; 188 } 189 190 getBundleName(): void { 191 let param = Router.getParams(); 192 if (param) { 193 this.bundleName = param.settingBundleName.toString(); 194 this.appInfo = param; 195 AppStorage.SetOrCreate('appInformation', param); 196 } 197 198 if (this.bundleName == ' ') { 199 let want = GlobalContext.getContext().getObject(GlobalContext.globalKeyAbilityWant) as Want; 200 if (want?.action === 'action.settings.app.info') { 201 this.bundleName = want?.parameters?.settingsParamBundleName as string; 202 let bundleList: bundle.BundleInfo[] = []; 203 bundle.getBundleInfo(this.bundleName, bundle.BundleFlag.GET_BUNDLE_INFO_WITH_ABILITY) 204 .then((data) => { 205 bundleList[0] = data; 206 AppManagementModel.getResourceItem(0, 1, bundleList) 207 .then(() => { 208 let appMgrList = AppStorage.Get('appManagementList') as BaseData[]; 209 if (appMgrList) { 210 this.mBundleInfoList = appMgrList; 211 } 212 this.appInfo = this.mBundleInfoList[0]; 213 AppStorage.SetOrCreate('appInformation', this.mBundleInfoList[0]); 214 }) 215 }); 216 } 217 } 218 } 219 220 onBackPress() { 221 LogUtil.info('settings ApplicationInfo onBackPress'); 222 } 223 224 /** 225 * Stop exception prompt Dialog 226 */ 227 showPromptDialog(callback: Callback<void>) { 228 AlertDialog.show({ 229 message: $r("app.string.Stop_exception_prompt"), 230 primaryButton: { 231 value: $r('app.string.cancel'), 232 action: () => { 233 LogUtil.info(ConfigData.TAG + 'Closed callbacks'); 234 } 235 }, 236 secondaryButton: { 237 value: $r('app.string.forcedStop'), 238 action: () => { 239 LogUtil.info(ConfigData.TAG + `AlertDialog success:`); 240 callback(); 241 } 242 }, 243 alignment: this.isPhoneOrRK ? DialogAlignment.Bottom : DialogAlignment.Center, 244 offset: ({ dx: 0, dy: this.isPhoneOrRK ? '-24dp' : 0 }) 245 }) 246 } 247 248 updateRemovableStatus(bundleName: string) { 249 this.controller.getBundleInfo(bundleName, (err: Error, result: bundle.BundleInfo) => { 250 if (err) { 251 LogUtil.info(MODULE_TAG + 'get system bundle info failed'); 252 } else { 253 LogUtil.info(MODULE_TAG + `${bundleName} is removeable = ${result.appInfo.removable}`); 254 if (result.appInfo.removable !== true) { 255 this.isRemovableBundle = false; 256 } 257 } 258 }); 259 } 260} 261 262/** 263 * Show dialog 264 */ 265@CustomDialog 266struct ShowDialog { 267 dialogController?: CustomDialogController; 268 @StorageLink('appInformation') appInfo: BaseData = { 269 settingIcon: "", 270 settingTitle: "", 271 settingValue: "", 272 settingArrow: "", 273 settingSummary: "", 274 settingBundleName: "", 275 settingIconId: "", 276 settingUri: "" 277 }; 278 private uirBack: string = 'pages/appManagement'; 279 action: () => void = () => { 280 }; 281 282 build() { 283 Column() { 284 Image(`${this.appInfo.settingIcon}`) 285 .height($r("app.float.application_common_size")) 286 .width($r("app.float.application_common_size")) 287 .margin({ 288 top: $r('app.float.item_common_vertical_margin'), 289 bottom: $r('app.float.item_common_vertical_margin') 290 }) 291 292 Text(`${this.appInfo.settingTitle}`) 293 .fontSize($r('app.float.font_18')) 294 .align(Alignment.Center) 295 .margin({ bottom: $r('app.float.item_common_vertical_margin') }) 296 297 Text($r("app.string.uninstall_prompt")) 298 .fontSize($r('app.float.font_18')) 299 .align(Alignment.Center) 300 .margin({ bottom: $r('app.float.item_common_vertical_margin') }) 301 302 // button 303 DialogButtonLayout({ 304 secondTitle: $r('app.string.uninstall'), 305 firstClickEvent: () => { 306 if (this.dialogController) { 307 this.dialogController.close(); 308 } 309 }, 310 secondClickEvent: () => { 311 this.action(); 312 if (this.dialogController) { 313 this.dialogController.close(); 314 } 315 Router.back({ uri: this.uirBack }); 316 } 317 }) 318 } 319 .alignItems(HorizontalAlign.Center) 320 .width(ConfigData.WH_100_100); 321 } 322}