!458 无障碍扩展服务管理功能合入

Merge pull request !458 from wangxinqiang007/master
This commit is contained in:
openharmony_ci 2023-07-26 10:12:10 +00:00 committed by Gitee
commit a52f8ce3f6
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
10 changed files with 1144 additions and 2 deletions

View File

@ -0,0 +1,110 @@
/**
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Router from '@system.router';
import ConfigData from '../../../../../../common/utils/src/main/ets/default/baseUtil/ConfigData';
import SettingListModel from '../../../../../../product/phone/src/main/ets/model/settingListImpl/SettingListModel';
import prompt from '@ohos.prompt'
@Component
export struct ServiceItemComponent {
private targetPage: string;
private serviceTitle: string | Resource;
private serviceEndText: string;
private serviceIcon: string | Resource;
@State touched: boolean = false;
onPageShow() {
console.info(`onPageShow: ${this.targetPage}`)
}
aboutToAppear(): void {
console.info(`aboutToAppear: ${this.targetPage}`)
}
build() {
Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {
Row() {
Image(this.serviceIcon)
.width($r('app.float.wh_value_24'))
.height($r('app.float.wh_value_24'))
.margin({
left: $r('app.float.distance_8'),
top: $r('app.float.distance_15'),
bottom: $r('app.float.distance_17')
})
Text(this.serviceTitle)
.fontSize($r('app.float.font_16'))
.lineHeight($r('app.float.lineHeight_22'))
.fontWeight(FontWeight.Medium)
.fontFamily('HarmonyHeiTi')
.fontColor($r('sys.color.ohos_id_color_text_primary'))
.align(Alignment.Start)
.margin({
left: $r('app.float.distance_16'),
top: $r('app.float.distance_17'),
bottom: $r('app.float.distance_17')
})
}
.align(Alignment.Start)
.height(ConfigData.WH_100_100)
Row() {
Text(this.serviceEndText)
.fontSize($r('app.float.font_14'))
.lineHeight($r('app.float.lineHeight_19'))
.align(Alignment.End)
.fontWeight(FontWeight.Regular)
.fontFamily('HarmonyHeiTi')
.fontColor($r('sys.color.ohos_id_color_text_secondary'))
.margin({ top: $r('app.float.distance_19'), bottom: $r('app.float.distance_18') });
Image('/res/image/ic_settings_arrow.svg')
.width($r('app.float.wh_value_12'))
.height($r('app.float.wh_value_24'))
.margin({
left: $r('app.float.distance_4'),
right: $r('app.float.distance_8'),
top: $r('app.float.distance_16'),
bottom: $r('app.float.distance_16')
})
.fillColor($r('sys.color.ohos_id_color_fourth'))
}
.align(Alignment.End)
.height(ConfigData.WH_100_100);
}
.width(ConfigData.WH_100_100)
.height($r('app.float.wh_value_56'))
.borderRadius($r('app.float.radius_20'))
.linearGradient(this.touched ? {
angle: 90,
direction: GradientDirection.Right,
colors: [[$r('app.color.DCEAF9'), 0.0], [$r('app.color.FAFAFA'), 1.0]]
} : {
angle: 90,
direction: GradientDirection.Right,
colors: [[$r('sys.color.ohos_id_color_foreground_contrary'), 1], [$r('sys.color.ohos_id_color_foreground_contrary'), 1]]
})
.onTouch((event: TouchEvent) => {
if (event.type === TouchType.Down) {
this.touched = true;
}
if (event.type === TouchType.Up) {
this.touched = false;
}
})
}
}

View File

@ -137,4 +137,71 @@ export struct SubEntryComponentWithEndText {
.borderRadius($r('app.float.radius_24'))
.backgroundColor($r("sys.color.ohos_id_color_foreground_contrary"));
}
}
/**
* Sub-Page Entry Component with StateText
*/
@Component
export struct SubEntryComponentWithText {
@State isTouched: boolean = false;
private endStateText: Resource;
private targetPage: string;
private title: string | Resource;
build() {
Navigator({ target: this.targetPage }) {
Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {
Row() {
Text(this.title)
.fontSize($r('app.float.font_16'))
.lineHeight($r('app.float.wh_value_22'))
.fontWeight(FontWeight.Medium)
.fontColor($r('app.color.font_color_182431'))
.margin({ left: $r('app.float.distance_8') })
.textAlign(TextAlign.Start);
}
Row() {
Text(this.endStateText)
.fontSize($r('app.float.font_14'))
.lineHeight($r('app.float.wh_value_19'))
.fontWeight(FontWeight.Regular)
.fontColor($r('sys.color.ohos_id_color_text_secondary'))
.margin({ right: $r('app.float.distance_4') })
.textAlign(TextAlign.End);
Image('/res/image/ic_settings_arrow.svg')
.width($r('app.float.wh_value_12'))
.height($r('app.float.wh_value_24'))
.margin({ right: $r('app.float.distance_8') })
.fillColor($r("sys.color.ohos_id_color_primary"))
.opacity($r("app.float.opacity_0_2"))
}
}
.height(ComponentConfig.WH_100_100)
.width(ComponentConfig.WH_100_100)
.borderRadius($r('app.float.radius_20'))
.linearGradient(this.isTouched ? {
angle: 90,
direction: GradientDirection.Right,
colors: [[$r('app.color.FAFAFA'), 0.0], [$r('app.color.FAFAFA'), 1.0]]
} : {
angle: 90,
direction: GradientDirection.Right,
colors: [[$r('sys.color.ohos_id_color_foreground_contrary'), 1], [$r('sys.color.ohos_id_color_foreground_contrary'), 1]]
})
.onTouch((event: TouchEvent) => {
if (event.type === TouchType.Down) {
this.isTouched = true;
}
if (event.type === TouchType.Up) {
this.isTouched = false;
}
});
}
.padding($r('app.float.distance_4'))
.height($r('app.float.wh_value_56'))
.borderRadius($r('app.float.radius_24'))
.backgroundColor($r('sys.color.ohos_id_color_foreground_contrary'));
}
}

View File

@ -0,0 +1,185 @@
/**
* Copyright (c) 2023-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Bundle from '@ohos.bundle';
import appManager from '@ohos.application.appManager';
import bundleManager from '@ohos.bundle.bundleManager';
import accessibility from '@ohos.accessibility';
import BaseModel from '../../../../../../../common/utils/src/main/ets/default/model/BaseModel';
import LogUtil from '../../../../../../../common/utils/src/main/ets/default/baseUtil/LogUtil';
import ConfigData from '../../../../../../../common/utils/src/main/ets/default/baseUtil/ConfigData';
const INDEX = 0;
const URI_PAGE = 'pages/accessibilityServiceInfo';
let icon_arrow = $r('app.media.ic_settings_arrow');
let icon_default = "ohos_app_icon";
let icon_default_str = "";
const MODULE_TAG = ConfigData.TAG + 'extensionService-> ';
/**
* app management service class
*/
export class ExtensionServiceManagementModel extends BaseModel {
private mBundleInfoList: any[] = [];
private serviceInfoList: any[] = [];
constructor() {
super();
try {
globalThis.settingsAbilityContext.resourceManager.getMediaBase64ByName(icon_default).then((res) => {
icon_default_str = res;
LogUtil.info(MODULE_TAG + 'getResourceManager init defaultIcon res:' + JSON.stringify(icon_default_str));
}).catch((err) => {
icon_default_str = '';
LogUtil.info(MODULE_TAG + 'getResourceManager init defaultIcon error:' + JSON.stringify(err));
});
} catch (err) {
icon_default_str = '';
LogUtil.info(MODULE_TAG + 'getResourceManager init defaultIcon error:' + JSON.stringify(err));
}
}
/**
* get extensionService data
*/
setExtensionServiceManagementListener() {
this.serviceInfoList = [];
accessibility.getAccessibilityExtensionList('all', 'install').then((data) => {
LogUtil.info(MODULE_TAG + 'extensionService data.length: ' + data.length + 'data: ' + JSON.stringify(data));
this.getResourceItemAndState(INDEX, data.length, data);
}).catch((err) => {
LogUtil.error(MODULE_TAG + 'getExtensionServiceList failed, err: ' + JSON.stringify(err));
});
}
/**
* get resource information according to resource id
*
* @param index - array position
* @param count - array length
* @param data - data
*/
async getResourceItemAndState(index, count, data) {
LogUtil.info(MODULE_TAG + 'getIconItem start data.length: ' + data.length);
let imageValue = '';
let description: ResourceStr;
let enabledServiceList: Array<accessibility.AccessibilityAbilityInfo> = await accessibility.getAccessibilityExtensionList('all', 'enable');
for (let serviceInfo of data) {
if (!serviceInfo || !serviceInfo.id) {
continue;
}
LogUtil.info(MODULE_TAG + 'extensionService name :' + JSON.stringify(serviceInfo.id));
let serviceState: boolean = false;
for (let enabledService of enabledServiceList) {
if (enabledService.id && enabledService.id === serviceInfo.id) {
serviceState = true;
break;
}
}
LogUtil.info(MODULE_TAG + JSON.stringify(serviceInfo.name) + ': ' + JSON.stringify(serviceState));
let bundleFlag: number = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION | bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_HAP_MODULE | bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_EXTENSION_ABILITY;
let bundleInfo: bundleManager.BundleInfo = await bundleManager.getBundleInfo(serviceInfo.bundleName, bundleFlag);
imageValue = await this.loadIcon(bundleInfo);
description = await this.loadDescription(bundleInfo, serviceInfo.name);
LogUtil.info(MODULE_TAG + 'getResourceManager getMediaBase64() value:' + imageValue);
this.serviceInfoList.push({
serviceIcon: imageValue,
serviceTitle: serviceInfo.name,
serviceArrow: icon_arrow,
serviceSummary: description,
serviceEndText: serviceState ? $r('app.string.enabled') : $r('app.string.disabled'),
serviceState: serviceState,
serviceId: serviceInfo.id,
serviceBundleName: serviceInfo.bundleName,
serviceUri: URI_PAGE,
});
}
AppStorage.SetOrCreate('extensionServiceManagementList', this.serviceInfoList);
LogUtil.info(MODULE_TAG + 'loadExtensionService end');
}
/**
* Load icon of AccessibilityService
*/
async loadIcon(bundleInfo: bundleManager.BundleInfo): Promise<string> {
let appInfo = bundleInfo.appInfo;
let imageValue = '';
let context = globalThis.settingsAbilityContext;
LogUtil.info(MODULE_TAG + 'getResourceManager appInfo.iconResource:' + JSON.stringify(appInfo.iconResource));
if (appInfo.iconResource.id > 0) {
imageValue = await context.resourceManager.getMediaBase64(appInfo.iconResource);
if (!imageValue) {
LogUtil.warn(MODULE_TAG + 'load icon invalid');
imageValue = icon_default_str;
}
LogUtil.info(MODULE_TAG + 'getResourceManager loadIcon end');
return imageValue;
}
imageValue = icon_default_str;
return imageValue;
}
/**
* Load description of AccessibilityService
*/
async loadDescription(bundleInfo: bundleManager.BundleInfo, serviceName: string): Promise<ResourceStr> {
let description: ResourceStr = $r('app.string.no_description_provided');
let context = globalThis.settingsAbilityContext;
let moduleInfo: Array<bundleManager.HapModuleInfo> = bundleInfo.hapModulesInfo;
if (moduleInfo.length > 0) {
for (let hapInfo of moduleInfo) {
for (let ability of hapInfo.extensionAbilitiesInfo) {
if (ability.name === serviceName && ability.descriptionId > 0) {
description = await context.resourceManager.getString(ability.descriptionId);
if (!description) {
LogUtil.warn(MODULE_TAG + 'load description invalid');
description = $r('app.string.no_description_provided');
}
LogUtil.info(MODULE_TAG + 'load description end');
return description;
}
}
}
}
return description;
}
/**
* Clear up application data by bundle name
* @param bundleName bundle name
*/
clearUpExtensionServiceData(bundleName: string, callback) {
appManager.clearUpApplicationData(bundleName, callback);
}
/**
* Clears cache data of a specified application.
* @param bundleName bundle name
*/
cleanBundleCacheFiles(bundleName: string, callback) {
Bundle.cleanBundleCacheFiles(bundleName, callback);
}
getBundleInfo(bundleName, callback) {
LogUtil.info(MODULE_TAG + 'start get bundle info');
Bundle.getBundleInfo(bundleName, Bundle.BundleFlag.GET_APPLICATION_INFO_WITH_PERMISSION, callback);
LogUtil.info(MODULE_TAG + 'end get bundle info');
}
}
let extensionServiceManagementModel = new ExtensionServiceManagementModel();
export default extensionServiceManagementModel as ExtensionServiceManagementModel;

View File

@ -14,12 +14,14 @@
*/
import config from '@ohos.accessibility.config';
import accessibility from '@ohos.accessibility';
import LogUtil from '../../../../../../common/utils/src/main/ets/default/baseUtil/LogUtil';
import Log from '../../../../../../common/utils/src/main/ets/default/baseUtil/LogDecorator';
import ConfigData from '../../../../../../common/utils/src/main/ets/default/baseUtil/ConfigData';
import HeadComponent from '../../../../../../common/component/src/main/ets/default/headComponent';
import { SubHeader } from '../../../../../../common/component/src/main/ets/default/textComponent';
import { AccessibilitySettingModel } from '../model/accessibilityImpl/AccessibilitySettingModel';
import { SubEntryComponentWithText } from '../../../../../../common/component/src/main/ets/default/subEntryComponent';
const AUDIO_BALANCE_STEP_VALUE: number = 1;
const AUDIO_BALANCE_MIN_VALUE: number = -100;
@ -34,6 +36,7 @@ struct AccessibilitySettings {
@State highContrastTextIsOn: boolean = false;
@State audioMonoIsOn: boolean = false;
@State inSetValueAudioBalance: number = 0;
@State serviceNum: number = 0;
private TAG = ConfigData.TAG + 'AccessibilitySettings ';
build() {
@ -162,7 +165,7 @@ struct AccessibilitySettings {
}
.width(ConfigData.WH_100_100)
.borderRadius($r('app.float.radius_24'))
.backgroundColor($r("sys.color.ohos_id_color_foreground_contrary"));
.backgroundColor($r('sys.color.ohos_id_color_foreground_contrary'));
Text($r('app.string.audio_balance_suggestion'))
.width(ConfigData.WH_100_100)
@ -175,6 +178,25 @@ struct AccessibilitySettings {
top: $r('app.float.distance_4'),
bottom: $r('app.float.distance_24'),
});
SubHeader({ titleContent: $r('app.string.extension_service') });
if (this.serviceNum > 0) {
SubEntryComponentWithText({
targetPage: 'pages/serviceManagement',
title: $r('app.string.installed_service'),
endStateText: $r('app.string.service_number', this.serviceNum)
})
.margin({ top: $r("app.float.distance_8") })
} else {
SubEntryComponentWithText({
targetPage: 'pages/serviceManagement',
title: $r('app.string.installed_service'),
endStateText: $r('app.string.no_service')
})
.margin({ top: $r("app.float.distance_8") })
.enabled(false);
}
}
.useSizeType({
sm: { span: 4, offset: 0 },
@ -220,7 +242,7 @@ struct AccessibilitySettings {
}
@Log
aboutToAppear(): void{
aboutToAppear(): void {
LogUtil.info(this.TAG + 'aboutToAppear in');
config.highContrastText.get().then((data) => {
LogUtil.info(this.TAG + 'get highContrastText switch success');
@ -243,6 +265,14 @@ struct AccessibilitySettings {
LogUtil.error(this.TAG + 'failed to get audioBalance, because ' + JSON.stringify(err));
});
accessibility.getAccessibilityExtensionList('all', 'install').then((data) => {
LogUtil.info(this.TAG + 'get accessibilityAbilityList success, service length: ' + JSON.stringify(data.length));
if (data.length > 0) {
this.serviceNum = data.length;
}
}).catch((err) => {
LogUtil.error(this.TAG + 'failed to get accessibilityAbilityList, because ' + JSON.stringify(err));
})
LogUtil.info(this.TAG + 'aboutToAppear out');
}

View File

@ -0,0 +1,411 @@
/**
* Copyright (c) 2023-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Router from '@system.router';
import deviceInfo from '@ohos.deviceInfo';
import accessibility from '@ohos.accessibility';
import config from '@ohos.accessibility.config';
import LogUtil from '../../../../../../common/utils/src/main/ets/default/baseUtil/LogUtil';
import Log from '../../../../../../common/utils/src/main/ets/default/baseUtil/LogDecorator';
import ConfigData from '../../../../../../common/utils/src/main/ets/default/baseUtil/ConfigData';
import HeadComponent from '../../../../../../common/component/src/main/ets/default/headComponent';
import ComponentConfig from '../../../../../../common/component/src/main/ets/default/ComponentConfig';
const MODULE_TAG = ConfigData.TAG + 'service-> ';
const DEVICE_TYPE = deviceInfo.deviceType;
class ServiceInfoData {
serviceIcon: string = '';
serviceTitle:string = '';
serviceArrow: string = '';
serviceSummary: string = '';
serviceEndText: string = '';
serviceState: boolean = false;
serviceId: string = '';
serviceBundleName: string = '';
serviceUri:string = '';
}
/**
* AccessibilityService Info
*/
@Entry
@Component
struct AccessibilityServiceInfo {
tag: string = 'AccessibilityServiceInfoSettings';
isPhoneOrRK: boolean = true;
bundleName: string = '';
serviceName: string = '';
capabilities: Array<accessibility.Capability> = ['retrieve', 'keyEventObserver', 'gesture', 'zoom', 'touchGuide'];
@State serviceIsOn: boolean = false;
@State pageChanged: boolean = false;
@StorageLink('accessibilityServiceInfo') serviceInfo: ServiceInfoData = {
serviceIcon: '',
serviceTitle: '',
serviceArrow: '',
serviceSummary: '',
serviceEndText: '',
serviceState: false,
serviceId: '',
serviceBundleName: '',
serviceUri: ''
};
showDialog: CustomDialogController = new CustomDialogController({
builder: ShowDialog({
firstClickAction: () => {
this.enableAbility(this.serviceInfo.serviceId);
},
secondClickAction: () => {
this.cancelButton();
},
}),
alignment: this.isPhoneOrRK ? DialogAlignment.Bottom : DialogAlignment.Center,
autoCancel: false,
offset: ({ dx: 0, dy: this.isPhoneOrRK ? '-12dp' : 0 })
});
build() {
Column() {
GridContainer({ gutter: ConfigData.GRID_CONTAINER_GUTTER_24, margin: ConfigData.GRID_CONTAINER_MARGIN_24 }) {
Column() {
HeadComponent({ headName: this.serviceInfo.serviceTitle, isActive: true });
Column() {
Row() {
Text(this.serviceInfo.serviceTitle)
.fontSize($r('sys.float.ohos_id_text_size_body1'))
.fontColor($r('sys.color.ohos_id_color_text_primary'))
.fontWeight(FontWeight.Medium)
.textAlign(TextAlign.Start);
Blank();
if (this.pageChanged) {
Toggle({ type: ToggleType.Switch, isOn: this.serviceIsOn })
.width('36vp')
.height('20vp')
.selectedColor('#007DFF')
.onChange((isOn: boolean) => {
this.setExtensionServiceState(isOn);
});
} else {
Toggle({ type: ToggleType.Switch, isOn: this.serviceIsOn })
.width('36vp')
.height('20vp')
.selectedColor('#007DFF')
.onChange((isOn: boolean) => {
this.setExtensionServiceState(isOn);
});
}
}
.height($r('app.float.wh_value_56'))
.width(ConfigData.WH_100_100)
.alignItems(VerticalAlign.Center)
.padding({ left: $r( 'app.float.wh_value_12'), right: $r('app.float.wh_value_6') })
.backgroundColor($r('app.color.white_bg_color'))
.borderRadius($r('app.float.radius_24'));
Blank(4);
Row() {
Text($r('app.string.more_settings'))
.fontSize($r('sys.float.ohos_id_text_size_body1'))
.fontColor($r('sys.color.ohos_id_color_text_primary'))
.fontWeight(FontWeight.Medium)
.textAlign(TextAlign.Start);
Blank();
Image('/res/image/ic_settings_arrow.svg')
.width($r('app.float.wh_value_12'))
.height($r('app.float.wh_value_24'))
.margin({ right: $r('app.float.distance_8') })
.fillColor($r('sys.color.ohos_id_color_primary'))
.opacity($r('sys.float.ohos_fa_alpha_content_fourth'))
}
.height($r('app.float.wh_value_56'))
.width(ConfigData.WH_100_100)
.alignItems(VerticalAlign.Center)
.padding({ left: $r('app.float.wh_value_12'), right: $r('app.float.wh_value_6') })
.enabled(false)
.backgroundColor($r('app.color.white_bg_color'))
.borderRadius($r('app.float.radius_24'));
Blank(20);
Text($r('app.string.help'))
.width(ConfigData.WH_100_100)
.fontSize($r('app.float.font_14'))
.fontColor($r('sys.color.ohos_id_color_text_secondary'))
.height($r('app.float.wh_value_52'))
.lineHeight($r('app.float.wh_value_20'))
.padding({
left: $r('app.float.wh_value_12'),
top: $r('app.float.distance_4'),
bottom: $r('app.float.distance_24'),
});
Text(this.serviceInfo.serviceSummary)
.width(ConfigData.WH_100_100)
.fontSize($r('app.float.font_14'))
.fontColor($r('sys.color.ohos_id_color_text_secondary'))
.height($r('app.float.wh_value_52'))
.lineHeight($r('app.float.wh_value_20'))
.padding({
left: $r('app.float.wh_value_12'),
top: $r('app.float.distance_4'),
bottom: $r('app.float.distance_24'),
});
}
.useSizeType({
sm: { span: 4, offset: 0 },
md: { span: 6, offset: 1 },
lg: { span: 8, offset: 2 }
})
}
}
.width(ConfigData.WH_100_100)
.height(ConfigData.WH_100_100)
}
.backgroundColor($r("sys.color.ohos_id_color_sub_background"))
.width(ConfigData.WH_100_100)
.height(ConfigData.WH_100_100)
}
@Log
aboutToAppear(): void{
LogUtil.info(this.tag + ' aboutToAppear start ');
if (DEVICE_TYPE === 'phone' || DEVICE_TYPE === 'default') {
this.isPhoneOrRK = true;
} else {
this.isPhoneOrRK = false;
}
this.getServiceName();
LogUtil.info(this.tag + " aboutToAppear end ");
}
getServiceName(): void {
let param;
param = Router.getParams();
if (param) {
LogUtil.info(this.tag + 'param is valid');
this.bundleName = param.serviceBundleName;
this.serviceInfo = param;
this.serviceName = param.serviceServiceId;
this.serviceIsOn = param.serviceState;
AppStorage.SetOrCreate('ServiceInformation', param);
}
LogUtil.error(this.tag + 'param is invalid');
}
setExtensionServiceState(isOn: boolean): void {
LogUtil.info(this.tag + 'setExtensionServiceState ' + isOn);
LogUtil.info(this.tag + 'serviceState: ' + JSON.stringify(this.serviceIsOn));
if (isOn) {
this.showDialog.open();
} else {
this.disableAbility(this.serviceInfo.serviceId);
}
}
enableAbility(abilityName: string): void {
config.enableAbility(abilityName, this.capabilities).then(() => {
LogUtil.info(this.tag + 'enable accessibilityService success');
this.serviceIsOn = true;
}).catch((err) => {
this.serviceIsOn = false;
this.pageChanged = !this.pageChanged;
LogUtil.error(this.tag + 'failed to enable accessibilityService, because ' + JSON.stringify(err));
})
}
disableAbility(abilityName: string): void {
config.disableAbility(abilityName).then(() => {
LogUtil.info(MODULE_TAG + 'disable accessibilityService success');
this.serviceIsOn = false;
}).catch((err) => {
LogUtil.error(MODULE_TAG + 'disable accessibilityService failed, error: ' + JSON.stringify(err));
});
}
cancelButton(): void {
this.serviceIsOn = false;
this.pageChanged = !this.pageChanged;
LogUtil.info(MODULE_TAG + 'cancel: serviceStatus ' + JSON.stringify(this.serviceIsOn));
}
}
/**
* Show dialog
*/
@CustomDialog
struct ShowDialog {
dialogController: CustomDialogController;
firstClickAction: () => void;
secondClickAction: () => void;
@State @Watch("freezeView")
private countDownTime: number = 10000;
@State freezingTimeForView: number = -1;
@State userApproval: boolean = false;
@State title: Resource = $r('app.string.user_approval_remain_times', 10);
@State enableState: boolean = false;
build() {
Column() {
Blank(2);
Text($r('app.string.accessibility_security_notification'))
.width(ConfigData.WH_100_100)
.fontSize($r('app.float.font_24'))
.fontColor($r('sys.color.ohos_id_color_text_secondary'))
.padding({
left: $r('app.float.wh_value_12'),
top: $r('app.float.distance_4'),
bottom: $r('app.float.distance_24'),
});
Text($r('app.string.accessibility_notify_content'))
.width(ConfigData.WH_100_100)
.fontSize($r('app.float.font_18'))
.fontColor($r('sys.color.ohos_id_color_text_secondary'))
.padding({
left: $r('app.float.wh_value_12'),
top: $r('app.float.distance_4'),
bottom: $r('app.float.distance_24'),
});
Text($r('app.string.accessibility_risk_detail'))
.width(ConfigData.WH_100_100)
.fontSize($r('app.float.font_20'))
.fontColor($r('sys.color.ohos_id_color_text_secondary'))
.padding({
left: $r('app.float.wh_value_12'),
top: $r('app.float.distance_4'),
bottom: $r('app.float.distance_24'),
});
Text($r('app.string.accessibility_risk_content'))
.width(ConfigData.WH_100_100)
.fontSize($r('app.float.font_18'))
.fontColor($r('sys.color.ohos_id_color_text_secondary'))
.padding({
left: $r('app.float.wh_value_12'),
top: $r('app.float.distance_4'),
bottom: $r('app.float.distance_24'),
});
// checkbox
Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center}) {
Checkbox()
.select(false)
.selectedColor('#4C89F0')
.onChange((value: boolean) => {
this.updateUserApproval(value);
})
Text($r('app.string.accessibility_user_approval'))
.fontSize($r('app.float.font_18'))
.baselineOffset(-20)
.margin({ bottom: $r('app.float.item_common_vertical_margin') })
}
Button($r('app.string.accessibility_disable'))
.backgroundColor($r('app.color.font_color_007DFF'))
.fontSize($r("app.float.font_20"))
.fontColor(Color.White)
.fontWeight(FontWeight.Medium)
.width(ComponentConfig.WH_50_100)
.onClick((event) => this.cancelEvent())
Divider()
.color($r('sys.color.ohos_id_color_list_separator'))
.vertical(true)
.height($r('app.float.wh_value_10'))
.opacity($r('app.float.opacity_0_2'))
Button(this.title)
.backgroundColor(Color.White)
.fontSize($r("app.float.font_20"))
.fontColor(Color.Red)
.fontWeight(FontWeight.Medium)
.width(ComponentConfig.WH_50_100)
.enabled(this.enableState)
.opacity(this.enableState ? 1 : 0.5)
.onClick((event) => this.confirmEvent())
}
.alignItems(HorizontalAlign.Center)
.width(ConfigData.WH_100_100);
}
updateUserApproval(value: boolean): void {
this.userApproval = value;
this.getEnableButtonState();
}
getUserApproval(): boolean {
return this.userApproval;
}
getEnableButtonState(): void {
if (this.freezingTimeForView <= 0 && this.userApproval) {
this.enableState = true;
} else {
this.enableState = false;
}
}
updateButtonTitle(): void {
this.getEnableButtonState();
if (this.freezingTimeForView > 0) {
this.title = $r('app.string.user_approval_remain_times', this.freezingTimeForView);
} else {
this.title = $r('app.string.accessibility_enable');
}
}
cancelEvent(): void {
LogUtil.info(MODULE_TAG + 'Cancel enable accessibility service');
this.secondClickAction();
this.freezingTimeForView = -1;
this.dialogController.close();
}
confirmEvent(): void {
LogUtil.info(MODULE_TAG + 'Confirm enable accessibility service');
this.firstClickAction();
this.dialogController.close();
}
@Log
async freezeView() {
if (this.countDownTime <= 0) {
return;
}
this.freezingTimeForView = this.countDownTime / 1000;
while (this.freezingTimeForView > 0) {
await Sleep(1000);
LogUtil.info(MODULE_TAG + 'time left: ' + JSON.stringify(this.freezingTimeForView));
this.freezingTimeForView -= 1;
this.updateButtonTitle();
}
}
aboutToAppear(): void {
this.freezeView();
}
aboutToDisappear(): void {
this.freezingTimeForView = -1;
}
}
export const Sleep = (ms)=> {
return new Promise(resolve=>setTimeout(resolve, ms))
}

View File

@ -0,0 +1,129 @@
/**
* Copyright (c) 2023-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Router from '@system.router';
import ExtensionServiceManagementModel from '../model/accessibilityImpl/ExtensionServiceManagementModel';
import LogUtil from '../../../../../../common/utils/src/main/ets/default/baseUtil/LogUtil';
import ConfigData from '../../../../../../common/utils/src/main/ets/default/baseUtil/ConfigData';
import HeadComponent from '../../../../../../common/component/src/main/ets/default/headComponent';
import ResourceUtil from '../../../../../../common/search/src/main/ets/default/common/ResourceUtil';
import { ServiceItemComponent } from '../../../../../../common/component/src/main/ets/default/serviceItemComponent';
import ImageAnimatorComponent from '../../../../../../common/component/src/main/ets/default/imageAnimatorComponent';
const MODULE_TAG = ConfigData.TAG + 'serviceManagement-> ';
/**
* application list
*/
@Entry
@Component
struct extensionServiceManagement {
@StorageLink('extensionServiceManagementList') serviceList: any[] = [];
private whtl: string = '80vp';
build() {
Column() {
GridContainer({ gutter: ConfigData.GRID_CONTAINER_GUTTER_24, margin: ConfigData.GRID_CONTAINER_MARGIN_24 }) {
Column() {
HeadComponent({ headName: $r('app.string.installed_service'), isActive: true });
if (this.serviceList.length <= 0) {
ImageAnimatorComponent({
imageWidth: $r('app.float.wh_value_80'),
imageHeight: $r('app.float.wh_value_80'), whtl: this.whtl
})
.margin({ top: $r("app.float.distance_8") })
.zIndex(1)
.align(Alignment.Center)
.padding({ top: ConfigData.WH_35_100 })
.width(ConfigData.WH_100_100)
.height(ConfigData.WH_100_100);
}
Column() {
List() {
ForEach(this.serviceList, (item) => {
ListItem() {
ServiceItemComponent({
targetPage: item.serviceUri,
serviceIcon: item.serviceIcon,
serviceTitle: item.serviceTitle,
serviceEndText: item.serviceEndText
});
}
.onClick(() => {
Router.push({ uri: item.serviceUri, params: item });
})
.height($r('app.float.wh_value_72'));
}, item => JSON.stringify(item));
}
.borderRadius($r("app.float.radius_24"))
.divider({
strokeWidth: 1,
color: $r('app.color.color_E3E3E3_grey'),
startMargin: $r('app.float.wh_value_65'),
endMargin: $r('sys.float.ohos_id_card_margin_end')
})
.visibility(this.serviceList.length > 0 ? Visibility.Visible : Visibility.None)
.zIndex(0);
}
.layoutWeight(ConfigData.LAYOUT_WEIGHT_1)
.borderRadius($r("app.float.radius_24"))
.backgroundColor($r("app.color.white_bg_color"))
.padding($r('app.float.distance_4'))
}
.useSizeType({
sm: { span: 4, offset: 0 },
md: { span: 6, offset: 1 },
lg: { span: 8, offset: 2 }
})
}
.width(ConfigData.WH_100_100)
.height(ConfigData.WH_100_100)
}
.backgroundColor($r("sys.color.ohos_id_color_sub_background"))
.width(ConfigData.WH_100_100)
.height(ConfigData.WH_100_100)
}
aboutToAppear(): void {
LogUtil.info(MODULE_TAG + 'aboutToAppear in');
AppStorage.SetOrCreate('extensionServiceManagementList', []);
ExtensionServiceManagementModel.setExtensionServiceManagementListener();
ResourceUtil.getString($r('app.float.wh_value_80')).then(value => this.whtl = value);
LogUtil.info(MODULE_TAG + 'aboutToAppear appList:' + JSON.stringify(this.serviceList));
LogUtil.info(MODULE_TAG + 'aboutToAppear out');
}
onPageShow(): void {
LogUtil.info(MODULE_TAG + 'onPageShow in');
AppStorage.SetOrCreate('extensionServiceManagementList', []);
ExtensionServiceManagementModel.setExtensionServiceManagementListener();
ResourceUtil.getString($r('app.float.wh_value_80')).then(value => this.whtl = value);
LogUtil.info(MODULE_TAG + 'onPageShow ServiceList:' + JSON.stringify(this.serviceList));
LogUtil.info(MODULE_TAG + 'onPageShow out');
}
aboutToDisappear(): void{
LogUtil.info(MODULE_TAG + 'aboutToDisappear in');
AppStorage.Delete(MODULE_TAG + 'extensionServiceManagementList');
LogUtil.info(MODULE_TAG + 'aboutToDisappear out');
}
}

View File

@ -1307,6 +1307,82 @@
{
"name": "audio_balance_suggestion",
"value": "向左或右滑动,可调节相应声道的音量大小"
},
{
"name":"user_approval_remain_times",
"value":"开启 (%d秒)"
},
{
"name": "extension_service",
"value": "扩展服务"
},
{
"name": "installed_service",
"value": "已安装服务"
},
{
"name": "service_number",
"value": "%d项服务"
},
{
"name": "no_service",
"value": "无服务"
},
{
"name": "more_settings",
"value": "更多设置"
},
{
"name": "help",
"value": "帮助"
},
{
"name": "no_description_provided",
"value": "未提供说明"
},
{
"name": "accessibility_on",
"value": "已开启"
},
{
"name": "accessibility_off",
"value": "已关闭"
},
{
"name": "accessibility_security_notification",
"value": "安全提醒"
},
{
"name": "accessibility_notify_content",
"value": "无障碍为高度敏感权限,授予应用该权限,您的隐私信息可能会泄露,财产安全将受到威胁。授权后,应用可进行的行为有:"
},
{
"name": "accessibility_risk_detail",
"value": "风险详情"
},
{
"name": "accessibility_risk_content",
"value": "• 可读取屏幕上的所有内容:并允许其在其他应用上层显示内容\n• 可跟踪您使用各应用的行为,并代替您操控应用。"
},
{
"name": "accessibility_user_approval",
"value": "我已知晓如上风险,并自愿承担可能导致的后果。"
},
{
"name": "accessibility_enable",
"value": "开启"
},
{
"name": "accessibility_disable",
"value": "不开启"
},
{
"name": "accessibility_label",
"value": "辅助应用"
},
{
"name": "accessibility_desc",
"value": "未提供说明"
}
]
}

View File

@ -7,6 +7,8 @@
"pages/applicationInfo",
"pages/applicationStorage",
"pages/accessibility",
"pages/accessibilityServiceInfo",
"pages/serviceManagement",
"pages/screenAndBrightness",
"pages/aboutDevice",
"pages/deviceName",

View File

@ -1303,6 +1303,74 @@
{
"name": "audio_balance_suggestion",
"value": "Adjust the volume balance between left and right channels."
},
{
"name":"user_approval_remain_times",
"value":"Grant Access (%dS)"
},
{
"name": "extension_service",
"value": "Services"
},
{
"name": "installed_service",
"value": "Installed services"
},
{
"name": "service_number",
"value": "%d"
},
{
"name": "no_service",
"value": "None"
},
{
"name": "more_settings",
"value": "More settings"
},
{
"name": "help",
"value": "HELP AND FEEDBACK"
},
{
"name": "no_description_provided",
"value": "No description"
},
{
"name": "accessibility_on",
"value": "On"
},
{
"name": "accessibility_off",
"value": "Off"
},
{
"name": "accessibility_security_notification",
"value": "Security alert"
},
{
"name": "accessibility_notify_content",
"value": "Accessibility is a highly sensitive permission. Granting this permission may put your private information and property at risk."
},
{
"name": "accessibility_risk_detail",
"value": "This app will be able to:"
},
{
"name": "accessibility_risk_content",
"value": " • Read everything on the screen and display content on top of other apps.\n • Track your behavior in each app and control apps on your behalf."
},
{
"name": "accessibility_user_approval",
"value": "I'm aware of and willing to assume these risks."
},
{
"name": "accessibility_enable",
"value": "Grant access"
},
{
"name": "accessibility_disable",
"value": "Cancel"
}
]
}

View File

@ -1307,6 +1307,70 @@
{
"name": "audio_balance_suggestion",
"value": "向左或右滑动,可调节相应声道的音量大小"
},
{
"name": "extension_service",
"value": "扩展服务"
},
{
"name": "installed_service",
"value": "已安装服务"
},
{
"name": "service_number",
"value": "%d项服务"
},
{
"name": "no_service",
"value": "无服务"
},
{
"name": "more_settings",
"value": "更多设置"
},
{
"name": "help",
"value": "帮助"
},
{
"name": "no_description_provided",
"value": "未提供说明"
},
{
"name": "accessibility_on",
"value": "已开启"
},
{
"name": "accessibility_off",
"value": "已关闭"
},
{
"name": "accessibility_security_notification",
"value": "安全提醒"
},
{
"name": "accessibility_notify_content",
"value": "无障碍为高度敏感权限,授予应用该权限,您的隐私信息可能会泄露,财产安全将受到威胁。授权后,应用可进行的行为有:"
},
{
"name": "accessibility_risk_detail",
"value": "风险详情"
},
{
"name": "accessibility_risk_content",
"value": "• 可读取屏幕上的所有内容:并允许其在其他应用上层显示内容\n• 可跟踪您使用各应用的行为,并代替您操控应用。"
},
{
"name": "accessibility_user_approval",
"value": "我已知晓如上风险,并自愿承担可能导致的后果。"
},
{
"name": "accessibility_enable",
"value": "开启"
},
{
"name": "accessibility_disable",
"value": "不开启"
}
]
}