diff --git a/atomicserviceweb/interfaces/atomicserviceweb.js b/atomicserviceweb/interfaces/atomicserviceweb.js index f9e3584d2a2b93d193ca3dd3dcd0f92b5168efed..95dbf4c4eb08d46d726811584d080f268322654f 100644 --- a/atomicserviceweb/interfaces/atomicserviceweb.js +++ b/atomicserviceweb/interfaces/atomicserviceweb.js @@ -99,6 +99,11 @@ const TEL_PROTOCOL = 'tel:'; const MAILTO_PROTOCOL = 'mailto:'; const WANT_ACTION_SEND_TO_DATA = 'ohos.want.action.sendToData'; const RESOURCE_RAWFILE = 'resource://rawfile'; +const TYPE_AS_WEB = 'ASWeb'; +const WEB_PERMISSIONS = { + 'TYPE_VIDEO_CAPTURE': 'ohos.permission.CAMERA', + 'TYPE_AUDIO_CAPTURE': 'ohos.permission.MICROPHONE' +}; const SYSTEM_INTERNAL_ERROR = new AsError(500, 'System internal error.'); const JS_API_INVALID_INVOKE_ERROR = new AsError(200001, 'Invalid invoke.'); const PARAM_REQUIRED_ERROR_CODE = 200002; @@ -351,6 +356,7 @@ export class AtomicServiceWeb extends ViewPU { } return n7; }); + Web.onPermissionRequest((c10) => { this.handleOnPermissionRequest(c10); }); }, Web); } @@ -528,6 +534,76 @@ export class AtomicServiceWeb extends ViewPU { } } + handleOnPermissionRequest(t8) { + if (this.checkPermissionRequest(t8)) { + t8.request.grant(t8.request.getAccessibleResource()); + } else { + t8.request.deny(); + } + } + + checkPermissionRequest(o8) { + let p8 = o8.request.getAccessibleResource(); + if (!p8 || p8.length <= 0) { + return false; + } + let q8 = this.getAppId(); + if (!q8) { + console.error('AtomicServiceWeb checkPermissionRequest error, appId is invalid'); + return false; + } + for (let r8 of p8) { + let s8 = WEB_PERMISSIONS[r8]; + if (!s8) { + console.error('AtomicServiceWeb checkPermissionRequest error, permission is not support'); + return false; + } + if (!this.isPermissionUserGranted(s8)) { + return false; + } + if (!this.isPermissionWhiteListAllow(q8, s8)) { + return false; + } + } + return true; + } + + isPermissionUserGranted(j8) { + try { + let l8 = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION); + if (!l8?.appInfo?.accessTokenId) { + return false; + } + let m8 = l8.appInfo.accessTokenId; + let n8 = abilityAccessCtrl.createAtManager() + .checkAccessTokenSync(m8, j8); + if (n8 !== abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) { + console.error(`AtomicServiceWeb isPermissionGranted permission ${j8} is not grant`); + return false; + } + return true; + } catch (k8) { + console.error(`AtomicServiceWeb isPermissionGranted error, code: ${k8.code}, message: ${k8.message}`); + return false; + } + } + + isPermissionWhiteListAllow(f8, g8) { + if (!atomicBasicEngine || !atomicBasicEngine.default || + typeof atomicBasicEngine.default.checkAtomicServiceAllow !== 'function') { + console.error('AtomicServiceWeb isPermissionRequestAllow error, checkAtomicServiceAllow is not available'); + return false; + } + try { + let i8 = atomicBasicEngine.default.checkAtomicServiceAllow(f8, g8, TYPE_AS_WEB); + console.debug(`AtomicServiceWeb isPermissionRequestAllow ret=${i8} permission=${g8}`); + return i8; + } catch (h8) { + console.error(`AtomicServiceWeb isPermissionRequestAllow error, code: ${h8.code}, message: ${h8.message}`); + return false; + } + } + rerender() { this.updateDirtyElements(); } diff --git a/atomicserviceweb/source/atomicserviceweb.ets b/atomicserviceweb/source/atomicserviceweb.ets index 1a5534c460624dbe8e6b8c72a3f295c35cdb340e..b076aa2b5ac85e4eb84c54751264d3fb7a4cb48c 100644 --- a/atomicserviceweb/source/atomicserviceweb.ets +++ b/atomicserviceweb/source/atomicserviceweb.ets @@ -93,6 +93,11 @@ const TEL_PROTOCOL: string = 'tel:'; const MAILTO_PROTOCOL: string = 'mailto:'; const WANT_ACTION_SEND_TO_DATA: string = 'ohos.want.action.sendToData'; const RESOURCE_RAWFILE: string = 'resource://rawfile'; +const TYPE_AS_WEB: string = 'ASWeb'; +const WEB_PERMISSIONS: Record = { + 'TYPE_VIDEO_CAPTURE': 'ohos.permission.CAMERA', + 'TYPE_AUDIO_CAPTURE': 'ohos.permission.MICROPHONE' +}; const SYSTEM_INTERNAL_ERROR: AsError = new AsError(500, 'System internal error.'); const JS_API_INVALID_INVOKE_ERROR: AsError = new AsError(200001, 'Invalid invoke.'); @@ -233,6 +238,9 @@ export struct AtomicServiceWeb { } return checkResult; }) + .onPermissionRequest((event: OnPermissionRequestEvent) => { + this.handleOnPermissionRequest(event); + }) } onCommonCallBack(method: string, event: T, callback?: (event: T) => void): void { @@ -432,6 +440,89 @@ export struct AtomicServiceWeb { console.error(`AtomicServiceWeb openSendMail error, code: ${err.code}, message: ${err.message}`); } } + + /** + * 处理onPermissionRequest回调 + */ + private handleOnPermissionRequest(event: OnPermissionRequestEvent): void { + if (this.checkPermissionRequest(event)) { + event.request.grant(event.request.getAccessibleResource()); + } else { + event.request.deny(); + } + } + + /** + * onPermissionRequest权限校验 + */ + private checkPermissionRequest(event: OnPermissionRequestEvent): boolean { + let accessibleResource: string[] = event.request.getAccessibleResource(); + if (!accessibleResource || accessibleResource.length <= 0) { + return false; + } + let appId: string | null = this.getAppId(); + if (!appId) { + console.error('AtomicServiceWeb checkPermissionRequest error, appId is invalid'); + return false; + } + for (let resource of accessibleResource) { + let permission: string = WEB_PERMISSIONS[resource]; + if (!permission) { + console.error('AtomicServiceWeb checkPermissionRequest error, permission is not support'); + return false; + } + if (!this.isPermissionUserGranted(permission)) { + return false; + } + if (!this.isPermissionWhiteListAllow(appId, permission)) { + return false; + } + } + return true; + } + + /** + * 检查用户是否授予权限 + */ + private isPermissionUserGranted(permission: string): boolean { + try { + let bundleInfo: bundleManager.BundleInfo = + bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION); + if (!bundleInfo?.appInfo?.accessTokenId) { + return false; + } + let tokenId: number = bundleInfo.appInfo.accessTokenId; + let grantStatus: abilityAccessCtrl.GrantStatus = abilityAccessCtrl.createAtManager() + .checkAccessTokenSync(tokenId, permission as Permissions); + if (grantStatus !== abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) { + console.error(`AtomicServiceWeb isPermissionGranted permission ${permission} is not grant`); + return false; + } + return true; + } catch (err) { + console.error(`AtomicServiceWeb isPermissionGranted error, code: ${err.code}, message: ${err.message}`); + return false; + } + } + + /** + * 检查权限白名单是否通过 + */ + private isPermissionWhiteListAllow(appId: string, permission: string): boolean { + if (!atomicBasicEngine || !atomicBasicEngine.default || + typeof atomicBasicEngine.default.checkAtomicServiceAllow !== 'function') { + console.error('AtomicServiceWeb isPermissionRequestAllow error, checkAtomicServiceAllow is not available'); + return false; + } + try { + let isAllow: boolean = atomicBasicEngine.default.checkAtomicServiceAllow(appId, permission, TYPE_AS_WEB); + console.debug(`AtomicServiceWeb isPermissionRequestAllow ret=${isAllow} permission=${permission}`); + return isAllow; + } catch (err) { + console.error(`AtomicServiceWeb isPermissionRequestAllow error, code: ${err.code}, message: ${err.message}`); + return false; + } + } } @Observed