瀑布流适配

Signed-off-by: li-li-wang <wangliliang5@h-partners.com>
This commit is contained in:
li-li-wang
2025-07-10 10:24:14 +08:00
parent 747aaf9adb
commit 55b5d375d8
9 changed files with 117 additions and 118 deletions
+2 -2
View File
@@ -4,8 +4,8 @@
"app": {
"bundleName": "com.ohos.permissionmanager",
"vendor": "example",
"versionCode": 1000081,
"versionName": "1.8.1",
"versionCode": 1000082,
"versionName": "1.8.2",
"icon": "$media:app_icon",
"label": "$string:app_name",
"configuration": "$profile:configuration"
+2 -2
View File
@@ -16,8 +16,8 @@
"app": {
"bundleName": "com.ohos.permissionmanager",
"vendor": "example",
"versionCode": 1000081,
"versionName": "1.8.1",
"versionCode": 1000082,
"versionName": "1.8.2",
"icon": "$media:app_icon",
"label": "$string:app_name",
"configuration": "$profile:configuration"
@@ -17,48 +17,44 @@ import extension from '@ohos.app.ability.ServiceExtensionAbility';
import window from '@ohos.window';
import { GlobalContext } from '../common/utils/globalContext';
import { Configuration } from '@ohos.app.ability.Configuration';
import Want from '@ohos.app.ability.Want';
import { Property, NavigationBarRect } from '../common/model/typedef';
import { NotifyType } from '../common/model/definition';
import { Log } from '../common/utils/utils';
const TAG = 'PermissionManager_Log:';
const BG_COLOR = '#00000000';
enum NotifyType {
Toast = 1,
Dialog = 0
}
export default class SecurityExtensionAbility extends extension {
/**
* Lifecycle function, called back when a service extension is started for initialization.
*/
onCreate(want): void {
console.info(TAG + 'SecurityExtensionAbility onCreate, ability name is ' + want.abilityName);
onCreate(want: Want): void {
Log.info(`SecurityExtensionAbility onCreate, ability name is ${want.abilityName}.`);
globalThis.windowNum = 0;
console.info(TAG + 'Set windowNum = 0');
}
/**
* Lifecycle function, called back when a service extension is started or recall.
*/
onRequest(want, startId): void {
console.info(TAG + 'SecurityExtensionAbility onRequest. start id is ' + startId);
console.info(TAG + 'want: ' + JSON.stringify(want));
onRequest(want: Want, startId: number): void {
Log.info(`SecurityExtensionAbility onRequest. start id is ${startId}.`);
try {
let width = want.parameters['ohos.display.width'] ?? 0;
let height = want.parameters['ohos.display.height'] ?? 0;
let top = want.parameters['ohos.display.top'] ?? 0;
let navigationBarRect = {
let width = want.parameters?.['ohos.display.width'] as number ?? 0;
let height = want.parameters?.['ohos.display.height'] as number ?? 0;
let top = want.parameters?.['ohos.display.top'] as number ?? 0;
let navigationBarRect: NavigationBarRect = {
left: 0,
top: top,
width: width,
height: height
};
let notifyType = want.parameters['ohos.ability.notify.type'] ?? 0;
let notifyType = want.parameters?.['ohos.ability.notify.type'] ?? 0;
if (notifyType === NotifyType.Dialog) {
this.createWindow('SecurityDialog' + startId, window.WindowType.TYPE_DIALOG, navigationBarRect, want);
}
} catch (exception) {
console.error(TAG + 'Failed to obtain the default display object. Code: ' + JSON.stringify(exception));
Log.error(`Failed to obtain the default display object. Code: ${JSON.stringify(exception)}.`);
};
}
@@ -66,36 +62,39 @@ export default class SecurityExtensionAbility extends extension {
* Lifecycle function, called back before a service extension is destroyed.
*/
onDestroy(): void {
console.info(TAG + 'SecurityExtensionAbility onDestroy.');
Log.info('SecurityExtensionAbility onDestroy.');
}
onConfigurationUpdate(newConfig: Configuration): void {
console.info(TAG + 'onConfigurationUpdate: ' + JSON.stringify(newConfig));
Log.info(`onConfigurationUpdate: ${JSON.stringify(newConfig)}.`);
}
private async createWindow(name: string, windowType, rect, want): Promise<void> {
console.info(TAG + 'create securityWindow');
private async createWindow(name: string, windowType: window.WindowType, rect: NavigationBarRect,
want: Want): Promise<void> {
Log.info('create securityWindow.');
let dialogSet: Set<String> = GlobalContext.load('dialogSet');
if (!dialogSet) {
dialogSet = new Set<String>();
console.info(TAG + 'new dialogSet');
Log.info('new dialogSet.');
GlobalContext.store('dialogSet', dialogSet);
}
let callerToken: number = want.parameters['ohos.caller.uid'];
let windId: number = want.parameters['ohos.ability.params.windowId'];
let callerToken: number = want.parameters?.['ohos.caller.uid'] as number;
let windId: number = want.parameters?.['ohos.ability.params.windowId'] as number;
let token: String = String(callerToken) + '_' + String(windId);
if (dialogSet.has(token)) {
console.info(TAG + 'window already exists');
Log.info('window already exists.');
return;
}
try {
const win = await window.createWindow({ ctx: this.context, name, windowType });
let storage: LocalStorage = new LocalStorage({ 'want': want, 'win': win });
await win.bindDialogTarget(want.parameters['ohos.ability.params.token'].value, () => {
let property: Record<string, Object> = { 'want': want, 'win': win };
let storage: LocalStorage = new LocalStorage(property);
let tokenValue = want.parameters?.['ohos.ability.params.token'] as Property;
await win.bindDialogTarget(tokenValue.value, () => {
win.destroyWindow();
let dialogSet: Set<String> = GlobalContext.load('dialogSet');
let callerToken: number = want.parameters['ohos.caller.uid'];
let windId: number = want.parameters['ohos.ability.params.windowId'];
let callerToken: number = want.parameters?.['ohos.caller.uid'] as number;
let windId: number = want.parameters?.['ohos.ability.params.windowId'] as number;
let token: String = String(callerToken) + '_' + String(windId);
dialogSet.delete(token);
GlobalContext.store('dialogSet', dialogSet);
@@ -106,22 +105,23 @@ export default class SecurityExtensionAbility extends extension {
try {
await win.setFollowParentWindowLayoutEnabled(true);
} catch (error) {
console.error(TAG + `setFollowParentWindowLayoutEnabled error: ${JSON.stringify(error)}.`);
Log.error(`setFollowParentWindowLayoutEnabled error: ${JSON.stringify(error)}.`);
await win.moveWindowTo(rect.left, rect.top);
await win.resize(rect.width, rect.height);
};
await win.loadContent('pages/securityDialog', storage);
win.setWindowBackgroundColor(BG_COLOR);
await win.showWindow();
console.info(TAG + 'showWindow end.');
Log.info('showWindow end.');
dialogSet.add(token);
GlobalContext.store('dialogSet', dialogSet);
} catch (err) {
console.error(TAG + `window create failed! err: ${JSON.stringify(err)}`);
}
Log.error(`window create failed! err: ${JSON.stringify(err)}.`);
};
}
private async createToast(name: string, windowType, rect, want): Promise<void> {
private async createToast(name: string, windowType: window.WindowType, rect: NavigationBarRect,
want: Want): Promise<void> {
try {
const win = await window.createWindow({ ctx: this.context, name, windowType });
let property: Record<string, Object> = { 'want': want, 'win': win };
@@ -131,7 +131,7 @@ export default class SecurityExtensionAbility extends extension {
try {
await win.setSystemAvoidAreaEnabled(true);
} catch (error) {
console.error(TAG + `setSystemAvoidAreaEnabled error: ${JSON.stringify(error)}.`);
Log.error(`setSystemAvoidAreaEnabled error: ${JSON.stringify(error)}.`);
};
await win.loadContent('pages/securityToast', storage);
win.setWindowBackgroundColor(BG_COLOR);
@@ -139,7 +139,7 @@ export default class SecurityExtensionAbility extends extension {
await win.setWindowFocusable(false);
await win.showWindow();
} catch (error) {
console.error(TAG + `window create failed! err: ${JSON.stringify(error)} `);
}
Log.error(`window create failed! err: ${JSON.stringify(error)}.`);
};
}
};
@@ -98,4 +98,9 @@ export enum PermissionOption {
REVOKE = 'REVOKE',
// 不操作
SKIP = 'SKIP'
}
export enum NotifyType {
Toast = 1,
Dialog = 0
}
@@ -531,4 +531,11 @@ export interface PermissionWithOption {
export interface optionAndState {
operationResult: number;
permissionState: abilityAccessCtrl.GrantStatus;
}
export interface NavigationBarRect {
left: number;
top: number;
width: number;
height: number;
}
@@ -183,7 +183,7 @@ struct CustomDialogWearable {
.customizeButton()
.backgroundColor('#1F71FF')
.onClick(() => {
Log.info('allow click start');
Log.info('Allow click start.');
this.dialogControllerForWearable?.close();
if (this.confirm) {
this.confirm();
@@ -197,7 +197,7 @@ struct CustomDialogWearable {
.customizeButton()
.backgroundColor('#405EA1FF')
.onClick(() => {
Log.info('cancel click start');
Log.info('cancel click start.');
this.dialogControllerForWearable?.close();
if (this.cancel) {
this.cancel();
@@ -236,10 +236,10 @@ struct SecurityDialog {
dialogControllerForWearable: CustomDialogController | null = new CustomDialogController({
builder: CustomDialogWearable({
cancel: () => {
this.onCancel()
this.loadCancel();
},
confirm: () => {
this.onAccept()
this.onAccept();
},
index: $index,
appName: $appName,
@@ -249,7 +249,7 @@ struct SecurityDialog {
}),
customStyle: true,
cancel: () => {
this.onCancel();
this.loadCancel();
},
})
@@ -265,16 +265,7 @@ struct SecurityDialog {
buttonStyle: ButtonStyleMode.TEXTUAL,
action: () => {
this.dialogController?.close();
this.win.destroyWindow();
let dialogSet: Set<String> = GlobalContext.load('dialogSet');
let callerToken: number = this.want.parameters['ohos.caller.uid'];
let windId: number = this.want.parameters['ohos.ability.params.windowId'];
let token: String = String(callerToken) + '_' + String(windId);
dialogSet.delete(token);
GlobalContext.store('dialogSet', dialogSet);
if (dialogSet.size === 0) {
this.context.terminateSelf();
}
this.loadCancel();
}
},
{
@@ -289,16 +280,7 @@ struct SecurityDialog {
}),
autoCancel: false,
cancel: () => {
this.win.destroyWindow();
let dialogSet: Set<String> = GlobalContext.load('dialogSet');
let callerToken: number = this.want.parameters['ohos.caller.uid'];
let windId: number = this.want.parameters['ohos.ability.params.windowId'];
let token: String = String(callerToken) + '_' + String(windId);
dialogSet.delete(token);
GlobalContext.store('dialogSet', dialogSet);
if (dialogSet.size === 0) {
this.context.terminateSelf();
}
this.loadCancel();
},
});
@@ -348,9 +330,9 @@ struct SecurityDialog {
this.dialogControllerForWearable = null;
}
onCancel() {
Log.info('Callback when the first button is clicked');
this.win.destroyWindow();
loadCancel() {
Log.info('Callback when the first button is clicked.');
this.win?.destroyWindow();
let dialogSet: Set<String> = GlobalContext.load('dialogSet');
let callerToken: number = this.want.parameters['ohos.caller.uid'];
let windId: number = this.want.parameters['ohos.ability.params.windowId'];
@@ -363,7 +345,7 @@ struct SecurityDialog {
}
onAccept() {
Log.info('Callback when the second button is clicked');
Log.info('Callback when the second button is clicked.');
this.destruction();
}
@@ -371,15 +353,15 @@ struct SecurityDialog {
let uid: number = this.want.parameters['ohos.caller.uid'];
try {
bundleManager.getAppCloneIdentity(uid).then(cloneInfo => {
Log.info(`getAppCloneIdentity: ${JSON.stringify(cloneInfo)}`);
Log.info(`getAppCloneIdentity: ${JSON.stringify(cloneInfo)}.`);
this.appIndex = cloneInfo.appIndex;
this.getSelfName(cloneInfo);
}).catch((err: BusinessError) => {
Log.error(`getAppCloneIdentity failed: ${JSON.stringify(err)}`);
Log.error(`getAppCloneIdentity failed: ${JSON.stringify(err)}.`);
})
} catch (err) {
Log.error(`get appName failed: ${JSON.stringify(err)}`);
}
Log.error(`get appName failed: ${JSON.stringify(err)}.`);
};
}
getSelfName(cloneInfo: bundleManager.AppCloneIdentity) {
@@ -390,11 +372,11 @@ struct SecurityDialog {
data.labelResource.type = RESOURCE_TYPE;
this.appName = data.labelResource;
}).catch((error: BusinessError) => {
Log.error('getApplicationInfo failed. err is ' + JSON.stringify(error));
Log.error(`getApplicationInfo failed. err is ${JSON.stringify(error)}.`);
});
} catch (err) {
Log.error('getSelfName failed. err is ' + JSON.stringify(err));
}
Log.error(`getSelfName failed. err is ${JSON.stringify(err)}.`);
};
}
getCloneName(cloneInfo: bundleManager.AppCloneIdentity) {
@@ -404,8 +386,8 @@ struct SecurityDialog {
bundleResourceManager.getBundleResourceInfo(cloneInfo.bundleName, resourceFlag, cloneInfo.appIndex);
this.appName = resourceInfo?.label;
} catch (err) {
Log.error('getCloneName failed. err is ' + JSON.stringify(err));
}
Log.error(`getCloneName failed. err is ${JSON.stringify(err)}.`);
};
}
destruction() {
@@ -425,16 +407,7 @@ struct SecurityDialog {
}).finally(() => {
data.reclaim();
reply.reclaim();
this.win.destroyWindow();
let dialogSet: Set<String> = GlobalContext.load('dialogSet');
let callerToken: number = this.want.parameters['ohos.caller.uid'];
let windId: number = this.want.parameters['ohos.ability.params.windowId'];
let token: String = String(callerToken) + '_' + String(windId);
dialogSet.delete(token);
GlobalContext.store('dialogSet', dialogSet);
if (dialogSet.size === 0) {
this.context.terminateSelf();
}
this.loadCancel();
})
}
}
@@ -21,9 +21,44 @@ import { DeviceUtil } from '../common/utils/deviceUtil';
import Constants from '../common/utils/constant';
import { WantInfo } from '../common/model/typedef';
class ToastFlexModifier implements AttributeModifier<FlexAttribute> {
applyNormalAttribute(instance: FlexAttribute): void {
if (DeviceUtil.isPC()) {
instance.padding($r('sys.float.padding_level4'))
instance.shadow({
radius: Constants.TOAST_FLEX_SHADOW_RADIUS_40,
color: $r('app.color.outerDefaultSMColor'),
offsetX: Constants.TOAST_FLEX_SHADOW_OFFSET_X,
offsetY: Constants.TOAST_FLEX_SHADOW_OFFSET_Y
})
instance.borderRadius($r('sys.float.corner_radius_level4'))
instance.backgroundBlurStyle(BlurStyle.COMPONENT_REGULAR)
instance.border({ width: '1px', color: '#33ffffff' })
instance.outline({ width: '1px', color: $r('app.color.outline'), radius: $r('sys.float.corner_radius_level4') })
} else {
instance.padding({
top: Constants.PADDING_8,
right: Constants.PADDING_16,
bottom: Constants.PADDING_8,
left: Constants.PADDING_16
})
instance.shadow({
radius: Constants.TOAST_FLEX_SHADOW_RADIUS_60,
color: $r('app.color.outerDefaultMDColor'),
offsetX: Constants.TOAST_FLEX_SHADOW_OFFSET_X,
offsetY: Constants.TOAST_FLEX_SHADOW_OFFSET_Y
})
instance.borderRadius($r('sys.float.corner_radius_level9'))
instance.backgroundBlurStyle(BlurStyle.COMPONENT_ULTRA_THICK)
}
}
}
@Entry({ useSharedStorage: true })
@Component
struct SecurityToast {
@State modifier: ToastFlexModifier = new ToastFlexModifier();
@LocalStorageLink('want') want: WantInfo = new WantInfo([]);
@LocalStorageLink('win') win: window.Window = {} as window.Window;
@State alpha: number = 0;
@@ -54,7 +89,7 @@ struct SecurityToast {
});
} catch (error) {
Log.error(`sendAccessibilityEvent failed, error code: ${error.code}, message: ${error.message}.`);
}
};
}
getWinAvoidArea() {
@@ -103,7 +138,7 @@ struct SecurityToast {
display.off('change');
} catch (exception) {
Log.error(`Failed to unregister callback. Cause code: ${exception.code}, message: ${exception.message}`);
}
};
}
screenMonitor() {
@@ -114,7 +149,7 @@ struct SecurityToast {
});
} catch (exception) {
Log.error(`Failed to register callback. Code: ${JSON.stringify(exception)}`);
}
};
try {
display.on('change', (data: number) => {
@@ -133,7 +168,7 @@ struct SecurityToast {
});
} catch (exception) {
Log.error(`Failed to register callback. Code: ${JSON.stringify(exception)}`);
}
};
}
build() {
@@ -169,28 +204,7 @@ struct SecurityToast {
minHeight: Constants.TOAST_CONSTRAINT_SIZE_MIN_HEIGHT
})
.margin(this.setPosition ? { top: this.setOffset - px2vp(this.topRectHeight) } : { bottom: this.setOffset })
.padding(DeviceUtil.isPC() ? $r('sys.float.padding_level4') : {
top: Constants.PADDING_8,
right: Constants.PADDING_16,
bottom: Constants.PADDING_8,
left: Constants.PADDING_16
})
.shadow(DeviceUtil.isPC() ? {
radius: Constants.TOAST_FLEX_SHADOW_RADIUS_40,
color: $r('app.color.outerDefaultSMColor'),
offsetX: Constants.TOAST_FLEX_SHADOW_OFFSET_X,
offsetY: Constants.TOAST_FLEX_SHADOW_OFFSET_Y
} : {
radius: Constants.TOAST_FLEX_SHADOW_RADIUS_60,
color: $r('app.color.outerDefaultMDColor'),
offsetX: Constants.TOAST_FLEX_SHADOW_OFFSET_X,
offsetY: Constants.TOAST_FLEX_SHADOW_OFFSET_Y
})
.borderRadius(DeviceUtil.isPC() ? $r('sys.float.corner_radius_level4') : $r('sys.float.corner_radius_level9'))
.backgroundBlurStyle(DeviceUtil.isPC() ? BlurStyle.COMPONENT_REGULAR : BlurStyle.COMPONENT_ULTRA_THICK)
.border(DeviceUtil.isPC() ? { width: '1px', color: '#33ffffff' } : {})
.outline(DeviceUtil.isPC() ?
{ width: '1px', color: $r('app.color.outline'), radius: $r('sys.float.corner_radius_level4') } : {})
.attributeModifier(this.modifier)
}
.width(Constants.TOAST_COLUMN_WIDTH)
.height(Constants.TOAST_COLUMN_HEIGHT)
+1 -1
View File
@@ -70,7 +70,7 @@
{
"icon": "$media:icon",
"name": "com.ohos.permissionmanager.SecurityExtAbility",
"srcEntry": "./ets/SecurityExtAbility/SecurityExtAbility.ts",
"srcEntry": "./ets/SecurityExtAbility/SecurityExtAbility.ets",
"type": "service",
"exported": true,
"permissions": ["ohos.permission.GET_SENSITIVE_PERMISSIONS"]
+1 -1
View File
@@ -82,7 +82,7 @@
{
"icon": "$media:icon",
"name": "com.ohos.permissionmanager.SecurityExtAbility",
"srcEntry": "./ets/SecurityExtAbility/SecurityExtAbility.ts",
"srcEntry": "./ets/SecurityExtAbility/SecurityExtAbility.ets",
"type": "service",
"exported": true,
"permissions": ["ohos.permission.GET_SENSITIVE_PERMISSIONS"]