From dbcf3a1e56d2912de3059fb9461e5a10e4c0cfa1 Mon Sep 17 00:00:00 2001 From: Baligh Uddin Date: Thu, 28 Jan 2021 05:11:19 +0000 Subject: [PATCH] Migrate apex/permission to packages/modules/Permission Refactor import in core/proto/android/os/incident.proto BUG: 167963264 Test: TH Change-Id: I1a6aac95deabeee6d301ad83a2ad31ed2663c02e Merged-In: Ib7c32ba3037c534e9ab8c144716d68e46c908a39 --- apex/permission/Android.bp | 49 -- apex/permission/OWNERS | 6 - apex/permission/TEST_MAPPING | 7 - apex/permission/apex_manifest.json | 4 - .../com.android.permission.avbpubkey | Bin 1032 -> 0 bytes apex/permission/com.android.permission.pem | 51 -- apex/permission/com.android.permission.pk8 | Bin 2376 -> 0 bytes .../com.android.permission.x509.pem | 35 - apex/permission/framework-s/Android.bp | 72 -- apex/permission/framework-s/api/current.txt | 19 - .../framework-s/api/module-lib-current.txt | 11 - .../framework-s/api/module-lib-removed.txt | 1 - apex/permission/framework-s/api/removed.txt | 1 - .../framework-s/api/system-current.txt | 43 - .../framework-s/api/system-removed.txt | 1 - .../role/IOnRoleHoldersChangedListener.aidl | 25 - .../android/app/role/IRoleController.aidl | 43 - .../java/android/app/role/IRoleManager.aidl | 61 -- .../role/OnRoleHoldersChangedListener.java | 38 - .../app/role/RoleControllerManager.java | 265 ------ .../app/role/RoleControllerService.java | 304 ------- .../app/role/RoleFrameworkInitializer.java | 44 - .../java/android/app/role/RoleManager.java | 773 ------------------ .../java/android/app/role/TEST_MAPPING | 12 - apex/permission/framework/Android.bp | 50 -- apex/permission/framework/api/current.txt | 1 - .../framework/api/module-lib-current.txt | 1 - .../framework/api/module-lib-removed.txt | 1 - apex/permission/framework/api/removed.txt | 1 - .../framework/api/system-current.txt | 1 - .../framework/api/system-removed.txt | 1 - .../android/permission/PermissionState.java | 22 - apex/permission/jarjar-rules.txt | 5 - apex/permission/service/Android.bp | 106 --- apex/permission/service/api/current.txt | 1 - apex/permission/service/api/removed.txt | 1 - .../service/api/system-server-current.txt | 54 -- .../service/api/system-server-removed.txt | 1 - .../permission/compat/UserHandleCompat.java | 48 -- .../permission/compat/package-info.java | 22 - .../permission/persistence/IoUtils.java | 40 - .../RuntimePermissionsPersistence.java | 74 -- .../RuntimePermissionsPersistenceImpl.java | 265 ------ .../persistence/RuntimePermissionsState.java | 222 ----- .../android/permission/util/ArrayUtils.java | 70 -- .../permission/util/BackgroundThread.java | 93 --- .../permission/util/CollectionUtils.java | 72 -- .../permission/util/ForegroundThread.java | 93 --- .../permission/util/ThrottledRunnable.java | 75 -- .../android/permission/util/package-info.java | 22 - .../com/android/role/RoleManagerLocal.java | 42 - .../java/com/android/role/RoleService.java | 736 ----------------- .../com/android/role/RoleShellCommand.java | 151 ---- .../java/com/android/role/RoleUserState.java | 476 ----------- .../java/com/android/role/TEST_MAPPING | 20 - .../java/com/android/role/package-info.java | 22 - .../role/persistence/RolesPersistence.java | 73 -- .../persistence/RolesPersistenceImpl.java | 218 ----- .../android/role/persistence/RolesState.java | 115 --- .../proto/com/android/role/roleservice.proto | 56 -- apex/permission/testing/Android.bp | 25 - apex/permission/testing/test_manifest.json | 4 - apex/permission/tests/Android.bp | 37 - apex/permission/tests/AndroidManifest.xml | 32 - .../RuntimePermissionsPersistenceTest.kt | 110 --- .../role/persistence/RolesPersistenceTest.kt | 101 --- core/proto/android/os/incident.proto | 2 +- 67 files changed, 1 insertion(+), 5426 deletions(-) delete mode 100644 apex/permission/Android.bp delete mode 100644 apex/permission/OWNERS delete mode 100644 apex/permission/TEST_MAPPING delete mode 100644 apex/permission/apex_manifest.json delete mode 100644 apex/permission/com.android.permission.avbpubkey delete mode 100644 apex/permission/com.android.permission.pem delete mode 100644 apex/permission/com.android.permission.pk8 delete mode 100644 apex/permission/com.android.permission.x509.pem delete mode 100644 apex/permission/framework-s/Android.bp delete mode 100644 apex/permission/framework-s/api/current.txt delete mode 100644 apex/permission/framework-s/api/module-lib-current.txt delete mode 100644 apex/permission/framework-s/api/module-lib-removed.txt delete mode 100644 apex/permission/framework-s/api/removed.txt delete mode 100644 apex/permission/framework-s/api/system-current.txt delete mode 100644 apex/permission/framework-s/api/system-removed.txt delete mode 100644 apex/permission/framework-s/java/android/app/role/IOnRoleHoldersChangedListener.aidl delete mode 100644 apex/permission/framework-s/java/android/app/role/IRoleController.aidl delete mode 100644 apex/permission/framework-s/java/android/app/role/IRoleManager.aidl delete mode 100644 apex/permission/framework-s/java/android/app/role/OnRoleHoldersChangedListener.java delete mode 100644 apex/permission/framework-s/java/android/app/role/RoleControllerManager.java delete mode 100644 apex/permission/framework-s/java/android/app/role/RoleControllerService.java delete mode 100644 apex/permission/framework-s/java/android/app/role/RoleFrameworkInitializer.java delete mode 100644 apex/permission/framework-s/java/android/app/role/RoleManager.java delete mode 100644 apex/permission/framework-s/java/android/app/role/TEST_MAPPING delete mode 100644 apex/permission/framework/Android.bp delete mode 100644 apex/permission/framework/api/current.txt delete mode 100644 apex/permission/framework/api/module-lib-current.txt delete mode 100644 apex/permission/framework/api/module-lib-removed.txt delete mode 100644 apex/permission/framework/api/removed.txt delete mode 100644 apex/permission/framework/api/system-current.txt delete mode 100644 apex/permission/framework/api/system-removed.txt delete mode 100644 apex/permission/framework/java/android/permission/PermissionState.java delete mode 100644 apex/permission/jarjar-rules.txt delete mode 100644 apex/permission/service/Android.bp delete mode 100644 apex/permission/service/api/current.txt delete mode 100644 apex/permission/service/api/removed.txt delete mode 100644 apex/permission/service/api/system-server-current.txt delete mode 100644 apex/permission/service/api/system-server-removed.txt delete mode 100644 apex/permission/service/java/com/android/permission/compat/UserHandleCompat.java delete mode 100644 apex/permission/service/java/com/android/permission/compat/package-info.java delete mode 100644 apex/permission/service/java/com/android/permission/persistence/IoUtils.java delete mode 100644 apex/permission/service/java/com/android/permission/persistence/RuntimePermissionsPersistence.java delete mode 100644 apex/permission/service/java/com/android/permission/persistence/RuntimePermissionsPersistenceImpl.java delete mode 100644 apex/permission/service/java/com/android/permission/persistence/RuntimePermissionsState.java delete mode 100644 apex/permission/service/java/com/android/permission/util/ArrayUtils.java delete mode 100644 apex/permission/service/java/com/android/permission/util/BackgroundThread.java delete mode 100644 apex/permission/service/java/com/android/permission/util/CollectionUtils.java delete mode 100644 apex/permission/service/java/com/android/permission/util/ForegroundThread.java delete mode 100644 apex/permission/service/java/com/android/permission/util/ThrottledRunnable.java delete mode 100644 apex/permission/service/java/com/android/permission/util/package-info.java delete mode 100644 apex/permission/service/java/com/android/role/RoleManagerLocal.java delete mode 100644 apex/permission/service/java/com/android/role/RoleService.java delete mode 100644 apex/permission/service/java/com/android/role/RoleShellCommand.java delete mode 100644 apex/permission/service/java/com/android/role/RoleUserState.java delete mode 100644 apex/permission/service/java/com/android/role/TEST_MAPPING delete mode 100644 apex/permission/service/java/com/android/role/package-info.java delete mode 100644 apex/permission/service/java/com/android/role/persistence/RolesPersistence.java delete mode 100644 apex/permission/service/java/com/android/role/persistence/RolesPersistenceImpl.java delete mode 100644 apex/permission/service/java/com/android/role/persistence/RolesState.java delete mode 100644 apex/permission/service/proto/com/android/role/roleservice.proto delete mode 100644 apex/permission/testing/Android.bp delete mode 100644 apex/permission/testing/test_manifest.json delete mode 100644 apex/permission/tests/Android.bp delete mode 100644 apex/permission/tests/AndroidManifest.xml delete mode 100644 apex/permission/tests/java/com/android/permission/persistence/RuntimePermissionsPersistenceTest.kt delete mode 100644 apex/permission/tests/java/com/android/role/persistence/RolesPersistenceTest.kt diff --git a/apex/permission/Android.bp b/apex/permission/Android.bp deleted file mode 100644 index be51143e47305..0000000000000 --- a/apex/permission/Android.bp +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (C) 2019 The Android Open Source Project -// -// 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. - -apex { - name: "com.android.permission", - defaults: ["com.android.permission-defaults"], - manifest: "apex_manifest.json", -} - -apex_defaults { - name: "com.android.permission-defaults", - updatable: true, - min_sdk_version: "30", - key: "com.android.permission.key", - certificate: ":com.android.permission.certificate", - java_libs: [ - "framework-permission", - "framework-permission-s", - "service-permission", - ], - apps: ["PermissionController"], -} - -apex_key { - name: "com.android.permission.key", - public_key: "com.android.permission.avbpubkey", - private_key: "com.android.permission.pem", -} - -android_app_certificate { - name: "com.android.permission.certificate", - certificate: "com.android.permission", -} - -filegroup { - name: "permission-jarjar-rules", - srcs: ["jarjar-rules.txt"], -} diff --git a/apex/permission/OWNERS b/apex/permission/OWNERS deleted file mode 100644 index 957e10a582a01..0000000000000 --- a/apex/permission/OWNERS +++ /dev/null @@ -1,6 +0,0 @@ -svetoslavganov@google.com -moltmann@google.com -eugenesusla@google.com -zhanghai@google.com -evanseverson@google.com -ntmyren@google.com diff --git a/apex/permission/TEST_MAPPING b/apex/permission/TEST_MAPPING deleted file mode 100644 index 6e67ce92a27ea..0000000000000 --- a/apex/permission/TEST_MAPPING +++ /dev/null @@ -1,7 +0,0 @@ -{ - "presubmit" : [ - { - "name" : "PermissionApexTests" - } - ] -} diff --git a/apex/permission/apex_manifest.json b/apex/permission/apex_manifest.json deleted file mode 100644 index 6350d54d695ee..0000000000000 --- a/apex/permission/apex_manifest.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "com.android.permission", - "version": 309999999 -} diff --git a/apex/permission/com.android.permission.avbpubkey b/apex/permission/com.android.permission.avbpubkey deleted file mode 100644 index 9eaf852596371a8ff62efd07e6735a2baa982a61..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1032 zcmV+j1o!&@01yDawPj zrmrWVP3dQJ`<(R5I(*!j4WN z6ImenPMk#~Nd0o!p**UZa(*JYcP0p)cX%u?m>>n zh)&&biy|5USWGk#yO#ELWakdVJnPNId(ZX61u+dg z2KK}yq|<;N{N^kQviE8U`KN>QfXft~wrtNz)zt@g;neCG^82Snv>3*Dl*cC(sh~aU zIf2J)3%$GZDvs%7P{itX;hjEyF%S&T^++qvR@|>TO;(N*S+G{d(3v@gFgekBY`gtZBYD+K}pyxRbnJ z&51WsqO1eeL>?O+uQcpD%4}t)bH4JXQHt!dcRG=$xw)?CH@TkI2@+9i{;!*JO5YV2 zuAU+;j{A7QO)ZJd)y$%e{8Fp)Q|MPH^MaCY?2lA|d%e{Z>9(9@^927Zcw(-?1eXn) z@%Y@X=>h;r#`gN_3+(P7Si71^gEfL#+<6$Mi0ZvtuMzg3v^( z`|u1DsN*D`Czbub@9zP>^%CzVAbLhSD*uK>3HSYWh$B)`;UD&0I^jWMe)sc||Muy~ zt$CH}91&<8141F^Mahaug1pV(kJ|`M>PJtcOxovc!J{$*RG%jQ_kGWSm*lNd<62Rm zK~&}je&&LNQUwE--=#Dgprj0)heo0I_-aE<~Qh z>d-<=L!MJ%$q;Kg0R$SPy#0j7ozbR=LcZEf2$&>EKCo^+jP@IjoLcaZ!_1NC`-nRZ zH_~tCZ%^6$;14BPqCd$M(`7Ub9`0uSxCe$U3vVQ;iJ@|#)xjx1Cps2#82ea`&_&Au za+c?=Z_4s>R(ew$RPN_T)@cZ@y9DFJB&(FNj8sk&-l7&}0Q&U5C3BxkLqQ%R0pMV9 z$Ax>5dT*^VJBAiU9xS0M^I`7{hawZboG~!gye$BJg0Q{VkpUG2;1u`CzR(N4sVhrj zLWhTGe9b-(Ys_S&gDtrI#)CQHcnvCE3=Cku11J`f03T! zQ+8w_2Q_?m!Izb10mvZt*sQ+Ts$Ey37T>dh6BbT_hc!@g_}>i#E-Rl2xYs^R;HV?| zpOt(D3kq%?T_SqF73H2Sq{SuXwX#(o&>0&`KKnM5yRmaH@YLn%z(s8c$^B^A-QzCN z^!9n$7`fbVFAh3ZdHTy@FObuMdWd0A)}RFhDN6J@t_Jy$vjPJF009Dm0stiP8Y?fC z$*_btIQ|}(hZDa#Lox94#`T=#CRG7W7!H+XX-t~oqQZRaa<%?~JO zQC-w>Sc>O4zpnB689d1w7KT{~IOF>1n{0B|ny=d{G_)q_>lXiBzZcbaq6;pJ$3JceI za`POSpy?eX-pfb<0~Q1WpyQkDP%P*6y!%*Qpd>%X?PWC#&-V}*eMfsb1hrb~+mw!o zS;@;wQ$cFX10whwVBhJgmLv#kF*X=`X>3JK1^K&+O+Faz3%KMq9v+DP@ZP_7oUl@r z?Z_(2Zshd31nz88$JqcUmRD;t#kyVPH%I46k+tm-ctH2g0UI*@ck7aeQkyf3a7JSA zIh^X7J@0Fry$RQ>AcqCb>syShtZIaMs>j!muk;G4hYZfW-i&+o>l&P5*YP82Y>wa} zn28D`YtkWd4J}-wT^Ar+ugj}rSY)alm$VEaJJSW1Dw=JZaiP zFYglYa0_{?#i#+EpUgz4$jD@x)%{gKWs+6L+3meQngsjDr3nIp0RaHyVgrxeIF7)l zb+fuMgLtxz&iEF%N@4a}-CP&~1`yF;)cZ_N)Ra76O1d9(hiFFz^;Y#xm)qx=VdD?I zkxPZL)bGhB%3>hS1kN$2w*G8L@r`My_j5k1oO`W`eZXsqvVLe;@Q-#MT8#3*kF0$p!5Xb4( zcSw|Df=xu;a5TF15F)F~$~B)XO2i0DFf;nzdi+SEo!Y-}Byl#_$g;z8RZV zfwt$wva37M(Kp7OM}RsRHLrnB{=-|iNN~nYh|W=rPz9o5L%q1Ga3FS^=qK66GxqaY zfd1_*o3k!ruM);pdld`m)?10bL!Dpme618V7Sb$QaDWJZ=vCw!yN(TIUzwG=oEV73 zDb7w&+}K~sP^7VzK>vW`27IGwzG8btugCDq%e49%C_<+a`mq2?9|sPoP%wW-#NcKn z&vTk7>l0svZYO7Fg&G7lsWh7~2E$nR#Vpn}y4QNMkyZ8iY%9HnB`J{DEb5PkG+}zBVH2n0RN=B3Jc;OTC8tB6y!?z-J+RUnBe!d6i-U~i0)hbn0L7fOo=*9= zGothzJ;CV*muJ%yB+Esp!I1FU^+QQ zF>e{7Bl|^}?$Jq@-};K`Z1)1g=Ucj;vN{ds*H#oNGqsZ-C$F3go>dJf)dzF8;xym1 zOLl@nFZ-r!yOD_>XF{-*e|J}5YB+WY~Axc74UpbV? z1LgK`C0QEgP+Uhq;eQV%08x1x4}M(1U167sA>!U}n+|+Ej>NO^BLac}0RXRvw5t;p z|0Twe08(TiiAd_DpI^D|U)4;sj*@CdFp(RAKF7T^=V-cDE?_K6q&>+~E4Ar%_(oPG z$+f8m$9bL4?bh#!&TTM^a+RYglljcYHVhu;#v|!Z(%hJ^R5OvyN&Jt z3-^SY;3|cNdWa~Y8GUWu#Q5&)T{wB)<;$pj@NcqD{`;kSqINN}s(`$G`la&|$IB?; zqu?t0V+AL|QD3LQrx69U-Vf;?Te1`^iDrNpJH(DKh^-;mZO|QY`|40RaHW3t!JN zAaQ5@(eX)Ao!LFM|FSeF>zGVpz&Eyss@{|`p@U!PwXANtm_J1iWtcX%71OZ(QD6Cr z24ZMn26(oeCLf4e@9gyGof0=NrvADCrNgheTWw=iB5W-?qr4rKe6m~%_mI{TsmM2q zJ4E7XFYEHoZ+BD~*;+~?Tz2~Nai}VVALU-W!=Gl*(zS>SkGphB;d z9mLcX;U@F07NMAoN&}8X{h+kkpd+Pw5gh^t6IfSv4oHl+8)zMs7f7k{dpBqRe}G7Q u8YA&ucbZJ5!Nk?XI-piTxk4632o`6<2Rx9o@k_1FN?_*n6!#3P9HbW_;e|l} diff --git a/apex/permission/com.android.permission.x509.pem b/apex/permission/com.android.permission.x509.pem deleted file mode 100644 index 4b146c9edd4f6..0000000000000 --- a/apex/permission/com.android.permission.x509.pem +++ /dev/null @@ -1,35 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIGKzCCBBOgAwIBAgIUezo3fQeVZsmLpm/dkpGWJ/G/MN8wDQYJKoZIhvcNAQEL -BQAwgaMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH -DA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRy -b2lkMR8wHQYDVQQDDBZjb20uYW5kcm9pZC5wZXJtaXNzaW9uMSIwIAYJKoZIhvcN -AQkBFhNhbmRyb2lkQGFuZHJvaWQuY29tMCAXDTE5MTAwOTIxMzExOVoYDzQ3NTcw -OTA0MjEzMTE5WjCBozELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWEx -FjAUBgNVBAcMDU1vdW50YWluIFZpZXcxEDAOBgNVBAoMB0FuZHJvaWQxEDAOBgNV -BAsMB0FuZHJvaWQxHzAdBgNVBAMMFmNvbS5hbmRyb2lkLnBlcm1pc3Npb24xIjAg -BgkqhkiG9w0BCQEWE2FuZHJvaWRAYW5kcm9pZC5jb20wggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQCxefguRJ7E6tBCTEOeU2HJEGs6AQQapLz9hMed0aaJ -Qr7aTQiYJEk+sG4+jPYbjpxa8JDDzJHp+4g7DjfSb+dvT9n84A8lWaI/yRXTZTQN -Hu5m/bgHhi0LbySpiaFyodXBKUAnOhZyGPtYjtBFywFylueub8ryc1Z6UxxU7udH -1mkIr7sE48Qkq5SyjFROE96iFmYA+vS/JXOfS0NBHiMB4GBxx4V7kXpvrTI7hhZG -HiyhKvNh7wyHIhO9nDEw1rwtAH6CsL3YkQEVBeAU98m+0Au+qStLYkKHh2l8zT4W -7sVK1VSqfB+VqOUmeIGdzlBfqMsoXD+FJz6KnIdUHIwjFDjL7Xr+hd+7xve+Q3S+ -U3Blk/U6atY8PM09wNfilG+SvwcKk5IgriDcu3rWKgIFxbUUaxLrDW7pLlu6wt/d -GGtKK+Bc0jF+9Z901Tl33i5xhc5yOktT0btkKs7lSeE6VzP/Nk5g0SuzixmuRoh9 -f5Ge41N2ZCEHNXx3wZeVZwHIIPfYrL7Yql1Xoxbfs4ETFk6ChzVQcvjfDQQuK58J -uNc+TOCoI/qflXwGCwpuHl0ier8V5Z4tpMUl5rWyVR/QGRtLPvs2lLuxczDw1OXq -wEVtCMn9aNnd4y7R9PZ52hi53HAvDjpWefrLYi+Q04J6iGFQ1qAFBClK9DquBvmR -swIDAQABo1MwUTAdBgNVHQ4EFgQULpfus5s5SrqLkoUKyPXA0D1iHPMwHwYDVR0j -BBgwFoAULpfus5s5SrqLkoUKyPXA0D1iHPMwDwYDVR0TAQH/BAUwAwEB/zANBgkq -hkiG9w0BAQsFAAOCAgEAjxQG5EFv8V/9yV2glI53VOmlWMjfEgvUjd39s/XLyPlr -OzPOKSB0NFo8To3l4l+MsManxPK8y0OyfEVKbWVz9onv0ovo5MVokBmV/2G0jmsV -B4e9yjOq+DmqIvY/Qh63Ywb97sTgcFI8620MhQDbh2IpEGv4ZNV0H6rgXmgdSCBw -1EjBoYfFpN5aMgZjeyzZcq+d1IapdWqdhuEJQkMvoYS4WIumNIJlEXPQRoq/F5Ih -nszdbKI/jVyiGFa2oeZ3rja1Y6GCRU8TYEoKx1pjS8uQDOEDTwsG/QnUe9peEj0V -SsCkIidJWTomAmq9Tub9vpBe1zuTpuRAwxwR0qwgSxozV1Mvow1dJ19oFtHX0yD6 -ZjCpRn5PW9kMvSWSlrcrFs1NJf0j1Cvf7bHpkEDqLqpMnnh9jaFQq3nzDY+MWcIR -jDcgQpI+AiE2/qtauZnFEVhbce49nCnk9+5bpTTIZJdzqeaExe5KXHwEtZLaEDh4 -atLY9LuEvPsjmDIMOR6hycD9FvwGXhJOQBjESIWFwigtSb1Yud9n6201jw3MLJ4k -+WhkbmZgWy+xc+Mdm5H3XyB1lvHaHGkxu+QB9KyQuVQKwbUVcbwZIfTFPN6Zr/dS -ZXJqAbBhG/dBgF0LazuLaPVpibi+a3Y+tb9b8eXGkz4F97PWZIEDkELQ+9KOvhc= ------END CERTIFICATE----- diff --git a/apex/permission/framework-s/Android.bp b/apex/permission/framework-s/Android.bp deleted file mode 100644 index e71cc43f13fe3..0000000000000 --- a/apex/permission/framework-s/Android.bp +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (C) 2021 The Android Open Source Project -// -// 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. - -filegroup { - name: "framework-permission-s-sources", - srcs: [ - "java/**/*.java", - "java/**/*.aidl", - ], - path: "java", - visibility: ["//frameworks/base"], -} - -java_library { - name: "framework-permission-s-shared", - srcs: [":framework-permission-s-shared-srcs"], - libs: [ - "framework-annotations-lib", - "unsupportedappusage", - ], - apex_available: [ - "com.android.permission", - "test_com.android.permission", - ], - installable: false, - min_sdk_version: "30", - sdk_version: "module_current", -} - -java_sdk_library { - name: "framework-permission-s", - defaults: ["framework-module-defaults"], - srcs: [ - ":framework-permission-s-sources", - ], - libs: [ - "framework-annotations-lib" - ], - static_libs: [ - "framework-permission-s-shared", - ], - apex_available: [ - "com.android.permission", - "test_com.android.permission", - ], - hostdex: true, - // Restrict access to implementation library. - impl_library_visibility: [ - "//frameworks/base/apex/permission:__subpackages__", - "//packages/modules/Permission:__subpackages__", - ], - installable: true, - jarjar_rules: ":permission-jarjar-rules", - min_sdk_version: "30", - permitted_packages: [ - "android.permission", - "android.app.role", - // For com.android.permission.jarjar. - "com.android.permission", - ], -} diff --git a/apex/permission/framework-s/api/current.txt b/apex/permission/framework-s/api/current.txt deleted file mode 100644 index 4ecc98980c439..0000000000000 --- a/apex/permission/framework-s/api/current.txt +++ /dev/null @@ -1,19 +0,0 @@ -// Signature format: 2.0 -package android.app.role { - - public final class RoleManager { - method @NonNull public android.content.Intent createRequestRoleIntent(@NonNull String); - method public boolean isRoleAvailable(@NonNull String); - method public boolean isRoleHeld(@NonNull String); - field public static final String ROLE_ASSISTANT = "android.app.role.ASSISTANT"; - field public static final String ROLE_BROWSER = "android.app.role.BROWSER"; - field public static final String ROLE_CALL_REDIRECTION = "android.app.role.CALL_REDIRECTION"; - field public static final String ROLE_CALL_SCREENING = "android.app.role.CALL_SCREENING"; - field public static final String ROLE_DIALER = "android.app.role.DIALER"; - field public static final String ROLE_EMERGENCY = "android.app.role.EMERGENCY"; - field public static final String ROLE_HOME = "android.app.role.HOME"; - field public static final String ROLE_SMS = "android.app.role.SMS"; - } - -} - diff --git a/apex/permission/framework-s/api/module-lib-current.txt b/apex/permission/framework-s/api/module-lib-current.txt deleted file mode 100644 index d7c9a2395c043..0000000000000 --- a/apex/permission/framework-s/api/module-lib-current.txt +++ /dev/null @@ -1,11 +0,0 @@ -// Signature format: 2.0 -package android.app.role { - - public final class RoleManager { - method @Nullable public String getBrowserRoleHolder(int); - method @Nullable public String getSmsRoleHolder(int); - method @Nullable @RequiresPermission(android.Manifest.permission.SET_PREFERRED_APPLICATIONS) public boolean setBrowserRoleHolder(@Nullable String, int); - } - -} - diff --git a/apex/permission/framework-s/api/module-lib-removed.txt b/apex/permission/framework-s/api/module-lib-removed.txt deleted file mode 100644 index d802177e249b3..0000000000000 --- a/apex/permission/framework-s/api/module-lib-removed.txt +++ /dev/null @@ -1 +0,0 @@ -// Signature format: 2.0 diff --git a/apex/permission/framework-s/api/removed.txt b/apex/permission/framework-s/api/removed.txt deleted file mode 100644 index d802177e249b3..0000000000000 --- a/apex/permission/framework-s/api/removed.txt +++ /dev/null @@ -1 +0,0 @@ -// Signature format: 2.0 diff --git a/apex/permission/framework-s/api/system-current.txt b/apex/permission/framework-s/api/system-current.txt deleted file mode 100644 index 6778d4826841e..0000000000000 --- a/apex/permission/framework-s/api/system-current.txt +++ /dev/null @@ -1,43 +0,0 @@ -// Signature format: 2.0 -package android.app.role { - - public interface OnRoleHoldersChangedListener { - method public void onRoleHoldersChanged(@NonNull String, @NonNull android.os.UserHandle); - } - - @Deprecated public abstract class RoleControllerService extends android.app.Service { - ctor @Deprecated public RoleControllerService(); - method @Deprecated @WorkerThread public abstract boolean onAddRoleHolder(@NonNull String, @NonNull String, int); - method @Deprecated @Nullable public final android.os.IBinder onBind(@Nullable android.content.Intent); - method @Deprecated @WorkerThread public abstract boolean onClearRoleHolders(@NonNull String, int); - method @Deprecated @WorkerThread public abstract boolean onGrantDefaultRoles(); - method @Deprecated public abstract boolean onIsApplicationQualifiedForRole(@NonNull String, @NonNull String); - method @Deprecated public boolean onIsApplicationVisibleForRole(@NonNull String, @NonNull String); - method @Deprecated public abstract boolean onIsRoleVisible(@NonNull String); - method @Deprecated @WorkerThread public abstract boolean onRemoveRoleHolder(@NonNull String, @NonNull String, int); - field @Deprecated public static final String SERVICE_INTERFACE = "android.app.role.RoleControllerService"; - } - - public class RoleFrameworkInitializer { - method public static void registerServiceWrappers(); - } - - public final class RoleManager { - method @RequiresPermission(android.Manifest.permission.OBSERVE_ROLE_HOLDERS) public void addOnRoleHoldersChangedListenerAsUser(@NonNull java.util.concurrent.Executor, @NonNull android.app.role.OnRoleHoldersChangedListener, @NonNull android.os.UserHandle); - method @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public void addRoleHolderAsUser(@NonNull String, @NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer); - method @Deprecated @RequiresPermission("com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER") public boolean addRoleHolderFromController(@NonNull String, @NonNull String); - method @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public void clearRoleHoldersAsUser(@NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer); - method @Deprecated @NonNull @RequiresPermission("com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER") public java.util.List getHeldRolesFromController(@NonNull String); - method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public java.util.List getRoleHolders(@NonNull String); - method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public java.util.List getRoleHoldersAsUser(@NonNull String, @NonNull android.os.UserHandle); - method @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public void isApplicationVisibleForRole(@NonNull String, @NonNull String, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer); - method @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public void isRoleVisible(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer); - method @RequiresPermission(android.Manifest.permission.OBSERVE_ROLE_HOLDERS) public void removeOnRoleHoldersChangedListenerAsUser(@NonNull android.app.role.OnRoleHoldersChangedListener, @NonNull android.os.UserHandle); - method @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public void removeRoleHolderAsUser(@NonNull String, @NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer); - method @Deprecated @RequiresPermission("com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER") public boolean removeRoleHolderFromController(@NonNull String, @NonNull String); - method @Deprecated @RequiresPermission("com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER") public void setRoleNamesFromController(@NonNull java.util.List); - field public static final int MANAGE_HOLDERS_FLAG_DONT_KILL_APP = 1; // 0x1 - } - -} - diff --git a/apex/permission/framework-s/api/system-removed.txt b/apex/permission/framework-s/api/system-removed.txt deleted file mode 100644 index d802177e249b3..0000000000000 --- a/apex/permission/framework-s/api/system-removed.txt +++ /dev/null @@ -1 +0,0 @@ -// Signature format: 2.0 diff --git a/apex/permission/framework-s/java/android/app/role/IOnRoleHoldersChangedListener.aidl b/apex/permission/framework-s/java/android/app/role/IOnRoleHoldersChangedListener.aidl deleted file mode 100644 index 6cf961fad2c45..0000000000000 --- a/apex/permission/framework-s/java/android/app/role/IOnRoleHoldersChangedListener.aidl +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * 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. - */ - -package android.app.role; - -/** - * @hide - */ -oneway interface IOnRoleHoldersChangedListener { - - void onRoleHoldersChanged(String roleName, int userId); -} diff --git a/apex/permission/framework-s/java/android/app/role/IRoleController.aidl b/apex/permission/framework-s/java/android/app/role/IRoleController.aidl deleted file mode 100644 index 8a43d7fa90364..0000000000000 --- a/apex/permission/framework-s/java/android/app/role/IRoleController.aidl +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * 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. - */ - -package android.app.role; - -import android.os.RemoteCallback; - -/** - * @hide - */ -oneway interface IRoleController { - - void grantDefaultRoles(in RemoteCallback callback); - - void onAddRoleHolder(in String roleName, in String packageName, int flags, - in RemoteCallback callback); - - void onRemoveRoleHolder(in String roleName, in String packageName, int flags, - in RemoteCallback callback); - - void onClearRoleHolders(in String roleName, int flags, in RemoteCallback callback); - - void isApplicationQualifiedForRole(in String roleName, in String packageName, - in RemoteCallback callback); - - void isApplicationVisibleForRole(in String roleName, in String packageName, - in RemoteCallback callback); - - void isRoleVisible(in String roleName, in RemoteCallback callback); -} diff --git a/apex/permission/framework-s/java/android/app/role/IRoleManager.aidl b/apex/permission/framework-s/java/android/app/role/IRoleManager.aidl deleted file mode 100644 index 5fc25f0422e2f..0000000000000 --- a/apex/permission/framework-s/java/android/app/role/IRoleManager.aidl +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * 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. - */ - -package android.app.role; - -import android.app.role.IOnRoleHoldersChangedListener; -import android.os.Bundle; -import android.os.RemoteCallback; - -/** - * @hide - */ -interface IRoleManager { - - boolean isRoleAvailable(in String roleName); - - boolean isRoleHeld(in String roleName, in String packageName); - - List getRoleHoldersAsUser(in String roleName, int userId); - - void addRoleHolderAsUser(in String roleName, in String packageName, int flags, int userId, - in RemoteCallback callback); - - void removeRoleHolderAsUser(in String roleName, in String packageName, int flags, int userId, - in RemoteCallback callback); - - void clearRoleHoldersAsUser(in String roleName, int flags, int userId, - in RemoteCallback callback); - - void addOnRoleHoldersChangedListenerAsUser(IOnRoleHoldersChangedListener listener, int userId); - - void removeOnRoleHoldersChangedListenerAsUser(IOnRoleHoldersChangedListener listener, - int userId); - - void setRoleNamesFromController(in List roleNames); - - boolean addRoleHolderFromController(in String roleName, in String packageName); - - boolean removeRoleHolderFromController(in String roleName, in String packageName); - - List getHeldRolesFromController(in String packageName); - - String getBrowserRoleHolder(int userId); - - boolean setBrowserRoleHolder(String packageName, int userId); - - String getSmsRoleHolder(int userId); -} diff --git a/apex/permission/framework-s/java/android/app/role/OnRoleHoldersChangedListener.java b/apex/permission/framework-s/java/android/app/role/OnRoleHoldersChangedListener.java deleted file mode 100644 index 5958debc86dd7..0000000000000 --- a/apex/permission/framework-s/java/android/app/role/OnRoleHoldersChangedListener.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * 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. - */ - -package android.app.role; - -import android.annotation.NonNull; -import android.annotation.SystemApi; -import android.os.UserHandle; - -/** - * Listener for role holder changes. - * - * @hide - */ -@SystemApi -public interface OnRoleHoldersChangedListener { - - /** - * Called when the holders of roles are changed. - * - * @param roleName the name of the role whose holders are changed - * @param user the user for this role holder change - */ - void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user); -} diff --git a/apex/permission/framework-s/java/android/app/role/RoleControllerManager.java b/apex/permission/framework-s/java/android/app/role/RoleControllerManager.java deleted file mode 100644 index 93a7ae0c82c0f..0000000000000 --- a/apex/permission/framework-s/java/android/app/role/RoleControllerManager.java +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * 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. - */ - -package android.app.role; - -import android.Manifest; -import android.annotation.CallbackExecutor; -import android.annotation.NonNull; -import android.annotation.RequiresPermission; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ServiceInfo; -import android.os.Binder; -import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.os.RemoteCallback; -import android.util.Log; -import android.util.SparseArray; - -import com.android.internal.annotations.GuardedBy; -import com.android.internal.infra.AndroidFuture; -import com.android.internal.infra.ServiceConnector; - -import java.util.concurrent.Executor; -import java.util.concurrent.TimeUnit; -import java.util.function.Consumer; - -/** - * Interface for communicating with the role controller. - * - * @hide - */ -public class RoleControllerManager { - - private static final String LOG_TAG = RoleControllerManager.class.getSimpleName(); - - private static final long REQUEST_TIMEOUT_MILLIS = 15 * 1000; - - private static volatile ComponentName sRemoteServiceComponentName; - - private static final Object sRemoteServicesLock = new Object(); - - /** - * Global remote services (per user) used by all {@link RoleControllerManager managers}. - */ - @GuardedBy("sRemoteServicesLock") - private static final SparseArray> sRemoteServices = - new SparseArray<>(); - - @NonNull - private final ServiceConnector mRemoteService; - - /** - * Initialize the remote service component name once so that we can avoid acquiring the - * PackageManagerService lock in constructor. - * - * @see #createWithInitializedRemoteServiceComponentName(Handler, Context) - * - * @hide - */ - public static void initializeRemoteServiceComponentName(@NonNull Context context) { - sRemoteServiceComponentName = getRemoteServiceComponentName(context); - } - - /** - * Create a {@link RoleControllerManager} instance with the initialized remote service component - * name so that we can avoid acquiring the PackageManagerService lock in constructor. - * - * @see #initializeRemoteServiceComponentName(Context) - * - * @hide - */ - @NonNull - public static RoleControllerManager createWithInitializedRemoteServiceComponentName( - @NonNull Handler handler, @NonNull Context context) { - return new RoleControllerManager(sRemoteServiceComponentName, handler, context); - } - - private RoleControllerManager(@NonNull ComponentName remoteServiceComponentName, - @NonNull Handler handler, @NonNull Context context) { - synchronized (sRemoteServicesLock) { - int userId = context.getUser().getIdentifier(); - ServiceConnector remoteService = sRemoteServices.get(userId); - if (remoteService == null) { - remoteService = new ServiceConnector.Impl(context, - new Intent(RoleControllerService.SERVICE_INTERFACE) - .setComponent(remoteServiceComponentName), - 0 /* bindingFlags */, userId, IRoleController.Stub::asInterface) { - - @Override - protected Handler getJobHandler() { - return handler; - } - }; - sRemoteServices.put(userId, remoteService); - } - mRemoteService = remoteService; - } - } - - /** - * @hide - */ - public RoleControllerManager(@NonNull Context context) { - this(getRemoteServiceComponentName(context), new Handler(Looper.getMainLooper()), context); - } - - @NonNull - private static ComponentName getRemoteServiceComponentName(@NonNull Context context) { - Intent intent = new Intent(RoleControllerService.SERVICE_INTERFACE); - PackageManager packageManager = context.getPackageManager(); - intent.setPackage(packageManager.getPermissionControllerPackageName()); - ServiceInfo serviceInfo = packageManager.resolveService(intent, 0).serviceInfo; - return new ComponentName(serviceInfo.packageName, serviceInfo.name); - } - - /** - * @see RoleControllerService#onGrantDefaultRoles() - * - * @hide - */ - public void grantDefaultRoles(@NonNull @CallbackExecutor Executor executor, - @NonNull Consumer callback) { - AndroidFuture operation = mRemoteService.postAsync(service -> { - AndroidFuture future = new AndroidFuture<>(); - service.grantDefaultRoles(new RemoteCallback(future::complete)); - return future; - }); - propagateCallback(operation, "grantDefaultRoles", executor, callback); - } - - /** - * @see RoleControllerService#onAddRoleHolder(String, String, int) - * - * @hide - */ - public void onAddRoleHolder(@NonNull String roleName, @NonNull String packageName, - @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) { - AndroidFuture operation = mRemoteService.postAsync(service -> { - AndroidFuture future = new AndroidFuture<>(); - service.onAddRoleHolder(roleName, packageName, flags, - new RemoteCallback(future::complete)); - return future; - }); - propagateCallback(operation, "onAddRoleHolder", callback); - } - - /** - * @see RoleControllerService#onRemoveRoleHolder(String, String, int) - * - * @hide - */ - public void onRemoveRoleHolder(@NonNull String roleName, @NonNull String packageName, - @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) { - AndroidFuture operation = mRemoteService.postAsync(service -> { - AndroidFuture future = new AndroidFuture<>(); - service.onRemoveRoleHolder(roleName, packageName, flags, - new RemoteCallback(future::complete)); - return future; - }); - propagateCallback(operation, "onRemoveRoleHolder", callback); - } - - /** - * @see RoleControllerService#onClearRoleHolders(String, int) - * - * @hide - */ - public void onClearRoleHolders(@NonNull String roleName, - @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) { - AndroidFuture operation = mRemoteService.postAsync(service -> { - AndroidFuture future = new AndroidFuture<>(); - service.onClearRoleHolders(roleName, flags, - new RemoteCallback(future::complete)); - return future; - }); - propagateCallback(operation, "onClearRoleHolders", callback); - } - - /** - * @see RoleControllerService#onIsApplicationVisibleForRole(String, String) - * - * @hide - */ - @RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS) - public void isApplicationVisibleForRole(@NonNull String roleName, @NonNull String packageName, - @NonNull @CallbackExecutor Executor executor, @NonNull Consumer callback) { - AndroidFuture operation = mRemoteService.postAsync(service -> { - AndroidFuture future = new AndroidFuture<>(); - service.isApplicationVisibleForRole(roleName, packageName, - new RemoteCallback(future::complete)); - return future; - }); - propagateCallback(operation, "isApplicationVisibleForRole", executor, callback); - } - - /** - * @see RoleControllerService#onIsRoleVisible(String) - * - * @hide - */ - @RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS) - public void isRoleVisible(@NonNull String roleName, - @NonNull @CallbackExecutor Executor executor, @NonNull Consumer callback) { - AndroidFuture operation = mRemoteService.postAsync(service -> { - AndroidFuture future = new AndroidFuture<>(); - service.isRoleVisible(roleName, new RemoteCallback(future::complete)); - return future; - }); - propagateCallback(operation, "isRoleVisible", executor, callback); - } - - private void propagateCallback(AndroidFuture operation, String opName, - @CallbackExecutor @NonNull Executor executor, - Consumer destination) { - operation.orTimeout(REQUEST_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS) - .whenComplete((res, err) -> executor.execute(() -> { - final long token = Binder.clearCallingIdentity(); - try { - if (err != null) { - Log.e(LOG_TAG, "Error calling " + opName + "()", err); - destination.accept(false); - } else { - destination.accept(res != null); - } - } finally { - Binder.restoreCallingIdentity(token); - } - })); - } - - private void propagateCallback(AndroidFuture operation, String opName, - RemoteCallback destination) { - operation.orTimeout(REQUEST_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS) - .whenComplete((res, err) -> { - final long token = Binder.clearCallingIdentity(); - try { - if (err != null) { - Log.e(LOG_TAG, "Error calling " + opName + "()", err); - destination.sendResult(null); - } else { - destination.sendResult(res); - } - } finally { - Binder.restoreCallingIdentity(token); - } - }); - } -} diff --git a/apex/permission/framework-s/java/android/app/role/RoleControllerService.java b/apex/permission/framework-s/java/android/app/role/RoleControllerService.java deleted file mode 100644 index cf7872913f26b..0000000000000 --- a/apex/permission/framework-s/java/android/app/role/RoleControllerService.java +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * 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. - */ - -package android.app.role; - -import android.Manifest; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.annotation.WorkerThread; -import android.app.Service; -import android.content.Intent; -import android.os.Binder; -import android.os.Bundle; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.IBinder; -import android.os.Process; -import android.os.RemoteCallback; -import android.os.UserHandle; - -import com.android.internal.util.Preconditions; - -import java.util.Objects; -import java.util.concurrent.Executor; - -/** - * Abstract base class for the role controller service. - *

- * Subclass should implement the business logic for role management, including enforcing role - * requirements and granting or revoking relevant privileges of roles. This class can only be - * implemented by the permission controller app which is registered in {@code PackageManager}. - * - * @deprecated The role controller service is an internal implementation detail inside role, and it - * may be replaced by other mechanisms in the future and no longer be called. - * - * @hide - */ -@Deprecated -@SystemApi -public abstract class RoleControllerService extends Service { - - /** - * The {@link Intent} that must be declared as handled by the service. - */ - public static final String SERVICE_INTERFACE = "android.app.role.RoleControllerService"; - - private HandlerThread mWorkerThread; - private Handler mWorkerHandler; - - @Override - public void onCreate() { - super.onCreate(); - - mWorkerThread = new HandlerThread(RoleControllerService.class.getSimpleName()); - mWorkerThread.start(); - mWorkerHandler = new Handler(mWorkerThread.getLooper()); - } - - @Override - public void onDestroy() { - super.onDestroy(); - - mWorkerThread.quitSafely(); - } - - @Nullable - @Override - public final IBinder onBind(@Nullable Intent intent) { - return new IRoleController.Stub() { - - @Override - public void grantDefaultRoles(RemoteCallback callback) { - enforceCallerSystemUid("grantDefaultRoles"); - - Objects.requireNonNull(callback, "callback cannot be null"); - - mWorkerHandler.post(() -> RoleControllerService.this.grantDefaultRoles(callback)); - } - - @Override - public void onAddRoleHolder(String roleName, String packageName, int flags, - RemoteCallback callback) { - enforceCallerSystemUid("onAddRoleHolder"); - - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Preconditions.checkStringNotEmpty(packageName, - "packageName cannot be null or empty"); - Objects.requireNonNull(callback, "callback cannot be null"); - - mWorkerHandler.post(() -> RoleControllerService.this.onAddRoleHolder(roleName, - packageName, flags, callback)); - } - - @Override - public void onRemoveRoleHolder(String roleName, String packageName, int flags, - RemoteCallback callback) { - enforceCallerSystemUid("onRemoveRoleHolder"); - - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Preconditions.checkStringNotEmpty(packageName, - "packageName cannot be null or empty"); - Objects.requireNonNull(callback, "callback cannot be null"); - - mWorkerHandler.post(() -> RoleControllerService.this.onRemoveRoleHolder(roleName, - packageName, flags, callback)); - } - - @Override - public void onClearRoleHolders(String roleName, int flags, RemoteCallback callback) { - enforceCallerSystemUid("onClearRoleHolders"); - - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Objects.requireNonNull(callback, "callback cannot be null"); - - mWorkerHandler.post(() -> RoleControllerService.this.onClearRoleHolders(roleName, - flags, callback)); - } - - private void enforceCallerSystemUid(@NonNull String methodName) { - if (Binder.getCallingUid() != Process.SYSTEM_UID) { - throw new SecurityException("Only the system process can call " + methodName - + "()"); - } - } - - @Override - public void isApplicationQualifiedForRole(String roleName, String packageName, - RemoteCallback callback) { - enforceCallingPermission(Manifest.permission.MANAGE_ROLE_HOLDERS, null); - - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Preconditions.checkStringNotEmpty(packageName, - "packageName cannot be null or empty"); - Objects.requireNonNull(callback, "callback cannot be null"); - - boolean qualified = onIsApplicationQualifiedForRole(roleName, packageName); - callback.sendResult(qualified ? Bundle.EMPTY : null); - } - - @Override - public void isApplicationVisibleForRole(String roleName, String packageName, - RemoteCallback callback) { - enforceCallingPermission(Manifest.permission.MANAGE_ROLE_HOLDERS, null); - - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Preconditions.checkStringNotEmpty(packageName, - "packageName cannot be null or empty"); - Objects.requireNonNull(callback, "callback cannot be null"); - - boolean visible = onIsApplicationVisibleForRole(roleName, packageName); - callback.sendResult(visible ? Bundle.EMPTY : null); - } - - @Override - public void isRoleVisible(String roleName, RemoteCallback callback) { - enforceCallingPermission(Manifest.permission.MANAGE_ROLE_HOLDERS, null); - - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Objects.requireNonNull(callback, "callback cannot be null"); - - boolean visible = onIsRoleVisible(roleName); - callback.sendResult(visible ? Bundle.EMPTY : null); - } - }; - } - - private void grantDefaultRoles(@NonNull RemoteCallback callback) { - boolean successful = onGrantDefaultRoles(); - callback.sendResult(successful ? Bundle.EMPTY : null); - } - - private void onAddRoleHolder(@NonNull String roleName, @NonNull String packageName, - @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) { - boolean successful = onAddRoleHolder(roleName, packageName, flags); - callback.sendResult(successful ? Bundle.EMPTY : null); - } - - private void onRemoveRoleHolder(@NonNull String roleName, @NonNull String packageName, - @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) { - boolean successful = onRemoveRoleHolder(roleName, packageName, flags); - callback.sendResult(successful ? Bundle.EMPTY : null); - } - - private void onClearRoleHolders(@NonNull String roleName, - @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) { - boolean successful = onClearRoleHolders(roleName, flags); - callback.sendResult(successful ? Bundle.EMPTY : null); - } - - /** - * Called by system to grant default permissions and roles. - *

- * This is typically when creating a new user or upgrading either system or - * permission controller package - * - * @return whether this call was successful - */ - @WorkerThread - public abstract boolean onGrantDefaultRoles(); - - /** - * Add a specific application to the holders of a role. If the role is exclusive, the previous - * holder will be replaced. - *

- * Implementation should enforce the role requirements and grant or revoke the relevant - * privileges of roles. - * - * @param roleName the name of the role to add the role holder for - * @param packageName the package name of the application to add to the role holders - * @param flags optional behavior flags - * - * @return whether this call was successful - * - * @see RoleManager#addRoleHolderAsUser(String, String, int, UserHandle, Executor, - * RemoteCallback) - */ - @WorkerThread - public abstract boolean onAddRoleHolder(@NonNull String roleName, @NonNull String packageName, - @RoleManager.ManageHoldersFlags int flags); - - /** - * Remove a specific application from the holders of a role. - * - * @param roleName the name of the role to remove the role holder for - * @param packageName the package name of the application to remove from the role holders - * @param flags optional behavior flags - * - * @return whether this call was successful - * - * @see RoleManager#removeRoleHolderAsUser(String, String, int, UserHandle, Executor, - * RemoteCallback) - */ - @WorkerThread - public abstract boolean onRemoveRoleHolder(@NonNull String roleName, - @NonNull String packageName, @RoleManager.ManageHoldersFlags int flags); - - /** - * Remove all holders of a role. - * - * @param roleName the name of the role to remove role holders for - * @param flags optional behavior flags - * - * @return whether this call was successful - * - * @see RoleManager#clearRoleHoldersAsUser(String, int, UserHandle, Executor, RemoteCallback) - */ - @WorkerThread - public abstract boolean onClearRoleHolders(@NonNull String roleName, - @RoleManager.ManageHoldersFlags int flags); - - /** - * Check whether an application is qualified for a role. - * - * @param roleName name of the role to check for - * @param packageName package name of the application to check for - * - * @return whether the application is qualified for the role - * - * @deprecated Implement {@link #onIsApplicationVisibleForRole(String, String)} instead. - */ - @Deprecated - public abstract boolean onIsApplicationQualifiedForRole(@NonNull String roleName, - @NonNull String packageName); - - /** - * Check whether an application is visible for a role. - * - * While an application can be qualified for a role, it can still stay hidden from user (thus - * not visible). If an application is visible for a role, we may show things related to the role - * for it, e.g. showing an entry pointing to the role settings in its application info page. - * - * @param roleName name of the role to check for - * @param packageName package name of the application to check for - * - * @return whether the application is visible for the role - */ - public boolean onIsApplicationVisibleForRole(@NonNull String roleName, - @NonNull String packageName) { - return onIsApplicationQualifiedForRole(roleName, packageName); - } - - /** - * Check whether a role should be visible to user. - * - * @param roleName name of the role to check for - * - * @return whether the role should be visible to user - */ - public abstract boolean onIsRoleVisible(@NonNull String roleName); -} diff --git a/apex/permission/framework-s/java/android/app/role/RoleFrameworkInitializer.java b/apex/permission/framework-s/java/android/app/role/RoleFrameworkInitializer.java deleted file mode 100644 index 7a97770ecf0fe..0000000000000 --- a/apex/permission/framework-s/java/android/app/role/RoleFrameworkInitializer.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * 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. - */ - -package android.app.role; - -import android.annotation.SystemApi; -import android.app.SystemServiceRegistry; -import android.content.Context; - -/** - * Class holding initialization code for role in the permission module. - * - * @hide - */ -@SystemApi -public class RoleFrameworkInitializer { - private RoleFrameworkInitializer() {} - - /** - * Called by {@link SystemServiceRegistry}'s static initializer and registers - * {@link RoleManager} to {@link Context}, so that {@link Context#getSystemService} can return - * it. - * - *

If this is called from other places, it throws a {@link IllegalStateException). - */ - public static void registerServiceWrappers() { - SystemServiceRegistry.registerContextAwareService(Context.ROLE_SERVICE, RoleManager.class, - (context, serviceBinder) -> new RoleManager(context, - IRoleManager.Stub.asInterface(serviceBinder))); - } -} diff --git a/apex/permission/framework-s/java/android/app/role/RoleManager.java b/apex/permission/framework-s/java/android/app/role/RoleManager.java deleted file mode 100644 index ceccc4cfc9f75..0000000000000 --- a/apex/permission/framework-s/java/android/app/role/RoleManager.java +++ /dev/null @@ -1,773 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * 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. - */ - -package android.app.role; - -import android.Manifest; -import android.annotation.CallbackExecutor; -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.RequiresPermission; -import android.annotation.SystemApi; -import android.annotation.SystemService; -import android.annotation.UserIdInt; -import android.content.Context; -import android.content.Intent; -import android.os.Binder; -import android.os.Process; -import android.os.RemoteCallback; -import android.os.RemoteException; -import android.os.UserHandle; -import android.util.ArrayMap; -import android.util.SparseArray; - -import com.android.internal.annotations.GuardedBy; -import com.android.internal.util.Preconditions; - -import java.util.List; -import java.util.Objects; -import java.util.concurrent.Executor; -import java.util.function.Consumer; - -/** - * This class provides information about and manages roles. - *

- * A role is a unique name within the system associated with certain privileges. The list of - * available roles might change with a system app update, so apps should not make assumption about - * the availability of roles. Instead, they should always query if the role is available using - * {@link #isRoleAvailable(String)} before trying to do anything with it. Some predefined role names - * are available as constants in this class, and a list of possibly available roles can be found in - * the AndroidX Role - * library. - *

- * There can be multiple applications qualifying for a role, but only a subset of them can become - * role holders. To qualify for a role, an application must meet certain requirements, including - * defining certain components in its manifest. These requirements can be found in the AndroidX - * Libraries. Then the application will need user consent to become a role holder, which can be - * requested using {@link android.app.Activity#startActivityForResult(Intent, int)} with the - * {@code Intent} obtained from {@link #createRequestRoleIntent(String)}. - *

- * Upon becoming a role holder, the application may be granted certain privileges that are role - * specific. When the application loses its role, these privileges will also be revoked. - */ -@SystemService(Context.ROLE_SERVICE) -public final class RoleManager { - - private static final String LOG_TAG = RoleManager.class.getSimpleName(); - - /** - * The name of the assistant app role. - * - * @see android.service.voice.VoiceInteractionService - */ - public static final String ROLE_ASSISTANT = "android.app.role.ASSISTANT"; - - /** - * The name of the browser role. - * - * @see Intent#CATEGORY_APP_BROWSER - */ - public static final String ROLE_BROWSER = "android.app.role.BROWSER"; - - /** - * The name of the dialer role. - * - * @see Intent#ACTION_DIAL - * @see android.telecom.InCallService - */ - public static final String ROLE_DIALER = "android.app.role.DIALER"; - - /** - * The name of the SMS role. - * - * @see Intent#CATEGORY_APP_MESSAGING - */ - public static final String ROLE_SMS = "android.app.role.SMS"; - - /** - * The name of the emergency role - */ - public static final String ROLE_EMERGENCY = "android.app.role.EMERGENCY"; - - /** - * The name of the home role. - * - * @see Intent#CATEGORY_HOME - */ - public static final String ROLE_HOME = "android.app.role.HOME"; - - /** - * The name of the call redirection role. - *

- * A call redirection app provides a means to re-write the phone number for an outgoing call to - * place the call through a call redirection service. - * - * @see android.telecom.CallRedirectionService - */ - public static final String ROLE_CALL_REDIRECTION = "android.app.role.CALL_REDIRECTION"; - - /** - * The name of the call screening and caller id role. - * - * @see android.telecom.CallScreeningService - */ - public static final String ROLE_CALL_SCREENING = "android.app.role.CALL_SCREENING"; - - /** - * @hide - */ - @IntDef(flag = true, value = { MANAGE_HOLDERS_FLAG_DONT_KILL_APP }) - public @interface ManageHoldersFlags {} - - /** - * Flag parameter for {@link #addRoleHolderAsUser}, {@link #removeRoleHolderAsUser} and - * {@link #clearRoleHoldersAsUser} to indicate that apps should not be killed when changing - * their role holder status. - * - * @hide - */ - @SystemApi - public static final int MANAGE_HOLDERS_FLAG_DONT_KILL_APP = 1; - - /** - * The action used to request user approval of a role for an application. - * - * @hide - */ - public static final String ACTION_REQUEST_ROLE = "android.app.role.action.REQUEST_ROLE"; - - /** - * The permission required to manage records of role holders in {@link RoleManager} directly. - * - * @hide - */ - public static final String PERMISSION_MANAGE_ROLES_FROM_CONTROLLER = - "com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER"; - - @NonNull - private final Context mContext; - - @NonNull - private final IRoleManager mService; - - @GuardedBy("mListenersLock") - @NonNull - private final SparseArray> mListeners = new SparseArray<>(); - @NonNull - private final Object mListenersLock = new Object(); - - @GuardedBy("mRoleControllerManagerLock") - @Nullable - private RoleControllerManager mRoleControllerManager; - private final Object mRoleControllerManagerLock = new Object(); - - /** - * Create a new instance of this class. - * - * @param context the {@link Context} - * @param service the {@link IRoleManager} service - * - * @hide - */ - public RoleManager(@NonNull Context context, @NonNull IRoleManager service) { - mContext = context; - mService = service; - } - - /** - * Returns an {@code Intent} suitable for passing to - * {@link android.app.Activity#startActivityForResult(Intent, int)} which prompts the user to - * grant a role to this application. - *

- * If the role is granted, the {@code resultCode} will be - * {@link android.app.Activity#RESULT_OK}, otherwise it will be - * {@link android.app.Activity#RESULT_CANCELED}. - * - * @param roleName the name of requested role - * - * @return the {@code Intent} to prompt user to grant the role - */ - @NonNull - public Intent createRequestRoleIntent(@NonNull String roleName) { - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Intent intent = new Intent(ACTION_REQUEST_ROLE); - intent.setPackage(mContext.getPackageManager().getPermissionControllerPackageName()); - intent.putExtra(Intent.EXTRA_ROLE_NAME, roleName); - return intent; - } - - /** - * Check whether a role is available in the system. - * - * @param roleName the name of role to checking for - * - * @return whether the role is available in the system - */ - public boolean isRoleAvailable(@NonNull String roleName) { - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - try { - return mService.isRoleAvailable(roleName); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Check whether the calling application is holding a particular role. - * - * @param roleName the name of the role to check for - * - * @return whether the calling application is holding the role - */ - public boolean isRoleHeld(@NonNull String roleName) { - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - try { - return mService.isRoleHeld(roleName, mContext.getPackageName()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Get package names of the applications holding the role. - *

- * Note: Using this API requires holding - * {@code android.permission.MANAGE_ROLE_HOLDERS}. - * - * @param roleName the name of the role to get the role holder for - * - * @return a list of package names of the role holders, or an empty list if none. - * - * @see #getRoleHoldersAsUser(String, UserHandle) - * - * @hide - */ - @NonNull - @RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS) - @SystemApi - public List getRoleHolders(@NonNull String roleName) { - return getRoleHoldersAsUser(roleName, Process.myUserHandle()); - } - - /** - * Get package names of the applications holding the role. - *

- * Note: Using this API requires holding - * {@code android.permission.MANAGE_ROLE_HOLDERS} and if the user id is not the current user - * {@code android.permission.INTERACT_ACROSS_USERS_FULL}. - * - * @param roleName the name of the role to get the role holder for - * @param user the user to get the role holder for - * - * @return a list of package names of the role holders, or an empty list if none. - * - * @see #addRoleHolderAsUser(String, String, int, UserHandle, Executor, Consumer) - * @see #removeRoleHolderAsUser(String, String, int, UserHandle, Executor, Consumer) - * @see #clearRoleHoldersAsUser(String, int, UserHandle, Executor, Consumer) - * - * @hide - */ - @NonNull - @RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS) - @SystemApi - public List getRoleHoldersAsUser(@NonNull String roleName, @NonNull UserHandle user) { - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Objects.requireNonNull(user, "user cannot be null"); - try { - return mService.getRoleHoldersAsUser(roleName, user.getIdentifier()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Add a specific application to the holders of a role. If the role is exclusive, the previous - * holder will be replaced. - *

- * Note: Using this API requires holding - * {@code android.permission.MANAGE_ROLE_HOLDERS} and if the user id is not the current user - * {@code android.permission.INTERACT_ACROSS_USERS_FULL}. - * - * @param roleName the name of the role to add the role holder for - * @param packageName the package name of the application to add to the role holders - * @param flags optional behavior flags - * @param user the user to add the role holder for - * @param executor the {@code Executor} to run the callback on. - * @param callback the callback for whether this call is successful - * - * @see #getRoleHoldersAsUser(String, UserHandle) - * @see #removeRoleHolderAsUser(String, String, int, UserHandle, Executor, Consumer) - * @see #clearRoleHoldersAsUser(String, int, UserHandle, Executor, Consumer) - * - * @hide - */ - @RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS) - @SystemApi - public void addRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName, - @ManageHoldersFlags int flags, @NonNull UserHandle user, - @CallbackExecutor @NonNull Executor executor, @NonNull Consumer callback) { - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); - Objects.requireNonNull(user, "user cannot be null"); - Objects.requireNonNull(executor, "executor cannot be null"); - Objects.requireNonNull(callback, "callback cannot be null"); - try { - mService.addRoleHolderAsUser(roleName, packageName, flags, user.getIdentifier(), - createRemoteCallback(executor, callback)); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Remove a specific application from the holders of a role. - *

- * Note: Using this API requires holding - * {@code android.permission.MANAGE_ROLE_HOLDERS} and if the user id is not the current user - * {@code android.permission.INTERACT_ACROSS_USERS_FULL}. - * - * @param roleName the name of the role to remove the role holder for - * @param packageName the package name of the application to remove from the role holders - * @param flags optional behavior flags - * @param user the user to remove the role holder for - * @param executor the {@code Executor} to run the callback on. - * @param callback the callback for whether this call is successful - * - * @see #getRoleHoldersAsUser(String, UserHandle) - * @see #addRoleHolderAsUser(String, String, int, UserHandle, Executor, Consumer) - * @see #clearRoleHoldersAsUser(String, int, UserHandle, Executor, Consumer) - * - * @hide - */ - @RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS) - @SystemApi - public void removeRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName, - @ManageHoldersFlags int flags, @NonNull UserHandle user, - @CallbackExecutor @NonNull Executor executor, @NonNull Consumer callback) { - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); - Objects.requireNonNull(user, "user cannot be null"); - Objects.requireNonNull(executor, "executor cannot be null"); - Objects.requireNonNull(callback, "callback cannot be null"); - try { - mService.removeRoleHolderAsUser(roleName, packageName, flags, user.getIdentifier(), - createRemoteCallback(executor, callback)); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Remove all holders of a role. - *

- * Note: Using this API requires holding - * {@code android.permission.MANAGE_ROLE_HOLDERS} and if the user id is not the current user - * {@code android.permission.INTERACT_ACROSS_USERS_FULL}. - * - * @param roleName the name of the role to remove role holders for - * @param flags optional behavior flags - * @param user the user to remove role holders for - * @param executor the {@code Executor} to run the callback on. - * @param callback the callback for whether this call is successful - * - * @see #getRoleHoldersAsUser(String, UserHandle) - * @see #addRoleHolderAsUser(String, String, int, UserHandle, Executor, Consumer) - * @see #removeRoleHolderAsUser(String, String, int, UserHandle, Executor, Consumer) - * - * @hide - */ - @RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS) - @SystemApi - public void clearRoleHoldersAsUser(@NonNull String roleName, @ManageHoldersFlags int flags, - @NonNull UserHandle user, @CallbackExecutor @NonNull Executor executor, - @NonNull Consumer callback) { - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Objects.requireNonNull(user, "user cannot be null"); - Objects.requireNonNull(executor, "executor cannot be null"); - Objects.requireNonNull(callback, "callback cannot be null"); - try { - mService.clearRoleHoldersAsUser(roleName, flags, user.getIdentifier(), - createRemoteCallback(executor, callback)); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - @NonNull - private static RemoteCallback createRemoteCallback(@NonNull Executor executor, - @NonNull Consumer callback) { - return new RemoteCallback(result -> executor.execute(() -> { - boolean successful = result != null; - final long token = Binder.clearCallingIdentity(); - try { - callback.accept(successful); - } finally { - Binder.restoreCallingIdentity(token); - } - })); - } - - /** - * Add a listener to observe role holder changes - *

- * Note: Using this API requires holding - * {@code android.permission.OBSERVE_ROLE_HOLDERS} and if the user id is not the current user - * {@code android.permission.INTERACT_ACROSS_USERS_FULL}. - * - * @param executor the {@code Executor} to call the listener on. - * @param listener the listener to be added - * @param user the user to add the listener for - * - * @see #removeOnRoleHoldersChangedListenerAsUser(OnRoleHoldersChangedListener, UserHandle) - * - * @hide - */ - @RequiresPermission(Manifest.permission.OBSERVE_ROLE_HOLDERS) - @SystemApi - public void addOnRoleHoldersChangedListenerAsUser(@CallbackExecutor @NonNull Executor executor, - @NonNull OnRoleHoldersChangedListener listener, @NonNull UserHandle user) { - Objects.requireNonNull(executor, "executor cannot be null"); - Objects.requireNonNull(listener, "listener cannot be null"); - Objects.requireNonNull(user, "user cannot be null"); - int userId = user.getIdentifier(); - synchronized (mListenersLock) { - ArrayMap listeners = - mListeners.get(userId); - if (listeners == null) { - listeners = new ArrayMap<>(); - mListeners.put(userId, listeners); - } else { - if (listeners.containsKey(listener)) { - return; - } - } - OnRoleHoldersChangedListenerDelegate listenerDelegate = - new OnRoleHoldersChangedListenerDelegate(executor, listener); - try { - mService.addOnRoleHoldersChangedListenerAsUser(listenerDelegate, userId); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - listeners.put(listener, listenerDelegate); - } - } - - /** - * Remove a listener observing role holder changes - *

- * Note: Using this API requires holding - * {@code android.permission.OBSERVE_ROLE_HOLDERS} and if the user id is not the current user - * {@code android.permission.INTERACT_ACROSS_USERS_FULL}. - * - * @param listener the listener to be removed - * @param user the user to remove the listener for - * - * @see #addOnRoleHoldersChangedListenerAsUser(Executor, OnRoleHoldersChangedListener, - * UserHandle) - * - * @hide - */ - @RequiresPermission(Manifest.permission.OBSERVE_ROLE_HOLDERS) - @SystemApi - public void removeOnRoleHoldersChangedListenerAsUser( - @NonNull OnRoleHoldersChangedListener listener, @NonNull UserHandle user) { - Objects.requireNonNull(listener, "listener cannot be null"); - Objects.requireNonNull(user, "user cannot be null"); - int userId = user.getIdentifier(); - synchronized (mListenersLock) { - ArrayMap listeners = - mListeners.get(userId); - if (listeners == null) { - return; - } - OnRoleHoldersChangedListenerDelegate listenerDelegate = listeners.get(listener); - if (listenerDelegate == null) { - return; - } - try { - mService.removeOnRoleHoldersChangedListenerAsUser(listenerDelegate, - user.getIdentifier()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - listeners.remove(listener); - if (listeners.isEmpty()) { - mListeners.remove(userId); - } - } - } - - /** - * Set the names of all the available roles. Should only be called from - * {@link android.app.role.RoleControllerService}. - *

- * Note: Using this API requires holding - * {@link #PERMISSION_MANAGE_ROLES_FROM_CONTROLLER}. - * - * @param roleNames the names of all the available roles - * - * @deprecated This is only usable by the role controller service, which is an internal - * implementation detail inside role. - * - * @hide - */ - @Deprecated - @RequiresPermission(PERMISSION_MANAGE_ROLES_FROM_CONTROLLER) - @SystemApi - public void setRoleNamesFromController(@NonNull List roleNames) { - Objects.requireNonNull(roleNames, "roleNames cannot be null"); - try { - mService.setRoleNamesFromController(roleNames); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Add a specific application to the holders of a role, only modifying records inside - * {@link RoleManager}. Should only be called from - * {@link android.app.role.RoleControllerService}. - *

- * Note: Using this API requires holding - * {@link #PERMISSION_MANAGE_ROLES_FROM_CONTROLLER}. - * - * @param roleName the name of the role to add the role holder for - * @param packageName the package name of the application to add to the role holders - * - * @return whether the operation was successful, and will also be {@code true} if a matching - * role holder is already found. - * - * @see #getRoleHolders(String) - * @see #removeRoleHolderFromController(String, String) - * - * @deprecated This is only usable by the role controller service, which is an internal - * implementation detail inside role. - * - * @hide - */ - @Deprecated - @RequiresPermission(PERMISSION_MANAGE_ROLES_FROM_CONTROLLER) - @SystemApi - public boolean addRoleHolderFromController(@NonNull String roleName, - @NonNull String packageName) { - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); - try { - return mService.addRoleHolderFromController(roleName, packageName); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Remove a specific application from the holders of a role, only modifying records inside - * {@link RoleManager}. Should only be called from - * {@link android.app.role.RoleControllerService}. - *

- * Note: Using this API requires holding - * {@link #PERMISSION_MANAGE_ROLES_FROM_CONTROLLER}. - * - * @param roleName the name of the role to remove the role holder for - * @param packageName the package name of the application to remove from the role holders - * - * @return whether the operation was successful, and will also be {@code true} if no matching - * role holder was found to remove. - * - * @see #getRoleHolders(String) - * @see #addRoleHolderFromController(String, String) - * - * @deprecated This is only usable by the role controller service, which is an internal - * implementation detail inside role. - * - * @hide - */ - @Deprecated - @RequiresPermission(PERMISSION_MANAGE_ROLES_FROM_CONTROLLER) - @SystemApi - public boolean removeRoleHolderFromController(@NonNull String roleName, - @NonNull String packageName) { - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); - try { - return mService.removeRoleHolderFromController(roleName, packageName); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Returns the list of all roles that the given package is currently holding - * - * @param packageName the package name - * @return the list of role names - * - * @deprecated This is only usable by the role controller service, which is an internal - * implementation detail inside role. - * - * @hide - */ - @Deprecated - @NonNull - @RequiresPermission(PERMISSION_MANAGE_ROLES_FROM_CONTROLLER) - @SystemApi - public List getHeldRolesFromController(@NonNull String packageName) { - Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); - try { - return mService.getHeldRolesFromController(packageName); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Get the role holder of {@link #ROLE_BROWSER} without requiring - * {@link Manifest.permission#OBSERVE_ROLE_HOLDERS}, as in - * {@link android.content.pm.PackageManager#getDefaultBrowserPackageNameAsUser(int)} - * - * @param userId the user ID - * @return the package name of the default browser, or {@code null} if none - * - * @hide - */ - @Nullable - @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) - public String getBrowserRoleHolder(@UserIdInt int userId) { - try { - return mService.getBrowserRoleHolder(userId); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Set the role holder of {@link #ROLE_BROWSER} requiring - * {@link Manifest.permission.SET_PREFERRED_APPLICATIONS} instead of - * {@link Manifest.permission#MANAGE_ROLE_HOLDERS}, as in - * {@link android.content.pm.PackageManager#setDefaultBrowserPackageNameAsUser(String, int)} - * - * @param packageName the package name of the default browser, or {@code null} if none - * @param userId the user ID - * @return whether the default browser was set successfully - * - * @hide - */ - @Nullable - @RequiresPermission(Manifest.permission.SET_PREFERRED_APPLICATIONS) - @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) - public boolean setBrowserRoleHolder(@Nullable String packageName, @UserIdInt int userId) { - try { - return mService.setBrowserRoleHolder(packageName, userId); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Allows getting the role holder for {@link #ROLE_SMS} without requiring - * {@link Manifest.permission#OBSERVE_ROLE_HOLDERS}, as in - * {@link android.provider.Telephony.Sms#getDefaultSmsPackage(Context)}. - * - * @param userId the user ID to get the default SMS package for - * @return the package name of the default SMS app, or {@code null} if none - * - * @hide - */ - @Nullable - @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) - public String getSmsRoleHolder(@UserIdInt int userId) { - try { - return mService.getSmsRoleHolder(userId); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Check whether a role should be visible to user. - * - * @param roleName name of the role to check for - * @param executor the executor to execute callback on - * @param callback the callback to receive whether the role should be visible to user - * - * @hide - */ - @RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS) - @SystemApi - public void isRoleVisible(@NonNull String roleName, - @NonNull @CallbackExecutor Executor executor, @NonNull Consumer callback) { - getRoleControllerManager().isRoleVisible(roleName, executor, callback); - } - - /** - * Check whether an application is visible for a role. - * - * While an application can be qualified for a role, it can still stay hidden from user (thus - * not visible). If an application is visible for a role, we may show things related to the role - * for it, e.g. showing an entry pointing to the role settings in its application info page. - * - * @param roleName the name of the role to check for - * @param packageName the package name of the application to check for - * @param executor the executor to execute callback on - * @param callback the callback to receive whether the application is visible for the role - * - * @hide - */ - @RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS) - @SystemApi - public void isApplicationVisibleForRole(@NonNull String roleName, @NonNull String packageName, - @NonNull @CallbackExecutor Executor executor, @NonNull Consumer callback) { - getRoleControllerManager().isApplicationVisibleForRole(roleName, packageName, executor, - callback); - } - - @NonNull - private RoleControllerManager getRoleControllerManager() { - synchronized (mRoleControllerManagerLock) { - if (mRoleControllerManager == null) { - mRoleControllerManager = new RoleControllerManager(mContext); - } - return mRoleControllerManager; - } - } - - private static class OnRoleHoldersChangedListenerDelegate - extends IOnRoleHoldersChangedListener.Stub { - - @NonNull - private final Executor mExecutor; - @NonNull - private final OnRoleHoldersChangedListener mListener; - - OnRoleHoldersChangedListenerDelegate(@NonNull Executor executor, - @NonNull OnRoleHoldersChangedListener listener) { - mExecutor = executor; - mListener = listener; - } - - @Override - public void onRoleHoldersChanged(@NonNull String roleName, @UserIdInt int userId) { - final long token = Binder.clearCallingIdentity(); - try { - mExecutor.execute(() -> - mListener.onRoleHoldersChanged(roleName, UserHandle.of(userId))); - } finally { - Binder.restoreCallingIdentity(token); - } - } - } -} diff --git a/apex/permission/framework-s/java/android/app/role/TEST_MAPPING b/apex/permission/framework-s/java/android/app/role/TEST_MAPPING deleted file mode 100644 index f8f140dd716ed..0000000000000 --- a/apex/permission/framework-s/java/android/app/role/TEST_MAPPING +++ /dev/null @@ -1,12 +0,0 @@ -{ - "presubmit": [ - { - "name": "CtsRoleTestCases", - "options": [ - { - "include-filter": "android.app.role.cts.RoleManagerTest" - } - ] - } - ] -} diff --git a/apex/permission/framework/Android.bp b/apex/permission/framework/Android.bp deleted file mode 100644 index 52a61674a5966..0000000000000 --- a/apex/permission/framework/Android.bp +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (C) 2020 The Android Open Source Project -// -// 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. - -filegroup { - name: "framework-permission-sources", - srcs: [ - "java/**/*.java", - "java/**/*.aidl", - ], - path: "java", - visibility: ["//frameworks/base"], -} - -java_sdk_library { - name: "framework-permission", - defaults: ["framework-module-defaults"], - - // Restrict access to implementation library. - impl_library_visibility: [ - "//frameworks/base/apex/permission:__subpackages__", - "//packages/modules/Permission:__subpackages__", - ], - - srcs: [ - ":framework-permission-sources", - ], - - apex_available: [ - "com.android.permission", - "test_com.android.permission", - ], - min_sdk_version: "30", - permitted_packages: [ - "android.permission", - "android.app.role", - ], - hostdex: true, - installable: true, -} diff --git a/apex/permission/framework/api/current.txt b/apex/permission/framework/api/current.txt deleted file mode 100644 index d802177e249b3..0000000000000 --- a/apex/permission/framework/api/current.txt +++ /dev/null @@ -1 +0,0 @@ -// Signature format: 2.0 diff --git a/apex/permission/framework/api/module-lib-current.txt b/apex/permission/framework/api/module-lib-current.txt deleted file mode 100644 index d802177e249b3..0000000000000 --- a/apex/permission/framework/api/module-lib-current.txt +++ /dev/null @@ -1 +0,0 @@ -// Signature format: 2.0 diff --git a/apex/permission/framework/api/module-lib-removed.txt b/apex/permission/framework/api/module-lib-removed.txt deleted file mode 100644 index d802177e249b3..0000000000000 --- a/apex/permission/framework/api/module-lib-removed.txt +++ /dev/null @@ -1 +0,0 @@ -// Signature format: 2.0 diff --git a/apex/permission/framework/api/removed.txt b/apex/permission/framework/api/removed.txt deleted file mode 100644 index d802177e249b3..0000000000000 --- a/apex/permission/framework/api/removed.txt +++ /dev/null @@ -1 +0,0 @@ -// Signature format: 2.0 diff --git a/apex/permission/framework/api/system-current.txt b/apex/permission/framework/api/system-current.txt deleted file mode 100644 index d802177e249b3..0000000000000 --- a/apex/permission/framework/api/system-current.txt +++ /dev/null @@ -1 +0,0 @@ -// Signature format: 2.0 diff --git a/apex/permission/framework/api/system-removed.txt b/apex/permission/framework/api/system-removed.txt deleted file mode 100644 index d802177e249b3..0000000000000 --- a/apex/permission/framework/api/system-removed.txt +++ /dev/null @@ -1 +0,0 @@ -// Signature format: 2.0 diff --git a/apex/permission/framework/java/android/permission/PermissionState.java b/apex/permission/framework/java/android/permission/PermissionState.java deleted file mode 100644 index e810db8ecbfe5..0000000000000 --- a/apex/permission/framework/java/android/permission/PermissionState.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * 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. - */ - -package android.permission; - -/** - * @hide - */ -public class PermissionState {} diff --git a/apex/permission/jarjar-rules.txt b/apex/permission/jarjar-rules.txt deleted file mode 100644 index 4729ed13dc4c7..0000000000000 --- a/apex/permission/jarjar-rules.txt +++ /dev/null @@ -1,5 +0,0 @@ -rule android.os.HandlerExecutor com.android.permission.jarjar.@0 -rule android.util.IndentingPrintWriter com.android.permission.jarjar.@0 -rule com.android.internal.** com.android.permission.jarjar.@0 -rule com.android.modules.** com.android.permission.jarjar.@0 -rule com.android.role.*Proto com.android.permission.jarjar.@0 diff --git a/apex/permission/service/Android.bp b/apex/permission/service/Android.bp deleted file mode 100644 index d0fc5b9d7c146..0000000000000 --- a/apex/permission/service/Android.bp +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (C) 2020 The Android Open Source Project -// -// 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. - -filegroup { - name: "service-permission-sources", - srcs: [ - "java/**/*.java", - ], - path: "java", - visibility: ["//frameworks/base/services"], -} - -filegroup { - name: "service-permission-protos", - srcs: [ - "proto/**/*.proto", - ], - visibility: ["//frameworks/base"], -} - -gensrcs { - name: "service-permission-javastream-protos", - depfile: true, - - tools: [ - "aprotoc", - "protoc-gen-javastream", - "soong_zip", - ], - - cmd: "mkdir -p $(genDir)/$(in) " + - "&& $(location aprotoc) " + - " --plugin=$(location protoc-gen-javastream) " + - " --dependency_out=$(depfile) " + - " --javastream_out=$(genDir)/$(in) " + - " -Iexternal/protobuf/src " + - " -I . " + - " $(in) " + - "&& $(location soong_zip) -jar -o $(out) -C $(genDir)/$(in) -D $(genDir)/$(in)", - - srcs: [ - ":service-permission-protos", - ], - output_extension: "srcjar", -} - -java_library { - name: "service-permission-shared", - srcs: [":service-permission-shared-srcs"], - libs: [ - "framework-annotations-lib", - "framework-permission-s-shared", - ], - apex_available: [ - "com.android.permission", - "test_com.android.permission", - ], - installable: false, - min_sdk_version: "30", - sdk_version: "system_server_current", -} - -java_sdk_library { - name: "service-permission", - defaults: ["framework-system-server-module-defaults"], - impl_library_visibility: [ - "//frameworks/base/apex/permission/tests", - "//frameworks/base/services/tests/mockingservicestests", - "//frameworks/base/services/tests/servicestests", - "//packages/modules/Permission/tests", - ], - srcs: [ - ":service-permission-sources", - ":service-permission-javastream-protos", - ], - libs: [ - "framework-permission", - "framework-permission-s.impl", - "framework-permission-s-shared", - ], - static_libs: [ - "modules-utils-os", - "service-permission-shared", - ], - jarjar_rules: ":permission-jarjar-rules", - min_sdk_version: "30", - sdk_version: "system_server_current", - apex_available: [ - "com.android.permission", - "test_com.android.permission", - ], - installable: true, - // We don't have last-api tracking files for the public part of this jar's API. - unsafe_ignore_missing_latest_api: true, -} diff --git a/apex/permission/service/api/current.txt b/apex/permission/service/api/current.txt deleted file mode 100644 index d802177e249b3..0000000000000 --- a/apex/permission/service/api/current.txt +++ /dev/null @@ -1 +0,0 @@ -// Signature format: 2.0 diff --git a/apex/permission/service/api/removed.txt b/apex/permission/service/api/removed.txt deleted file mode 100644 index d802177e249b3..0000000000000 --- a/apex/permission/service/api/removed.txt +++ /dev/null @@ -1 +0,0 @@ -// Signature format: 2.0 diff --git a/apex/permission/service/api/system-server-current.txt b/apex/permission/service/api/system-server-current.txt deleted file mode 100644 index b1869c2c731dd..0000000000000 --- a/apex/permission/service/api/system-server-current.txt +++ /dev/null @@ -1,54 +0,0 @@ -// Signature format: 2.0 -package com.android.permission.persistence { - - public interface RuntimePermissionsPersistence { - method @NonNull public static com.android.permission.persistence.RuntimePermissionsPersistence createInstance(); - method public void deleteForUser(@NonNull android.os.UserHandle); - method @Nullable public com.android.permission.persistence.RuntimePermissionsState readForUser(@NonNull android.os.UserHandle); - method public void writeForUser(@NonNull com.android.permission.persistence.RuntimePermissionsState, @NonNull android.os.UserHandle); - } - - public final class RuntimePermissionsState { - ctor public RuntimePermissionsState(int, @Nullable String, @NonNull java.util.Map>, @NonNull java.util.Map>); - method @Nullable public String getFingerprint(); - method @NonNull public java.util.Map> getPackagePermissions(); - method @NonNull public java.util.Map> getSharedUserPermissions(); - method public int getVersion(); - field public static final int NO_VERSION = -1; // 0xffffffff - } - - public static final class RuntimePermissionsState.PermissionState { - ctor public RuntimePermissionsState.PermissionState(@NonNull String, boolean, int); - method public int getFlags(); - method @NonNull public String getName(); - method public boolean isGranted(); - } - -} - -package com.android.role { - - public interface RoleManagerLocal { - method @NonNull public java.util.Map> getRolesAndHolders(int); - } - -} - -package com.android.role.persistence { - - public interface RolesPersistence { - method @NonNull public static com.android.role.persistence.RolesPersistence createInstance(); - method public void deleteForUser(@NonNull android.os.UserHandle); - method @Nullable public com.android.role.persistence.RolesState readForUser(@NonNull android.os.UserHandle); - method public void writeForUser(@NonNull com.android.role.persistence.RolesState, @NonNull android.os.UserHandle); - } - - public final class RolesState { - ctor public RolesState(int, @Nullable String, @NonNull java.util.Map>); - method @Nullable public String getPackagesHash(); - method @NonNull public java.util.Map> getRoles(); - method public int getVersion(); - } - -} - diff --git a/apex/permission/service/api/system-server-removed.txt b/apex/permission/service/api/system-server-removed.txt deleted file mode 100644 index d802177e249b3..0000000000000 --- a/apex/permission/service/api/system-server-removed.txt +++ /dev/null @@ -1 +0,0 @@ -// Signature format: 2.0 diff --git a/apex/permission/service/java/com/android/permission/compat/UserHandleCompat.java b/apex/permission/service/java/com/android/permission/compat/UserHandleCompat.java deleted file mode 100644 index 7c711d301f00e..0000000000000 --- a/apex/permission/service/java/com/android/permission/compat/UserHandleCompat.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * 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. - */ - -package com.android.permission.compat; - -import android.annotation.UserIdInt; -import android.os.UserHandle; - -/** - * Helper for accessing features in {@link UserHandle}. - */ -public final class UserHandleCompat { - /** - * A user ID to indicate all users on the device. - */ - public static final int USER_ALL = UserHandle.ALL.getIdentifier(); - - /** - * A user ID to indicate the "system" user of the device. - */ - public static final int USER_SYSTEM = UserHandle.SYSTEM.getIdentifier(); - - private UserHandleCompat() {} - - /** - * Get the user ID of a given UID. - * - * @param uid the UID - * @return the user ID - */ - @UserIdInt - public static int getUserId(int uid) { - return UserHandle.getUserHandleForUid(uid).getIdentifier(); - } -} diff --git a/apex/permission/service/java/com/android/permission/compat/package-info.java b/apex/permission/service/java/com/android/permission/compat/package-info.java deleted file mode 100644 index c89cc8eabb92a..0000000000000 --- a/apex/permission/service/java/com/android/permission/compat/package-info.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * 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. - */ - -/** - * @hide - * TODO(b/146466118) remove this javadoc tag - */ -@android.annotation.Hide -package com.android.permission.compat; diff --git a/apex/permission/service/java/com/android/permission/persistence/IoUtils.java b/apex/permission/service/java/com/android/permission/persistence/IoUtils.java deleted file mode 100644 index 569a78c0ab410..0000000000000 --- a/apex/permission/service/java/com/android/permission/persistence/IoUtils.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * 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. - */ - -package com.android.permission.persistence; - -import android.annotation.NonNull; - -/** - * Utility class for IO. - * - * @hide - */ -public class IoUtils { - - private IoUtils() {} - - /** - * Close 'closeable' ignoring any exceptions. - */ - public static void closeQuietly(@NonNull AutoCloseable closeable) { - try { - closeable.close(); - } catch (Exception ignored) { - // Ignored. - } - } -} diff --git a/apex/permission/service/java/com/android/permission/persistence/RuntimePermissionsPersistence.java b/apex/permission/service/java/com/android/permission/persistence/RuntimePermissionsPersistence.java deleted file mode 100644 index aedba290db1fb..0000000000000 --- a/apex/permission/service/java/com/android/permission/persistence/RuntimePermissionsPersistence.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * 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. - */ - -package com.android.permission.persistence; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.annotation.SystemApi.Client; -import android.os.UserHandle; - -/** - * Persistence for runtime permissions. - * - * TODO(b/147914847): Remove @hide when it becomes the default. - * @hide - */ -@SystemApi(client = Client.SYSTEM_SERVER) -public interface RuntimePermissionsPersistence { - - /** - * Read the runtime permissions from persistence. - * - * This will perform I/O operations synchronously. - * - * @param user the user to read for - * @return the runtime permissions read - */ - @Nullable - RuntimePermissionsState readForUser(@NonNull UserHandle user); - - /** - * Write the runtime permissions to persistence. - * - * This will perform I/O operations synchronously. - * - * @param runtimePermissions the runtime permissions to write - * @param user the user to write for - */ - void writeForUser(@NonNull RuntimePermissionsState runtimePermissions, - @NonNull UserHandle user); - - /** - * Delete the runtime permissions from persistence. - * - * This will perform I/O operations synchronously. - * - * @param user the user to delete for - */ - void deleteForUser(@NonNull UserHandle user); - - /** - * Create a new instance of {@link RuntimePermissionsPersistence} implementation. - * - * @return the new instance. - */ - @NonNull - static RuntimePermissionsPersistence createInstance() { - return new RuntimePermissionsPersistenceImpl(); - } -} diff --git a/apex/permission/service/java/com/android/permission/persistence/RuntimePermissionsPersistenceImpl.java b/apex/permission/service/java/com/android/permission/persistence/RuntimePermissionsPersistenceImpl.java deleted file mode 100644 index e43f59a3377a3..0000000000000 --- a/apex/permission/service/java/com/android/permission/persistence/RuntimePermissionsPersistenceImpl.java +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * 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. - */ - -package com.android.permission.persistence; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.content.ApexEnvironment; -import android.content.pm.PackageManager; -import android.os.UserHandle; -import android.util.ArrayMap; -import android.util.AtomicFile; -import android.util.Log; -import android.util.Xml; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlSerializer; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** - * Persistence implementation for runtime permissions. - * - * TODO(b/147914847): Remove @hide when it becomes the default. - * @hide - */ -public class RuntimePermissionsPersistenceImpl implements RuntimePermissionsPersistence { - - private static final String LOG_TAG = RuntimePermissionsPersistenceImpl.class.getSimpleName(); - - private static final String APEX_MODULE_NAME = "com.android.permission"; - - private static final String RUNTIME_PERMISSIONS_FILE_NAME = "runtime-permissions.xml"; - - private static final String TAG_PACKAGE = "package"; - private static final String TAG_PERMISSION = "permission"; - private static final String TAG_RUNTIME_PERMISSIONS = "runtime-permissions"; - private static final String TAG_SHARED_USER = "shared-user"; - - private static final String ATTRIBUTE_FINGERPRINT = "fingerprint"; - private static final String ATTRIBUTE_FLAGS = "flags"; - private static final String ATTRIBUTE_GRANTED = "granted"; - private static final String ATTRIBUTE_NAME = "name"; - private static final String ATTRIBUTE_VERSION = "version"; - - @Nullable - @Override - public RuntimePermissionsState readForUser(@NonNull UserHandle user) { - File file = getFile(user); - try (FileInputStream inputStream = new AtomicFile(file).openRead()) { - XmlPullParser parser = Xml.newPullParser(); - parser.setInput(inputStream, null); - return parseXml(parser); - } catch (FileNotFoundException e) { - Log.i(LOG_TAG, "runtime-permissions.xml not found"); - return null; - } catch (XmlPullParserException | IOException e) { - throw new IllegalStateException("Failed to read runtime-permissions.xml: " + file , e); - } - } - - @NonNull - private static RuntimePermissionsState parseXml(@NonNull XmlPullParser parser) - throws IOException, XmlPullParserException { - int type; - int depth; - int innerDepth = parser.getDepth() + 1; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && ((depth = parser.getDepth()) >= innerDepth || type != XmlPullParser.END_TAG)) { - if (depth > innerDepth || type != XmlPullParser.START_TAG) { - continue; - } - - if (parser.getName().equals(TAG_RUNTIME_PERMISSIONS)) { - return parseRuntimePermissions(parser); - } - } - throw new IllegalStateException("Missing <" + TAG_RUNTIME_PERMISSIONS - + "> in runtime-permissions.xml"); - } - - @NonNull - private static RuntimePermissionsState parseRuntimePermissions(@NonNull XmlPullParser parser) - throws IOException, XmlPullParserException { - String versionValue = parser.getAttributeValue(null, ATTRIBUTE_VERSION); - int version = versionValue != null ? Integer.parseInt(versionValue) - : RuntimePermissionsState.NO_VERSION; - String fingerprint = parser.getAttributeValue(null, ATTRIBUTE_FINGERPRINT); - - Map> packagePermissions = - new ArrayMap<>(); - Map> sharedUserPermissions = - new ArrayMap<>(); - int type; - int depth; - int innerDepth = parser.getDepth() + 1; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && ((depth = parser.getDepth()) >= innerDepth || type != XmlPullParser.END_TAG)) { - if (depth > innerDepth || type != XmlPullParser.START_TAG) { - continue; - } - - switch (parser.getName()) { - case TAG_PACKAGE: { - String packageName = parser.getAttributeValue(null, ATTRIBUTE_NAME); - List permissions = parsePermissions( - parser); - packagePermissions.put(packageName, permissions); - break; - } - case TAG_SHARED_USER: { - String sharedUserName = parser.getAttributeValue(null, ATTRIBUTE_NAME); - List permissions = parsePermissions( - parser); - sharedUserPermissions.put(sharedUserName, permissions); - break; - } - } - } - - return new RuntimePermissionsState(version, fingerprint, packagePermissions, - sharedUserPermissions); - } - - @NonNull - private static List parsePermissions( - @NonNull XmlPullParser parser) throws IOException, XmlPullParserException { - List permissions = new ArrayList<>(); - int type; - int depth; - int innerDepth = parser.getDepth() + 1; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && ((depth = parser.getDepth()) >= innerDepth || type != XmlPullParser.END_TAG)) { - if (depth > innerDepth || type != XmlPullParser.START_TAG) { - continue; - } - - if (parser.getName().equals(TAG_PERMISSION)) { - String name = parser.getAttributeValue(null, ATTRIBUTE_NAME); - boolean granted = Boolean.parseBoolean(parser.getAttributeValue(null, - ATTRIBUTE_GRANTED)); - int flags = Integer.parseInt(parser.getAttributeValue(null, - ATTRIBUTE_FLAGS), 16); - RuntimePermissionsState.PermissionState permission = - new RuntimePermissionsState.PermissionState(name, granted, flags); - permissions.add(permission); - } - } - return permissions; - } - - @Override - public void writeForUser(@NonNull RuntimePermissionsState runtimePermissions, - @NonNull UserHandle user) { - File file = getFile(user); - AtomicFile atomicFile = new AtomicFile(file); - FileOutputStream outputStream = null; - try { - outputStream = atomicFile.startWrite(); - - XmlSerializer serializer = Xml.newSerializer(); - serializer.setOutput(outputStream, StandardCharsets.UTF_8.name()); - serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); - serializer.startDocument(null, true); - - serializeRuntimePermissions(serializer, runtimePermissions); - - serializer.endDocument(); - atomicFile.finishWrite(outputStream); - } catch (Exception e) { - Log.wtf(LOG_TAG, "Failed to write runtime-permissions.xml, restoring backup: " + file, - e); - atomicFile.failWrite(outputStream); - } finally { - IoUtils.closeQuietly(outputStream); - } - } - - private static void serializeRuntimePermissions(@NonNull XmlSerializer serializer, - @NonNull RuntimePermissionsState runtimePermissions) throws IOException { - serializer.startTag(null, TAG_RUNTIME_PERMISSIONS); - - int version = runtimePermissions.getVersion(); - serializer.attribute(null, ATTRIBUTE_VERSION, Integer.toString(version)); - String fingerprint = runtimePermissions.getFingerprint(); - if (fingerprint != null) { - serializer.attribute(null, ATTRIBUTE_FINGERPRINT, fingerprint); - } - - for (Map.Entry> entry - : runtimePermissions.getPackagePermissions().entrySet()) { - String packageName = entry.getKey(); - List permissions = entry.getValue(); - - serializer.startTag(null, TAG_PACKAGE); - serializer.attribute(null, ATTRIBUTE_NAME, packageName); - serializePermissions(serializer, permissions); - serializer.endTag(null, TAG_PACKAGE); - } - - for (Map.Entry> entry - : runtimePermissions.getSharedUserPermissions().entrySet()) { - String sharedUserName = entry.getKey(); - List permissions = entry.getValue(); - - serializer.startTag(null, TAG_SHARED_USER); - serializer.attribute(null, ATTRIBUTE_NAME, sharedUserName); - serializePermissions(serializer, permissions); - serializer.endTag(null, TAG_SHARED_USER); - } - - serializer.endTag(null, TAG_RUNTIME_PERMISSIONS); - } - - private static void serializePermissions(@NonNull XmlSerializer serializer, - @NonNull List permissions) throws IOException { - int permissionsSize = permissions.size(); - for (int i = 0; i < permissionsSize; i++) { - RuntimePermissionsState.PermissionState permissionState = permissions.get(i); - - serializer.startTag(null, TAG_PERMISSION); - serializer.attribute(null, ATTRIBUTE_NAME, permissionState.getName()); - serializer.attribute(null, ATTRIBUTE_GRANTED, Boolean.toString( - permissionState.isGranted() && (permissionState.getFlags() - & PackageManager.FLAG_PERMISSION_ONE_TIME) == 0)); - serializer.attribute(null, ATTRIBUTE_FLAGS, Integer.toHexString( - permissionState.getFlags())); - serializer.endTag(null, TAG_PERMISSION); - } - } - - @Override - public void deleteForUser(@NonNull UserHandle user) { - getFile(user).delete(); - } - - @NonNull - private static File getFile(@NonNull UserHandle user) { - ApexEnvironment apexEnvironment = ApexEnvironment.getApexEnvironment(APEX_MODULE_NAME); - File dataDirectory = apexEnvironment.getDeviceProtectedDataDirForUser(user); - return new File(dataDirectory, RUNTIME_PERMISSIONS_FILE_NAME); - } -} diff --git a/apex/permission/service/java/com/android/permission/persistence/RuntimePermissionsState.java b/apex/permission/service/java/com/android/permission/persistence/RuntimePermissionsState.java deleted file mode 100644 index c6bfc6d329893..0000000000000 --- a/apex/permission/service/java/com/android/permission/persistence/RuntimePermissionsState.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * 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. - */ - -package com.android.permission.persistence; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.annotation.SystemApi.Client; - -import java.util.List; -import java.util.Map; -import java.util.Objects; - -/** - * State of all runtime permissions. - * - * TODO(b/147914847): Remove @hide when it becomes the default. - * @hide - */ -@SystemApi(client = Client.SYSTEM_SERVER) -public final class RuntimePermissionsState { - - /** - * Special value for {@link #mVersion} to indicate that no version was read. - */ - public static final int NO_VERSION = -1; - - /** - * The version of the runtime permissions. - */ - private final int mVersion; - - /** - * The fingerprint of the runtime permissions. - */ - @Nullable - private final String mFingerprint; - - /** - * The runtime permissions by packages. - */ - @NonNull - private final Map> mPackagePermissions; - - /** - * The runtime permissions by shared users. - */ - @NonNull - private final Map> mSharedUserPermissions; - - /** - * Create a new instance of this class. - * - * @param version the version of the runtime permissions - * @param fingerprint the fingerprint of the runtime permissions - * @param packagePermissions the runtime permissions by packages - * @param sharedUserPermissions the runtime permissions by shared users - */ - public RuntimePermissionsState(int version, @Nullable String fingerprint, - @NonNull Map> packagePermissions, - @NonNull Map> sharedUserPermissions) { - mVersion = version; - mFingerprint = fingerprint; - mPackagePermissions = packagePermissions; - mSharedUserPermissions = sharedUserPermissions; - } - - /** - * Get the version of the runtime permissions. - * - * @return the version of the runtime permissions - */ - public int getVersion() { - return mVersion; - } - - /** - * Get the fingerprint of the runtime permissions. - * - * @return the fingerprint of the runtime permissions - */ - @Nullable - public String getFingerprint() { - return mFingerprint; - } - - /** - * Get the runtime permissions by packages. - * - * @return the runtime permissions by packages - */ - @NonNull - public Map> getPackagePermissions() { - return mPackagePermissions; - } - - /** - * Get the runtime permissions by shared users. - * - * @return the runtime permissions by shared users - */ - @NonNull - public Map> getSharedUserPermissions() { - return mSharedUserPermissions; - } - - @Override - public boolean equals(Object object) { - if (this == object) { - return true; - } - if (object == null || getClass() != object.getClass()) { - return false; - } - RuntimePermissionsState that = (RuntimePermissionsState) object; - return mVersion == that.mVersion - && Objects.equals(mFingerprint, that.mFingerprint) - && Objects.equals(mPackagePermissions, that.mPackagePermissions) - && Objects.equals(mSharedUserPermissions, that.mSharedUserPermissions); - } - - @Override - public int hashCode() { - return Objects.hash(mVersion, mFingerprint, mPackagePermissions, mSharedUserPermissions); - } - - /** - * State of a single permission. - */ - public static final class PermissionState { - - /** - * The name of the permission. - */ - @NonNull - private final String mName; - - /** - * Whether the permission is granted. - */ - private final boolean mGranted; - - /** - * The flags of the permission. - */ - private final int mFlags; - - /** - * Create a new instance of this class. - * - * @param name the name of the permission - * @param granted whether the permission is granted - * @param flags the flags of the permission - */ - public PermissionState(@NonNull String name, boolean granted, int flags) { - mName = name; - mGranted = granted; - mFlags = flags; - } - - /** - * Get the name of the permission. - * - * @return the name of the permission - */ - @NonNull - public String getName() { - return mName; - } - - /** - * Get whether the permission is granted. - * - * @return whether the permission is granted - */ - public boolean isGranted() { - return mGranted; - } - - /** - * Get the flags of the permission. - * - * @return the flags of the permission - */ - public int getFlags() { - return mFlags; - } - - @Override - public boolean equals(Object object) { - if (this == object) { - return true; - } - if (object == null || getClass() != object.getClass()) { - return false; - } - PermissionState that = (PermissionState) object; - return mGranted == that.mGranted - && mFlags == that.mFlags - && Objects.equals(mName, that.mName); - } - - @Override - public int hashCode() { - return Objects.hash(mName, mGranted, mFlags); - } - } -} diff --git a/apex/permission/service/java/com/android/permission/util/ArrayUtils.java b/apex/permission/service/java/com/android/permission/util/ArrayUtils.java deleted file mode 100644 index 5d5cd78201bdd..0000000000000 --- a/apex/permission/service/java/com/android/permission/util/ArrayUtils.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * 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. - */ - -package com.android.permission.util; - -import android.annotation.Nullable; - -import java.util.Objects; - -/** - * Array utilities. - */ -public final class ArrayUtils { - private ArrayUtils() {} - - /** - * @see java.util.List#contains(Object) - */ - public static boolean contains(@Nullable T[] array, T value) { - return indexOf(array, value) != -1; - } - - /** - * Get the first element of an array, or {@code null} if none. - * - * @param array the array - * @param the type of the elements of the array - * @return first element of an array, or {@code null} if none - */ - public static T firstOrNull(@Nullable T[] array) { - return !isEmpty(array) ? array[0] : null; - } - - /** - * @see java.util.List#indexOf(Object) - */ - public static int indexOf(@Nullable T[] array, T value) { - if (array == null) { - return -1; - } - final int length = array.length; - for (int i = 0; i < length; i++) { - final T element = array[i]; - if (Objects.equals(element, value)) { - return i; - } - } - return -1; - } - - /** - * @see java.util.List#isEmpty() - */ - public static boolean isEmpty(@Nullable T[] array) { - return array == null || array.length == 0; - } -} diff --git a/apex/permission/service/java/com/android/permission/util/BackgroundThread.java b/apex/permission/service/java/com/android/permission/util/BackgroundThread.java deleted file mode 100644 index 7308eec985008..0000000000000 --- a/apex/permission/service/java/com/android/permission/util/BackgroundThread.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * 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. - */ - -package com.android.permission.util; - -import android.annotation.NonNull; -import android.os.Handler; -import android.os.HandlerExecutor; -import android.os.HandlerThread; - -import com.android.internal.annotations.GuardedBy; - -import java.util.concurrent.Executor; - -/** - * Shared singleton background thread. - */ -public class BackgroundThread extends HandlerThread { - private static final Object sLock = new Object(); - - @GuardedBy("sLock") - private static BackgroundThread sInstance; - @GuardedBy("sLock") - private static Handler sHandler; - @GuardedBy("sLock") - private static Executor sExecutor; - - private BackgroundThread() { - super(BackgroundThread.class.getName()); - } - - @GuardedBy("sLock") - private static void ensureInstanceLocked() { - if (sInstance == null) { - sInstance = new BackgroundThread(); - sInstance.start(); - sHandler = new Handler(sInstance.getLooper()); - sExecutor = new HandlerExecutor(sHandler); - } - } - - /** - * Get the singleton instance of thi class. - * - * @return the singleton instance of thi class - */ - @NonNull - public static BackgroundThread get() { - synchronized (sLock) { - ensureInstanceLocked(); - return sInstance; - } - } - - /** - * Get the {@link Handler} for this thread. - * - * @return the {@link Handler} for this thread. - */ - @NonNull - public static Handler getHandler() { - synchronized (sLock) { - ensureInstanceLocked(); - return sHandler; - } - } - - /** - * Get the {@link Executor} for this thread. - * - * @return the {@link Executor} for this thread. - */ - @NonNull - public static Executor getExecutor() { - synchronized (sLock) { - ensureInstanceLocked(); - return sExecutor; - } - } -} diff --git a/apex/permission/service/java/com/android/permission/util/CollectionUtils.java b/apex/permission/service/java/com/android/permission/util/CollectionUtils.java deleted file mode 100644 index ea49524041790..0000000000000 --- a/apex/permission/service/java/com/android/permission/util/CollectionUtils.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * 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. - */ - -package com.android.permission.util; - -import android.annotation.Nullable; - -import java.util.Collection; -import java.util.List; -import java.util.Map; - -/** - * {@link Collection} utilities. - */ -public class CollectionUtils { - private CollectionUtils() {} - - /** - * Get the first element of a {@link List}, or {@code null} if none. - * - * @param list the {@link List}, or {@code null} - * @param the element type of the {@link List} - * @return the first element of the {@link List}, or {@code 0} if none - */ - @Nullable - public static E firstOrNull(@Nullable List list) { - return !isEmpty(list) ? list.get(0) : null; - } - - /** - * Check whether a {@link Collection} is empty or {@code null}. - * - * @param collection the {@link Collection}, or {@code null} - * @return whether the {@link Collection} is empty or {@code null} - */ - public static boolean isEmpty(@Nullable Collection collection) { - return collection == null || collection.isEmpty(); - } - - /** - * Get the size of a {@link Collection}, or {@code 0} if {@code null}. - * - * @param collection the {@link Collection}, or {@code null} - * @return the size of the {@link Collection}, or {@code 0} if {@code null} - */ - public static int size(@Nullable Collection collection) { - return collection != null ? collection.size() : 0; - } - - /** - * Get the size of a {@link Map}, or {@code 0} if {@code null}. - * - * @param collection the {@link Map}, or {@code null} - * @return the size of the {@link Map}, or {@code 0} if {@code null} - */ - public static int size(@Nullable Map collection) { - return collection != null ? collection.size() : 0; - } -} diff --git a/apex/permission/service/java/com/android/permission/util/ForegroundThread.java b/apex/permission/service/java/com/android/permission/util/ForegroundThread.java deleted file mode 100644 index cd6f6057030b0..0000000000000 --- a/apex/permission/service/java/com/android/permission/util/ForegroundThread.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * 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. - */ - -package com.android.permission.util; - -import android.annotation.NonNull; -import android.os.Handler; -import android.os.HandlerExecutor; -import android.os.HandlerThread; - -import com.android.internal.annotations.GuardedBy; - -import java.util.concurrent.Executor; - -/** - * Shared singleton foreground thread. - */ -public class ForegroundThread extends HandlerThread { - private static final Object sLock = new Object(); - - @GuardedBy("sLock") - private static ForegroundThread sInstance; - @GuardedBy("sLock") - private static Handler sHandler; - @GuardedBy("sLock") - private static Executor sExecutor; - - private ForegroundThread() { - super(ForegroundThread.class.getName()); - } - - @GuardedBy("sLock") - private static void ensureInstanceLocked() { - if (sInstance == null) { - sInstance = new ForegroundThread(); - sInstance.start(); - sHandler = new Handler(sInstance.getLooper()); - sExecutor = new HandlerExecutor(sHandler); - } - } - - /** - * Get the singleton instance of thi class. - * - * @return the singleton instance of thi class - */ - @NonNull - public static ForegroundThread get() { - synchronized (sLock) { - ensureInstanceLocked(); - return sInstance; - } - } - - /** - * Get the {@link Handler} for this thread. - * - * @return the {@link Handler} for this thread. - */ - @NonNull - public static Handler getHandler() { - synchronized (sLock) { - ensureInstanceLocked(); - return sHandler; - } - } - - /** - * Get the {@link Executor} for this thread. - * - * @return the {@link Executor} for this thread. - */ - @NonNull - public static Executor getExecutor() { - synchronized (sLock) { - ensureInstanceLocked(); - return sExecutor; - } - } -} diff --git a/apex/permission/service/java/com/android/permission/util/ThrottledRunnable.java b/apex/permission/service/java/com/android/permission/util/ThrottledRunnable.java deleted file mode 100644 index ba1c3939f73ea..0000000000000 --- a/apex/permission/service/java/com/android/permission/util/ThrottledRunnable.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * 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. - */ - -package com.android.permission.util; - -import android.annotation.NonNull; -import android.os.Handler; -import android.os.SystemClock; - -import com.android.internal.annotations.GuardedBy; - -/** - * A throttled runnable that can wrap around a runnable and throttle calls to its run(). - * - * The throttling logic makes sure that the original runnable will be called only after the - * specified interval passes since the last actual call. The first call in a while (after the - * specified interval passes since the last actual call) will always result in the original runnable - * being called immediately, and then subsequent calls will start to be throttled. It is guaranteed - * that any call to this throttled runnable will always result in the original runnable being called - * afterwards, within the specified interval. - */ -public class ThrottledRunnable implements Runnable { - - @NonNull - private final Handler mHandler; - private final long mIntervalMillis; - @NonNull - private final Runnable mRunnable; - - @NonNull - private final Object mLock = new Object(); - - @GuardedBy("mLock") - private long mScheduledUptimeMillis; - - public ThrottledRunnable(@NonNull Handler handler, long intervalMillis, - @NonNull Runnable runnable) { - mHandler = handler; - mIntervalMillis = intervalMillis; - mRunnable = runnable; - } - - @Override - public void run() { - synchronized (mLock) { - if (mHandler.hasCallbacks(mRunnable)) { - // We have a scheduled runnable. - return; - } - long currentUptimeMillis = SystemClock.uptimeMillis(); - if (mScheduledUptimeMillis == 0 - || currentUptimeMillis > mScheduledUptimeMillis + mIntervalMillis) { - // First time in a while, schedule immediately. - mScheduledUptimeMillis = currentUptimeMillis; - } else { - // We were scheduled not long ago, so schedule with delay for throttling. - mScheduledUptimeMillis = mScheduledUptimeMillis + mIntervalMillis; - } - mHandler.postAtTime(mRunnable, mScheduledUptimeMillis); - } - } -} diff --git a/apex/permission/service/java/com/android/permission/util/package-info.java b/apex/permission/service/java/com/android/permission/util/package-info.java deleted file mode 100644 index 18fada534424b..0000000000000 --- a/apex/permission/service/java/com/android/permission/util/package-info.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * 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. - */ - -/** - * @hide - * TODO(b/146466118) remove this javadoc tag - */ -@android.annotation.Hide -package com.android.permission.util; diff --git a/apex/permission/service/java/com/android/role/RoleManagerLocal.java b/apex/permission/service/java/com/android/role/RoleManagerLocal.java deleted file mode 100644 index e243e2e0db66c..0000000000000 --- a/apex/permission/service/java/com/android/role/RoleManagerLocal.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * 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. - */ - -package com.android.role; - -import android.annotation.NonNull; -import android.annotation.SystemApi; -import android.annotation.UserIdInt; - -import java.util.Map; -import java.util.Set; - -/** - * Internal calls into {@link RoleService}. - * - * @hide - */ -@SystemApi(client = SystemApi.Client.SYSTEM_SERVER) -public interface RoleManagerLocal { - /** - * Get all roles and their holders. - * - * @param userId The user to query to roles for - * - * @return The roles and their holders - */ - @NonNull - Map> getRolesAndHolders(@UserIdInt int userId); -} diff --git a/apex/permission/service/java/com/android/role/RoleService.java b/apex/permission/service/java/com/android/role/RoleService.java deleted file mode 100644 index 5f7eb22a42a70..0000000000000 --- a/apex/permission/service/java/com/android/role/RoleService.java +++ /dev/null @@ -1,736 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * 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. - */ - -package com.android.role; - -import android.Manifest; -import android.annotation.AnyThread; -import android.annotation.MainThread; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.UserIdInt; -import android.annotation.WorkerThread; -import android.app.AppOpsManager; -import android.app.role.IOnRoleHoldersChangedListener; -import android.app.role.IRoleManager; -import android.app.role.RoleControllerManager; -import android.app.role.RoleManager; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.PackageManager; -import android.os.Binder; -import android.os.Handler; -import android.os.ParcelFileDescriptor; -import android.os.Process; -import android.os.RemoteCallback; -import android.os.RemoteCallbackList; -import android.os.RemoteException; -import android.os.UserHandle; -import android.os.UserManager; -import android.text.TextUtils; -import android.util.ArraySet; -import android.util.IndentingPrintWriter; -import android.util.Log; -import android.util.SparseArray; -import android.util.proto.ProtoOutputStream; - -import com.android.internal.annotations.GuardedBy; -import com.android.internal.infra.AndroidFuture; -import com.android.internal.util.Preconditions; -import com.android.internal.util.dump.DualDumpOutputStream; -import com.android.permission.compat.UserHandleCompat; -import com.android.permission.util.ArrayUtils; -import com.android.permission.util.CollectionUtils; -import com.android.permission.util.ForegroundThread; -import com.android.permission.util.ThrottledRunnable; -import com.android.server.LocalManagerRegistry; -import com.android.server.SystemService; -import com.android.server.role.RoleServicePlatformHelper; - -import java.io.FileDescriptor; -import java.io.FileOutputStream; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -/** - * Service for role management. - * - * @see RoleManager - */ -public class RoleService extends SystemService implements RoleUserState.Callback { - private static final String LOG_TAG = RoleService.class.getSimpleName(); - - private static final boolean DEBUG = false; - - private static final long GRANT_DEFAULT_ROLES_INTERVAL_MILLIS = 1000; - - @NonNull - private final AppOpsManager mAppOpsManager; - @NonNull - private final UserManager mUserManager; - - @NonNull - private final Object mLock = new Object(); - - @NonNull - private final RoleServicePlatformHelper mPlatformHelper; - - /** - * Maps user id to its state. - */ - @GuardedBy("mLock") - @NonNull - private final SparseArray mUserStates = new SparseArray<>(); - - /** - * Maps user id to its controller. - */ - @GuardedBy("mLock") - @NonNull - private final SparseArray mControllers = new SparseArray<>(); - - /** - * Maps user id to its list of listeners. - */ - @GuardedBy("mLock") - @NonNull - private final SparseArray> mListeners = - new SparseArray<>(); - - @NonNull - private final Handler mListenerHandler = ForegroundThread.getHandler(); - - /** - * Maps user id to its throttled runnable for granting default roles. - */ - @GuardedBy("mLock") - @NonNull - private final SparseArray mGrantDefaultRolesThrottledRunnables = - new SparseArray<>(); - - public RoleService(@NonNull Context context) { - super(context); - - mPlatformHelper = LocalManagerRegistry.getManager(RoleServicePlatformHelper.class); - - RoleControllerManager.initializeRemoteServiceComponentName(context); - - mAppOpsManager = context.getSystemService(AppOpsManager.class); - mUserManager = context.getSystemService(UserManager.class); - - LocalManagerRegistry.addManager(RoleManagerLocal.class, new Local()); - - registerUserRemovedReceiver(); - } - - private void registerUserRemovedReceiver() { - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(Intent.ACTION_USER_REMOVED); - getContext().registerReceiverForAllUsers(new BroadcastReceiver() { - @Override - public void onReceive(@NonNull Context context, @NonNull Intent intent) { - if (TextUtils.equals(intent.getAction(), Intent.ACTION_USER_REMOVED)) { - int userId = intent.getParcelableExtra(Intent.EXTRA_USER) - .getIdentifier(); - onRemoveUser(userId); - } - } - }, intentFilter, null, null); - } - - @Override - public void onStart() { - publishBinderService(Context.ROLE_SERVICE, new Stub()); - - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED); - intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); - intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); - intentFilter.addDataScheme("package"); - intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); - getContext().registerReceiverForAllUsers(new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - int userId = UserHandleCompat.getUserId(intent.getIntExtra(Intent.EXTRA_UID, -1)); - if (DEBUG) { - Log.i(LOG_TAG, "Packages changed - re-running initial grants for user " - + userId); - } - if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) - && intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { - // Package is being upgraded - we're about to get ACTION_PACKAGE_ADDED - return; - } - maybeGrantDefaultRolesAsync(userId); - } - }, intentFilter, null, null); - } - - @Override - public void onUserStarting(@NonNull TargetUser user) { - maybeGrantDefaultRolesSync(user.getUserHandle().getIdentifier()); - } - - @MainThread - private void maybeGrantDefaultRolesSync(@UserIdInt int userId) { - AndroidFuture future = maybeGrantDefaultRolesInternal(userId); - try { - future.get(30, TimeUnit.SECONDS); - } catch (InterruptedException | ExecutionException | TimeoutException e) { - Log.e(LOG_TAG, "Failed to grant default roles for user " + userId, e); - } - } - - private void maybeGrantDefaultRolesAsync(@UserIdInt int userId) { - ThrottledRunnable runnable; - synchronized (mLock) { - runnable = mGrantDefaultRolesThrottledRunnables.get(userId); - if (runnable == null) { - runnable = new ThrottledRunnable(ForegroundThread.getHandler(), - GRANT_DEFAULT_ROLES_INTERVAL_MILLIS, - () -> maybeGrantDefaultRolesInternal(userId)); - mGrantDefaultRolesThrottledRunnables.put(userId, runnable); - } - } - runnable.run(); - } - - @AnyThread - @NonNull - private AndroidFuture maybeGrantDefaultRolesInternal(@UserIdInt int userId) { - RoleUserState userState = getOrCreateUserState(userId); - String oldPackagesHash = userState.getPackagesHash(); - String newPackagesHash = mPlatformHelper.computePackageStateHash(userId); - if (Objects.equals(oldPackagesHash, newPackagesHash)) { - if (DEBUG) { - Log.i(LOG_TAG, "Already granted default roles for packages hash " - + newPackagesHash); - } - return AndroidFuture.completedFuture(null); - } - - // Some package state has changed, so grant default roles again. - Log.i(LOG_TAG, "Granting default roles..."); - AndroidFuture future = new AndroidFuture<>(); - getOrCreateController(userId).grantDefaultRoles(ForegroundThread.getExecutor(), - successful -> { - if (successful) { - userState.setPackagesHash(newPackagesHash); - future.complete(null); - } else { - future.completeExceptionally(new RuntimeException()); - } - }); - return future; - } - - @NonNull - private RoleUserState getOrCreateUserState(@UserIdInt int userId) { - synchronized (mLock) { - RoleUserState userState = mUserStates.get(userId); - if (userState == null) { - userState = new RoleUserState(userId, mPlatformHelper, this); - mUserStates.put(userId, userState); - } - return userState; - } - } - - @NonNull - private RoleControllerManager getOrCreateController(@UserIdInt int userId) { - synchronized (mLock) { - RoleControllerManager controller = mControllers.get(userId); - if (controller == null) { - Context systemContext = getContext(); - Context context; - try { - context = systemContext.createPackageContextAsUser( - systemContext.getPackageName(), 0, UserHandle.of(userId)); - } catch (PackageManager.NameNotFoundException e) { - throw new RuntimeException(e); - } - controller = RoleControllerManager.createWithInitializedRemoteServiceComponentName( - ForegroundThread.getHandler(), context); - mControllers.put(userId, controller); - } - return controller; - } - } - - @Nullable - private RemoteCallbackList getListeners(@UserIdInt int userId) { - synchronized (mLock) { - return mListeners.get(userId); - } - } - - @NonNull - private RemoteCallbackList getOrCreateListeners( - @UserIdInt int userId) { - synchronized (mLock) { - RemoteCallbackList listeners = mListeners.get(userId); - if (listeners == null) { - listeners = new RemoteCallbackList<>(); - mListeners.put(userId, listeners); - } - return listeners; - } - } - - private void onRemoveUser(@UserIdInt int userId) { - RemoteCallbackList listeners; - RoleUserState userState; - synchronized (mLock) { - mGrantDefaultRolesThrottledRunnables.remove(userId); - listeners = mListeners.get(userId); - mListeners.remove(userId); - mControllers.remove(userId); - userState = mUserStates.get(userId); - mUserStates.remove(userId); - } - if (listeners != null) { - listeners.kill(); - } - if (userState != null) { - userState.destroy(); - } - } - - @Override - public void onRoleHoldersChanged(@NonNull String roleName, @UserIdInt int userId) { - mListenerHandler.post(() -> notifyRoleHoldersChanged(roleName, userId)); - } - - @WorkerThread - private void notifyRoleHoldersChanged(@NonNull String roleName, @UserIdInt int userId) { - RemoteCallbackList listeners = getListeners(userId); - if (listeners != null) { - notifyRoleHoldersChangedForListeners(listeners, roleName, userId); - } - - RemoteCallbackList allUsersListeners = getListeners( - UserHandleCompat.USER_ALL); - if (allUsersListeners != null) { - notifyRoleHoldersChangedForListeners(allUsersListeners, roleName, userId); - } - } - - @WorkerThread - private void notifyRoleHoldersChangedForListeners( - @NonNull RemoteCallbackList listeners, - @NonNull String roleName, @UserIdInt int userId) { - int broadcastCount = listeners.beginBroadcast(); - try { - for (int i = 0; i < broadcastCount; i++) { - IOnRoleHoldersChangedListener listener = listeners.getBroadcastItem(i); - try { - listener.onRoleHoldersChanged(roleName, userId); - } catch (RemoteException e) { - Log.e(LOG_TAG, "Error calling OnRoleHoldersChangedListener", e); - } - } - } finally { - listeners.finishBroadcast(); - } - } - - private class Stub extends IRoleManager.Stub { - - @Override - public boolean isRoleAvailable(@NonNull String roleName) { - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - - int userId = UserHandleCompat.getUserId(getCallingUid()); - return getOrCreateUserState(userId).isRoleAvailable(roleName); - } - - @Override - public boolean isRoleHeld(@NonNull String roleName, @NonNull String packageName) { - int callingUid = getCallingUid(); - mAppOpsManager.checkPackage(callingUid, packageName); - - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); - - int userId = UserHandleCompat.getUserId(callingUid); - ArraySet roleHolders = getOrCreateUserState(userId).getRoleHolders(roleName); - if (roleHolders == null) { - return false; - } - return roleHolders.contains(packageName); - } - - @NonNull - @Override - public List getRoleHoldersAsUser(@NonNull String roleName, @UserIdInt int userId) { - if (!isUserExistent(userId)) { - Log.e(LOG_TAG, "user " + userId + " does not exist"); - return Collections.emptyList(); - } - enforceCrossUserPermission(userId, false, "getRoleHoldersAsUser"); - getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS, - "getRoleHoldersAsUser"); - - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - - ArraySet roleHolders = getOrCreateUserState(userId).getRoleHolders(roleName); - if (roleHolders == null) { - return Collections.emptyList(); - } - return new ArrayList<>(roleHolders); - } - - @Override - public void addRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName, - @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId, - @NonNull RemoteCallback callback) { - if (!isUserExistent(userId)) { - Log.e(LOG_TAG, "user " + userId + " does not exist"); - return; - } - enforceCrossUserPermission(userId, false, "addRoleHolderAsUser"); - getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS, - "addRoleHolderAsUser"); - - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); - Objects.requireNonNull(callback, "callback cannot be null"); - - getOrCreateController(userId).onAddRoleHolder(roleName, packageName, flags, - callback); - } - - @Override - public void removeRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName, - @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId, - @NonNull RemoteCallback callback) { - if (!isUserExistent(userId)) { - Log.e(LOG_TAG, "user " + userId + " does not exist"); - return; - } - enforceCrossUserPermission(userId, false, "removeRoleHolderAsUser"); - getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS, - "removeRoleHolderAsUser"); - - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); - Objects.requireNonNull(callback, "callback cannot be null"); - - getOrCreateController(userId).onRemoveRoleHolder(roleName, packageName, flags, - callback); - } - - @Override - public void clearRoleHoldersAsUser(@NonNull String roleName, - @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId, - @NonNull RemoteCallback callback) { - if (!isUserExistent(userId)) { - Log.e(LOG_TAG, "user " + userId + " does not exist"); - return; - } - enforceCrossUserPermission(userId, false, "clearRoleHoldersAsUser"); - getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS, - "clearRoleHoldersAsUser"); - - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Objects.requireNonNull(callback, "callback cannot be null"); - - getOrCreateController(userId).onClearRoleHolders(roleName, flags, callback); - } - - @Override - public void addOnRoleHoldersChangedListenerAsUser( - @NonNull IOnRoleHoldersChangedListener listener, @UserIdInt int userId) { - if (userId != UserHandleCompat.USER_ALL && !isUserExistent(userId)) { - Log.e(LOG_TAG, "user " + userId + " does not exist"); - return; - } - enforceCrossUserPermission(userId, true, "addOnRoleHoldersChangedListenerAsUser"); - getContext().enforceCallingOrSelfPermission(Manifest.permission.OBSERVE_ROLE_HOLDERS, - "addOnRoleHoldersChangedListenerAsUser"); - - Objects.requireNonNull(listener, "listener cannot be null"); - - RemoteCallbackList listeners = getOrCreateListeners( - userId); - listeners.register(listener); - } - - @Override - public void removeOnRoleHoldersChangedListenerAsUser( - @NonNull IOnRoleHoldersChangedListener listener, @UserIdInt int userId) { - if (userId != UserHandleCompat.USER_ALL && !isUserExistent(userId)) { - Log.e(LOG_TAG, "user " + userId + " does not exist"); - return; - } - enforceCrossUserPermission(userId, true, "removeOnRoleHoldersChangedListenerAsUser"); - getContext().enforceCallingOrSelfPermission(Manifest.permission.OBSERVE_ROLE_HOLDERS, - "removeOnRoleHoldersChangedListenerAsUser"); - - Objects.requireNonNull(listener, "listener cannot be null"); - - RemoteCallbackList listeners = getListeners(userId); - if (listener == null) { - return; - } - listeners.unregister(listener); - } - - @Override - public void setRoleNamesFromController(@NonNull List roleNames) { - getContext().enforceCallingOrSelfPermission( - RoleManager.PERMISSION_MANAGE_ROLES_FROM_CONTROLLER, - "setRoleNamesFromController"); - - Objects.requireNonNull(roleNames, "roleNames cannot be null"); - - int userId = UserHandleCompat.getUserId(Binder.getCallingUid()); - getOrCreateUserState(userId).setRoleNames(roleNames); - } - - @Override - public boolean addRoleHolderFromController(@NonNull String roleName, - @NonNull String packageName) { - getContext().enforceCallingOrSelfPermission( - RoleManager.PERMISSION_MANAGE_ROLES_FROM_CONTROLLER, - "addRoleHolderFromController"); - - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); - - int userId = UserHandleCompat.getUserId(Binder.getCallingUid()); - return getOrCreateUserState(userId).addRoleHolder(roleName, packageName); - } - - @Override - public boolean removeRoleHolderFromController(@NonNull String roleName, - @NonNull String packageName) { - getContext().enforceCallingOrSelfPermission( - RoleManager.PERMISSION_MANAGE_ROLES_FROM_CONTROLLER, - "removeRoleHolderFromController"); - - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); - - int userId = UserHandleCompat.getUserId(Binder.getCallingUid()); - return getOrCreateUserState(userId).removeRoleHolder(roleName, packageName); - } - - @Override - public List getHeldRolesFromController(@NonNull String packageName) { - getContext().enforceCallingOrSelfPermission( - RoleManager.PERMISSION_MANAGE_ROLES_FROM_CONTROLLER, - "getRolesHeldFromController"); - - Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); - - int userId = UserHandleCompat.getUserId(Binder.getCallingUid()); - return getOrCreateUserState(userId).getHeldRoles(packageName); - } - - private boolean isUserExistent(@UserIdInt int userId) { - // FIXME: This checks whether the user is alive, but we should check for whether the - // user is existent. - return mUserManager.getUserHandles(true).contains(UserHandle.of(userId)); - } - - private void enforceCrossUserPermission(@UserIdInt int userId, boolean allowAll, - @NonNull String message) { - final int callingUid = Binder.getCallingUid(); - final int callingUserId = UserHandleCompat.getUserId(callingUid); - if (userId == callingUserId) { - return; - } - Preconditions.checkArgument(userId >= UserHandleCompat.USER_SYSTEM - || (allowAll && userId == UserHandleCompat.USER_ALL), "Invalid user " + userId); - getContext().enforceCallingOrSelfPermission( - android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); - if (callingUid == Process.SHELL_UID && userId >= UserHandleCompat.USER_SYSTEM) { - if (mUserManager.hasUserRestrictionForUser(UserManager.DISALLOW_DEBUGGING_FEATURES, - UserHandle.of(userId))) { - throw new SecurityException("Shell does not have permission to access user " - + userId); - } - } - } - - @Override - public int handleShellCommand(@NonNull ParcelFileDescriptor in, - @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err, - @NonNull String[] args) { - return new RoleShellCommand(this).exec(this, in.getFileDescriptor(), - out.getFileDescriptor(), err.getFileDescriptor(), args); - } - - @Nullable - @Override - public String getBrowserRoleHolder(@UserIdInt int userId) { - final int callingUid = Binder.getCallingUid(); - if (UserHandleCompat.getUserId(callingUid) != userId) { - getContext().enforceCallingOrSelfPermission( - android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); - } - if (isInstantApp(callingUid)) { - return null; - } - - final long identity = Binder.clearCallingIdentity(); - try { - return CollectionUtils.firstOrNull(getRoleHoldersAsUser(RoleManager.ROLE_BROWSER, - userId)); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - - private boolean isInstantApp(int uid) { - final long identity = Binder.clearCallingIdentity(); - try { - final UserHandle user = UserHandle.getUserHandleForUid(uid); - final Context userContext = getContext().createContextAsUser(user, 0); - final PackageManager userPackageManager = userContext.getPackageManager(); - // Instant apps can not have shared UID, so it's safe to check only the first - // package name here. - final String packageName = ArrayUtils.firstOrNull( - userPackageManager.getPackagesForUid(uid)); - if (packageName == null) { - return false; - } - return userPackageManager.isInstantApp(packageName); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - - @Override - public boolean setBrowserRoleHolder(@Nullable String packageName, @UserIdInt int userId) { - final Context context = getContext(); - context.enforceCallingOrSelfPermission( - android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); - if (UserHandleCompat.getUserId(Binder.getCallingUid()) != userId) { - context.enforceCallingOrSelfPermission( - android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); - } - - if (!isUserExistent(userId)) { - return false; - } - - final AndroidFuture future = new AndroidFuture<>(); - final RemoteCallback callback = new RemoteCallback(result -> { - boolean successful = result != null; - if (successful) { - future.complete(null); - } else { - future.completeExceptionally(new RuntimeException()); - } - }); - final long identity = Binder.clearCallingIdentity(); - try { - if (packageName != null) { - addRoleHolderAsUser(RoleManager.ROLE_BROWSER, packageName, 0, userId, callback); - } else { - clearRoleHoldersAsUser(RoleManager.ROLE_BROWSER, 0, userId, callback); - } - try { - future.get(5, TimeUnit.SECONDS); - } catch (InterruptedException | ExecutionException | TimeoutException e) { - Log.e(LOG_TAG, "Exception while setting default browser: " + packageName, e); - return false; - } - } finally { - Binder.restoreCallingIdentity(identity); - } - - return true; - } - - @Override - public String getSmsRoleHolder(int userId) { - final long identity = Binder.clearCallingIdentity(); - try { - return CollectionUtils.firstOrNull(getRoleHoldersAsUser(RoleManager.ROLE_SMS, - userId)); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - - @Override - protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout, - @Nullable String[] args) { - if (!checkDumpPermission("role", fout)) { - return; - } - - boolean dumpAsProto = args != null && ArrayUtils.contains(args, "--proto"); - DualDumpOutputStream dumpOutputStream; - if (dumpAsProto) { - dumpOutputStream = new DualDumpOutputStream(new ProtoOutputStream( - new FileOutputStream(fd))); - } else { - fout.println("ROLE STATE (dumpsys role):"); - dumpOutputStream = new DualDumpOutputStream(new IndentingPrintWriter(fout, " ")); - } - - synchronized (mLock) { - final int userStatesSize = mUserStates.size(); - for (int i = 0; i < userStatesSize; i++) { - final RoleUserState userState = mUserStates.valueAt(i); - - userState.dump(dumpOutputStream, "user_states", - RoleServiceDumpProto.USER_STATES); - } - } - - dumpOutputStream.flush(); - } - - private boolean checkDumpPermission(@NonNull String serviceName, - @NonNull PrintWriter writer) { - if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP) - != PackageManager.PERMISSION_GRANTED) { - writer.println("Permission Denial: can't dump " + serviceName + " from from pid=" - + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() - + " due to missing " + android.Manifest.permission.DUMP + " permission"); - return false; - } else { - return true; - } - } - } - - private class Local implements RoleManagerLocal { - @NonNull - @Override - public Map> getRolesAndHolders(@UserIdInt int userId) { - // Convert ArrayMap> to Map> for the API. - //noinspection unchecked - return (Map>) (Map) - getOrCreateUserState(userId).getRolesAndHolders(); - } - } -} diff --git a/apex/permission/service/java/com/android/role/RoleShellCommand.java b/apex/permission/service/java/com/android/role/RoleShellCommand.java deleted file mode 100644 index 03b7c76d2df5b..0000000000000 --- a/apex/permission/service/java/com/android/role/RoleShellCommand.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * 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. - */ - -package com.android.role; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.app.role.IRoleManager; -import android.os.RemoteCallback; -import android.os.RemoteException; - -import com.android.modules.utils.BasicShellCommandHandler; -import com.android.permission.compat.UserHandleCompat; - -import java.io.PrintWriter; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.TimeUnit; - -class RoleShellCommand extends BasicShellCommandHandler { - @NonNull - private final IRoleManager mRoleManager; - - RoleShellCommand(@NonNull IRoleManager roleManager) { - mRoleManager = roleManager; - } - - private class CallbackFuture extends CompletableFuture { - @NonNull - public RemoteCallback createCallback() { - return new RemoteCallback(result -> { - boolean successful = result != null; - if (successful) { - complete(null); - } else { - completeExceptionally(new RuntimeException("Failed")); - } - }); - } - - public int waitForResult() { - try { - get(5, TimeUnit.SECONDS); - return 0; - } catch (Exception e) { - getErrPrintWriter().println("Error: see logcat for details.\n" + e); - return -1; - } - } - } - - @Override - public int onCommand(@Nullable String cmd) { - if (cmd == null) { - return handleDefaultCommands(cmd); - } - - PrintWriter pw = getOutPrintWriter(); - try { - switch (cmd) { - case "add-role-holder": - return runAddRoleHolder(); - case "remove-role-holder": - return runRemoveRoleHolder(); - case "clear-role-holders": - return runClearRoleHolders(); - default: - return handleDefaultCommands(cmd); - } - } catch (RemoteException e) { - pw.println("Remote exception: " + e); - } - return -1; - } - - private int getUserIdMaybe() { - int userId = UserHandleCompat.USER_SYSTEM; - String option = getNextOption(); - if (option != null && option.equals("--user")) { - userId = Integer.parseInt(getNextArgRequired()); - } - return userId; - } - - private int getFlagsMaybe() { - String flags = getNextArg(); - if (flags == null) { - return 0; - } - return Integer.parseInt(flags); - } - - private int runAddRoleHolder() throws RemoteException { - int userId = getUserIdMaybe(); - String roleName = getNextArgRequired(); - String packageName = getNextArgRequired(); - int flags = getFlagsMaybe(); - - CallbackFuture future = new CallbackFuture(); - mRoleManager.addRoleHolderAsUser(roleName, packageName, flags, userId, - future.createCallback()); - return future.waitForResult(); - } - - private int runRemoveRoleHolder() throws RemoteException { - int userId = getUserIdMaybe(); - String roleName = getNextArgRequired(); - String packageName = getNextArgRequired(); - int flags = getFlagsMaybe(); - - CallbackFuture future = new CallbackFuture(); - mRoleManager.removeRoleHolderAsUser(roleName, packageName, flags, userId, - future.createCallback()); - return future.waitForResult(); - } - - private int runClearRoleHolders() throws RemoteException { - int userId = getUserIdMaybe(); - String roleName = getNextArgRequired(); - int flags = getFlagsMaybe(); - - CallbackFuture future = new CallbackFuture(); - mRoleManager.clearRoleHoldersAsUser(roleName, flags, userId, future.createCallback()); - return future.waitForResult(); - } - - @Override - public void onHelp() { - PrintWriter pw = getOutPrintWriter(); - pw.println("Role (role) commands:"); - pw.println(" help or -h"); - pw.println(" Print this help text."); - pw.println(); - pw.println(" add-role-holder [--user USER_ID] ROLE PACKAGE [FLAGS]"); - pw.println(" remove-role-holder [--user USER_ID] ROLE PACKAGE [FLAGS]"); - pw.println(" clear-role-holders [--user USER_ID] ROLE [FLAGS]"); - pw.println(); - } -} diff --git a/apex/permission/service/java/com/android/role/RoleUserState.java b/apex/permission/service/java/com/android/role/RoleUserState.java deleted file mode 100644 index 78d8d15bbe604..0000000000000 --- a/apex/permission/service/java/com/android/role/RoleUserState.java +++ /dev/null @@ -1,476 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * 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. - */ - -package com.android.role; - -import android.annotation.CheckResult; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.UserIdInt; -import android.annotation.WorkerThread; -import android.os.Handler; -import android.os.UserHandle; -import android.util.ArrayMap; -import android.util.ArraySet; -import android.util.Log; - -import com.android.internal.annotations.GuardedBy; -import com.android.internal.util.dump.DualDumpOutputStream; -import com.android.permission.util.BackgroundThread; -import com.android.permission.util.CollectionUtils; -import com.android.role.persistence.RolesPersistence; -import com.android.role.persistence.RolesState; -import com.android.server.role.RoleServicePlatformHelper; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; - -/** - * Stores the state of roles for a user. - */ -class RoleUserState { - private static final String LOG_TAG = RoleUserState.class.getSimpleName(); - - public static final int VERSION_UNDEFINED = -1; - - private static final long WRITE_DELAY_MILLIS = 200; - - private final RolesPersistence mPersistence = RolesPersistence.createInstance(); - - @UserIdInt - private final int mUserId; - - @NonNull - private final RoleServicePlatformHelper mPlatformHelper; - - @NonNull - private final Callback mCallback; - - @NonNull - private final Object mLock = new Object(); - - @GuardedBy("mLock") - private int mVersion = VERSION_UNDEFINED; - - @GuardedBy("mLock") - @Nullable - private String mPackagesHash; - - /** - * Maps role names to its holders' package names. The values should never be null. - */ - @GuardedBy("mLock") - @NonNull - private ArrayMap> mRoles = new ArrayMap<>(); - - @GuardedBy("mLock") - private boolean mWriteScheduled; - - @GuardedBy("mLock") - private boolean mDestroyed; - - @NonNull - private final Handler mWriteHandler = new Handler(BackgroundThread.get().getLooper()); - - /** - * Create a new user state, and read its state from disk if previously persisted. - * - * @param userId the user id for this user state - * @param platformHelper the platform helper - * @param callback the callback for this user state - */ - public RoleUserState(@UserIdInt int userId, @NonNull RoleServicePlatformHelper platformHelper, - @NonNull Callback callback) { - mUserId = userId; - mPlatformHelper = platformHelper; - mCallback = callback; - - readFile(); - } - - /** - * Get the version of this user state. - */ - public int getVersion() { - synchronized (mLock) { - return mVersion; - } - } - - /** - * Set the version of this user state. - * - * @param version the version to set - */ - public void setVersion(int version) { - synchronized (mLock) { - if (mVersion == version) { - return; - } - mVersion = version; - scheduleWriteFileLocked(); - } - } - - /** - * Get the hash representing the state of packages during the last time initial grants was run. - * - * @return the hash representing the state of packages - */ - @Nullable - public String getPackagesHash() { - synchronized (mLock) { - return mPackagesHash; - } - } - - /** - * Set the hash representing the state of packages during the last time initial grants was run. - * - * @param packagesHash the hash representing the state of packages - */ - public void setPackagesHash(@Nullable String packagesHash) { - synchronized (mLock) { - if (Objects.equals(mPackagesHash, packagesHash)) { - return; - } - mPackagesHash = packagesHash; - scheduleWriteFileLocked(); - } - } - - /** - * Get whether the role is available. - * - * @param roleName the name of the role to get the holders for - * - * @return whether the role is available - */ - public boolean isRoleAvailable(@NonNull String roleName) { - synchronized (mLock) { - return mRoles.containsKey(roleName); - } - } - - /** - * Get the holders of a role. - * - * @param roleName the name of the role to query for - * - * @return the set of role holders, or {@code null} if and only if the role is not found - */ - @Nullable - public ArraySet getRoleHolders(@NonNull String roleName) { - synchronized (mLock) { - ArraySet packageNames = mRoles.get(roleName); - if (packageNames == null) { - return null; - } - return new ArraySet<>(packageNames); - } - } - - /** - * Adds the given role, effectively marking it as {@link #isRoleAvailable available} - * - * @param roleName the name of the role - * - * @return whether any changes were made - */ - public boolean addRoleName(@NonNull String roleName) { - synchronized (mLock) { - if (!mRoles.containsKey(roleName)) { - mRoles.put(roleName, new ArraySet<>()); - Log.i(LOG_TAG, "Added new role: " + roleName); - scheduleWriteFileLocked(); - return true; - } else { - return false; - } - } - } - - /** - * Set the names of all available roles. - * - * @param roleNames the names of all the available roles - */ - public void setRoleNames(@NonNull List roleNames) { - synchronized (mLock) { - boolean changed = false; - - for (int i = mRoles.size() - 1; i >= 0; i--) { - String roleName = mRoles.keyAt(i); - - if (!roleNames.contains(roleName)) { - ArraySet packageNames = mRoles.valueAt(i); - if (!packageNames.isEmpty()) { - Log.e(LOG_TAG, "Holders of a removed role should have been cleaned up," - + " role: " + roleName + ", holders: " + packageNames); - } - mRoles.removeAt(i); - changed = true; - } - } - - int roleNamesSize = roleNames.size(); - for (int i = 0; i < roleNamesSize; i++) { - changed |= addRoleName(roleNames.get(i)); - } - - if (changed) { - scheduleWriteFileLocked(); - } - } - } - - /** - * Add a holder to a role. - * - * @param roleName the name of the role to add the holder to - * @param packageName the package name of the new holder - * - * @return {@code false} if and only if the role is not found - */ - @CheckResult - public boolean addRoleHolder(@NonNull String roleName, @NonNull String packageName) { - boolean changed; - - synchronized (mLock) { - ArraySet roleHolders = mRoles.get(roleName); - if (roleHolders == null) { - Log.e(LOG_TAG, "Cannot add role holder for unknown role, role: " + roleName - + ", package: " + packageName); - return false; - } - changed = roleHolders.add(packageName); - if (changed) { - scheduleWriteFileLocked(); - } - } - - if (changed) { - mCallback.onRoleHoldersChanged(roleName, mUserId); - } - return true; - } - - /** - * Remove a holder from a role. - * - * @param roleName the name of the role to remove the holder from - * @param packageName the package name of the holder to remove - * - * @return {@code false} if and only if the role is not found - */ - @CheckResult - public boolean removeRoleHolder(@NonNull String roleName, @NonNull String packageName) { - boolean changed; - - synchronized (mLock) { - ArraySet roleHolders = mRoles.get(roleName); - if (roleHolders == null) { - Log.e(LOG_TAG, "Cannot remove role holder for unknown role, role: " + roleName - + ", package: " + packageName); - return false; - } - - changed = roleHolders.remove(packageName); - if (changed) { - scheduleWriteFileLocked(); - } - } - - if (changed) { - mCallback.onRoleHoldersChanged(roleName, mUserId); - } - return true; - } - - /** - * @see android.app.role.RoleManager#getHeldRolesFromController - */ - @NonNull - public List getHeldRoles(@NonNull String packageName) { - synchronized (mLock) { - List roleNames = new ArrayList<>(); - int size = mRoles.size(); - for (int i = 0; i < size; i++) { - if (mRoles.valueAt(i).contains(packageName)) { - roleNames.add(mRoles.keyAt(i)); - } - } - return roleNames; - } - } - - /** - * Schedule writing the state to file. - */ - @GuardedBy("mLock") - private void scheduleWriteFileLocked() { - if (mDestroyed) { - return; - } - - if (!mWriteScheduled) { - mWriteHandler.postDelayed(this::writeFile, WRITE_DELAY_MILLIS); - mWriteScheduled = true; - } - } - - @WorkerThread - private void writeFile() { - RolesState roles; - synchronized (mLock) { - if (mDestroyed) { - return; - } - - mWriteScheduled = false; - - roles = new RolesState(mVersion, mPackagesHash, - (Map>) (Map) snapshotRolesLocked()); - } - - mPersistence.writeForUser(roles, UserHandle.of(mUserId)); - } - - private void readFile() { - synchronized (mLock) { - RolesState roleState = mPersistence.readForUser(UserHandle.of(mUserId)); - - Map> roles; - if (roleState != null) { - mVersion = roleState.getVersion(); - mPackagesHash = roleState.getPackagesHash(); - roles = roleState.getRoles(); - } else { - roles = mPlatformHelper.getLegacyRoleState(mUserId); - } - mRoles.clear(); - for (Map.Entry> entry : roles.entrySet()) { - String roleName = entry.getKey(); - ArraySet roleHolders = new ArraySet<>(entry.getValue()); - mRoles.put(roleName, roleHolders); - } - - if (roleState == null) { - scheduleWriteFileLocked(); - } - } - } - - /** - * Dump this user state. - * - * @param dumpOutputStream the output stream to dump to - */ - public void dump(@NonNull DualDumpOutputStream dumpOutputStream, @NonNull String fieldName, - long fieldId) { - int version; - String packagesHash; - ArrayMap> roles; - synchronized (mLock) { - version = mVersion; - packagesHash = mPackagesHash; - roles = snapshotRolesLocked(); - } - - long fieldToken = dumpOutputStream.start(fieldName, fieldId); - dumpOutputStream.write("user_id", RoleUserStateProto.USER_ID, mUserId); - dumpOutputStream.write("version", RoleUserStateProto.VERSION, version); - dumpOutputStream.write("packages_hash", RoleUserStateProto.PACKAGES_HASH, packagesHash); - - int rolesSize = roles.size(); - for (int rolesIndex = 0; rolesIndex < rolesSize; rolesIndex++) { - String roleName = roles.keyAt(rolesIndex); - ArraySet roleHolders = roles.valueAt(rolesIndex); - - long rolesToken = dumpOutputStream.start("roles", RoleUserStateProto.ROLES); - dumpOutputStream.write("name", RoleProto.NAME, roleName); - - int roleHoldersSize = roleHolders.size(); - for (int roleHoldersIndex = 0; roleHoldersIndex < roleHoldersSize; roleHoldersIndex++) { - String roleHolder = roleHolders.valueAt(roleHoldersIndex); - - dumpOutputStream.write("holders", RoleProto.HOLDERS, roleHolder); - } - - dumpOutputStream.end(rolesToken); - } - - dumpOutputStream.end(fieldToken); - } - - /** - * Get the roles and their holders. - * - * @return A copy of the roles and their holders - */ - @NonNull - public ArrayMap> getRolesAndHolders() { - synchronized (mLock) { - return snapshotRolesLocked(); - } - } - - @GuardedBy("mLock") - @NonNull - private ArrayMap> snapshotRolesLocked() { - ArrayMap> roles = new ArrayMap<>(); - for (int i = 0, size = CollectionUtils.size(mRoles); i < size; ++i) { - String roleName = mRoles.keyAt(i); - ArraySet roleHolders = mRoles.valueAt(i); - - roleHolders = new ArraySet<>(roleHolders); - roles.put(roleName, roleHolders); - } - return roles; - } - - /** - * Destroy this user state and delete the corresponding file. Any pending writes to the file - * will be cancelled, and any future interaction with this state will throw an exception. - */ - public void destroy() { - synchronized (mLock) { - if (mDestroyed) { - throw new IllegalStateException("This RoleUserState has already been destroyed"); - } - mWriteHandler.removeCallbacksAndMessages(null); - mPersistence.deleteForUser(UserHandle.of(mUserId)); - mDestroyed = true; - } - } - - /** - * Callback for a user state. - */ - public interface Callback { - - /** - * Called when the holders of roles are changed. - * - * @param roleName the name of the role whose holders are changed - * @param userId the user id for this role holder change - */ - void onRoleHoldersChanged(@NonNull String roleName, @UserIdInt int userId); - } -} diff --git a/apex/permission/service/java/com/android/role/TEST_MAPPING b/apex/permission/service/java/com/android/role/TEST_MAPPING deleted file mode 100644 index 0d7bc1476bd1c..0000000000000 --- a/apex/permission/service/java/com/android/role/TEST_MAPPING +++ /dev/null @@ -1,20 +0,0 @@ -{ - "presubmit": [ - { - "name": "CtsStatsdHostTestCases", - "options": [ - { - "include-filter": "android.cts.statsd.atom.UidAtomTests#testRoleHolder" - } - ] - }, - { - "name": "CtsRoleTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] - } - ] -} diff --git a/apex/permission/service/java/com/android/role/package-info.java b/apex/permission/service/java/com/android/role/package-info.java deleted file mode 100644 index 8b5b2516105fe..0000000000000 --- a/apex/permission/service/java/com/android/role/package-info.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * 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. - */ - -/** - * @hide - * TODO(b/146466118) remove this javadoc tag - */ -@android.annotation.Hide -package com.android.role; diff --git a/apex/permission/service/java/com/android/role/persistence/RolesPersistence.java b/apex/permission/service/java/com/android/role/persistence/RolesPersistence.java deleted file mode 100644 index 2e5a28aa1d6ae..0000000000000 --- a/apex/permission/service/java/com/android/role/persistence/RolesPersistence.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * 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. - */ - -package com.android.role.persistence; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.annotation.SystemApi.Client; -import android.os.UserHandle; - -/** - * Persistence for roles. - * - * TODO(b/147914847): Remove @hide when it becomes the default. - * @hide - */ -@SystemApi(client = Client.SYSTEM_SERVER) -public interface RolesPersistence { - - /** - * Read the roles from persistence. - * - * This will perform I/O operations synchronously. - * - * @param user the user to read for - * @return the roles read - */ - @Nullable - RolesState readForUser(@NonNull UserHandle user); - - /** - * Write the roles to persistence. - * - * This will perform I/O operations synchronously. - * - * @param roles the roles to write - * @param user the user to write for - */ - void writeForUser(@NonNull RolesState roles, @NonNull UserHandle user); - - /** - * Delete the roles from persistence. - * - * This will perform I/O operations synchronously. - * - * @param user the user to delete for - */ - void deleteForUser(@NonNull UserHandle user); - - /** - * Create a new instance of {@link RolesPersistence} implementation. - * - * @return the new instance. - */ - @NonNull - static RolesPersistence createInstance() { - return new RolesPersistenceImpl(); - } -} diff --git a/apex/permission/service/java/com/android/role/persistence/RolesPersistenceImpl.java b/apex/permission/service/java/com/android/role/persistence/RolesPersistenceImpl.java deleted file mode 100644 index f66257f13ef62..0000000000000 --- a/apex/permission/service/java/com/android/role/persistence/RolesPersistenceImpl.java +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * 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. - */ - -package com.android.role.persistence; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.content.ApexEnvironment; -import android.os.UserHandle; -import android.util.ArrayMap; -import android.util.ArraySet; -import android.util.AtomicFile; -import android.util.Log; -import android.util.Xml; - -import com.android.permission.persistence.IoUtils; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlSerializer; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.Map; -import java.util.Set; - -/** - * Persistence implementation for roles. - * - * TODO(b/147914847): Remove @hide when it becomes the default. - * @hide - */ -public class RolesPersistenceImpl implements RolesPersistence { - - private static final String LOG_TAG = RolesPersistenceImpl.class.getSimpleName(); - - private static final String APEX_MODULE_NAME = "com.android.permission"; - - private static final String ROLES_FILE_NAME = "roles.xml"; - - private static final String TAG_ROLES = "roles"; - private static final String TAG_ROLE = "role"; - private static final String TAG_HOLDER = "holder"; - - private static final String ATTRIBUTE_VERSION = "version"; - private static final String ATTRIBUTE_NAME = "name"; - private static final String ATTRIBUTE_PACKAGES_HASH = "packagesHash"; - - @Nullable - @Override - public RolesState readForUser(@NonNull UserHandle user) { - File file = getFile(user); - try (FileInputStream inputStream = new AtomicFile(file).openRead()) { - XmlPullParser parser = Xml.newPullParser(); - parser.setInput(inputStream, null); - return parseXml(parser); - } catch (FileNotFoundException e) { - Log.i(LOG_TAG, "roles.xml not found"); - return null; - } catch (XmlPullParserException | IOException e) { - throw new IllegalStateException("Failed to read roles.xml: " + file , e); - } - } - - @NonNull - private static RolesState parseXml(@NonNull XmlPullParser parser) - throws IOException, XmlPullParserException { - int type; - int depth; - int innerDepth = parser.getDepth() + 1; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && ((depth = parser.getDepth()) >= innerDepth || type != XmlPullParser.END_TAG)) { - if (depth > innerDepth || type != XmlPullParser.START_TAG) { - continue; - } - - if (parser.getName().equals(TAG_ROLES)) { - return parseRoles(parser); - } - } - throw new IllegalStateException("Missing <" + TAG_ROLES + "> in roles.xml"); - } - - @NonNull - private static RolesState parseRoles(@NonNull XmlPullParser parser) - throws IOException, XmlPullParserException { - int version = Integer.parseInt(parser.getAttributeValue(null, ATTRIBUTE_VERSION)); - String packagesHash = parser.getAttributeValue(null, ATTRIBUTE_PACKAGES_HASH); - - Map> roles = new ArrayMap<>(); - int type; - int depth; - int innerDepth = parser.getDepth() + 1; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && ((depth = parser.getDepth()) >= innerDepth || type != XmlPullParser.END_TAG)) { - if (depth > innerDepth || type != XmlPullParser.START_TAG) { - continue; - } - - if (parser.getName().equals(TAG_ROLE)) { - String roleName = parser.getAttributeValue(null, ATTRIBUTE_NAME); - Set roleHolders = parseRoleHolders(parser); - roles.put(roleName, roleHolders); - } - } - - return new RolesState(version, packagesHash, roles); - } - - @NonNull - private static Set parseRoleHolders(@NonNull XmlPullParser parser) - throws IOException, XmlPullParserException { - Set roleHolders = new ArraySet<>(); - int type; - int depth; - int innerDepth = parser.getDepth() + 1; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && ((depth = parser.getDepth()) >= innerDepth || type != XmlPullParser.END_TAG)) { - if (depth > innerDepth || type != XmlPullParser.START_TAG) { - continue; - } - - if (parser.getName().equals(TAG_HOLDER)) { - String roleHolder = parser.getAttributeValue(null, ATTRIBUTE_NAME); - roleHolders.add(roleHolder); - } - } - return roleHolders; - } - - @Override - public void writeForUser(@NonNull RolesState roles, @NonNull UserHandle user) { - File file = getFile(user); - AtomicFile atomicFile = new AtomicFile(file); - FileOutputStream outputStream = null; - try { - outputStream = atomicFile.startWrite(); - - XmlSerializer serializer = Xml.newSerializer(); - serializer.setOutput(outputStream, StandardCharsets.UTF_8.name()); - serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); - serializer.startDocument(null, true); - - serializeRoles(serializer, roles); - - serializer.endDocument(); - atomicFile.finishWrite(outputStream); - } catch (Exception e) { - Log.wtf(LOG_TAG, "Failed to write roles.xml, restoring backup: " + file, - e); - atomicFile.failWrite(outputStream); - } finally { - IoUtils.closeQuietly(outputStream); - } - } - - private static void serializeRoles(@NonNull XmlSerializer serializer, - @NonNull RolesState roles) throws IOException { - serializer.startTag(null, TAG_ROLES); - - int version = roles.getVersion(); - serializer.attribute(null, ATTRIBUTE_VERSION, Integer.toString(version)); - String packagesHash = roles.getPackagesHash(); - if (packagesHash != null) { - serializer.attribute(null, ATTRIBUTE_PACKAGES_HASH, packagesHash); - } - - for (Map.Entry> entry : roles.getRoles().entrySet()) { - String roleName = entry.getKey(); - Set roleHolders = entry.getValue(); - - serializer.startTag(null, TAG_ROLE); - serializer.attribute(null, ATTRIBUTE_NAME, roleName); - serializeRoleHolders(serializer, roleHolders); - serializer.endTag(null, TAG_ROLE); - } - - serializer.endTag(null, TAG_ROLES); - } - - private static void serializeRoleHolders(@NonNull XmlSerializer serializer, - @NonNull Set roleHolders) throws IOException { - for (String roleHolder : roleHolders) { - serializer.startTag(null, TAG_HOLDER); - serializer.attribute(null, ATTRIBUTE_NAME, roleHolder); - serializer.endTag(null, TAG_HOLDER); - } - } - - @Override - public void deleteForUser(@NonNull UserHandle user) { - getFile(user).delete(); - } - - @NonNull - private static File getFile(@NonNull UserHandle user) { - ApexEnvironment apexEnvironment = ApexEnvironment.getApexEnvironment(APEX_MODULE_NAME); - File dataDirectory = apexEnvironment.getDeviceProtectedDataDirForUser(user); - return new File(dataDirectory, ROLES_FILE_NAME); - } -} diff --git a/apex/permission/service/java/com/android/role/persistence/RolesState.java b/apex/permission/service/java/com/android/role/persistence/RolesState.java deleted file mode 100644 index f61efa0e840dc..0000000000000 --- a/apex/permission/service/java/com/android/role/persistence/RolesState.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * 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. - */ - -package com.android.role.persistence; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.annotation.SystemApi.Client; - -import java.util.Map; -import java.util.Objects; -import java.util.Set; - -/** - * State of all roles. - * - * TODO(b/147914847): Remove @hide when it becomes the default. - * @hide - */ -@SystemApi(client = Client.SYSTEM_SERVER) -public final class RolesState { - - /** - * The version of the roles. - */ - private final int mVersion; - - /** - * The hash of all packages in the system. - */ - @Nullable - private final String mPackagesHash; - - /** - * The roles. - */ - @NonNull - private final Map> mRoles; - - /** - * Create a new instance of this class. - * - * @param version the version of the roles - * @param packagesHash the hash of all packages in the system - * @param roles the roles - */ - public RolesState(int version, @Nullable String packagesHash, - @NonNull Map> roles) { - mVersion = version; - mPackagesHash = packagesHash; - mRoles = roles; - } - - /** - * Get the version of the roles. - * - * @return the version of the roles - */ - public int getVersion() { - return mVersion; - } - - /** - * Get the hash of all packages in the system. - * - * @return the hash of all packages in the system - */ - @Nullable - public String getPackagesHash() { - return mPackagesHash; - } - - /** - * Get the roles. - * - * @return the roles - */ - @NonNull - public Map> getRoles() { - return mRoles; - } - - @Override - public boolean equals(Object object) { - if (this == object) { - return true; - } - if (object == null || getClass() != object.getClass()) { - return false; - } - RolesState that = (RolesState) object; - return mVersion == that.mVersion - && Objects.equals(mPackagesHash, that.mPackagesHash) - && Objects.equals(mRoles, that.mRoles); - } - - @Override - public int hashCode() { - return Objects.hash(mVersion, mPackagesHash, mRoles); - } -} diff --git a/apex/permission/service/proto/com/android/role/roleservice.proto b/apex/permission/service/proto/com/android/role/roleservice.proto deleted file mode 100644 index 79c42299207c1..0000000000000 --- a/apex/permission/service/proto/com/android/role/roleservice.proto +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * 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. - */ - -syntax = "proto2"; - -package com.android.role; - -option java_multiple_files = true; - -import "frameworks/base/core/proto/android/privacy.proto"; - -message RoleServiceDumpProto { - option (.android.msg_privacy).dest = DEST_AUTOMATIC; - - // List of per-user states for all users. - repeated RoleUserStateProto user_states = 1; -} - -message RoleUserStateProto { - option (.android.msg_privacy).dest = DEST_AUTOMATIC; - - // The user id of this state. - optional int32 user_id = 1; - - // The version of this state. - optional int32 version = 2; - - // The hash of packages for this state. - optional string packages_hash = 3; - - // The set of roles in this state. - repeated RoleProto roles = 4; -} - -message RoleProto { - option (.android.msg_privacy).dest = DEST_AUTOMATIC; - - // The name of this role, e.g. "android.app.role.DIALER". - optional string name = 1; - - // The package names of the holders of this role. - repeated string holders = 2; -} diff --git a/apex/permission/testing/Android.bp b/apex/permission/testing/Android.bp deleted file mode 100644 index 63bf0a08e9560..0000000000000 --- a/apex/permission/testing/Android.bp +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (C) 2019 The Android Open Source Project -// -// 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. - -apex_test { - name: "test_com.android.permission", - visibility: [ - "//system/apex/tests", - ], - defaults: ["com.android.permission-defaults"], - manifest: "test_manifest.json", - file_contexts: ":com.android.permission-file_contexts", - // Test APEX, should never be installed - installable: false, -} diff --git a/apex/permission/testing/test_manifest.json b/apex/permission/testing/test_manifest.json deleted file mode 100644 index bc19a9ea0172a..0000000000000 --- a/apex/permission/testing/test_manifest.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "com.android.permission", - "version": 2147483647 -} diff --git a/apex/permission/tests/Android.bp b/apex/permission/tests/Android.bp deleted file mode 100644 index 271e328c11394..0000000000000 --- a/apex/permission/tests/Android.bp +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2020 The Android Open Source Project -// -// 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. - -android_test { - name: "PermissionApexTests", - sdk_version: "test_current", - srcs: [ - "java/**/*.kt", - ], - static_libs: [ - "service-permission.impl", - "androidx.test.rules", - "androidx.test.ext.junit", - "androidx.test.ext.truth", - "mockito-target-extended-minus-junit4", - ], - jni_libs: [ - "libdexmakerjvmtiagent", - "libstaticjvmtiagent", - ], - compile_multilib: "both", - test_suites: [ - "general-tests", - "mts", - ], -} diff --git a/apex/permission/tests/AndroidManifest.xml b/apex/permission/tests/AndroidManifest.xml deleted file mode 100644 index 57ee6417aeb37..0000000000000 --- a/apex/permission/tests/AndroidManifest.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - diff --git a/apex/permission/tests/java/com/android/permission/persistence/RuntimePermissionsPersistenceTest.kt b/apex/permission/tests/java/com/android/permission/persistence/RuntimePermissionsPersistenceTest.kt deleted file mode 100644 index 2987da087e51d..0000000000000 --- a/apex/permission/tests/java/com/android/permission/persistence/RuntimePermissionsPersistenceTest.kt +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * 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. - */ - -package com.android.permission.persistence - -import android.content.ApexEnvironment -import android.content.Context -import android.os.Process -import android.os.UserHandle -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.platform.app.InstrumentationRegistry -import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession -import com.google.common.truth.Truth.assertThat -import org.junit.After -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.ArgumentMatchers.any -import org.mockito.ArgumentMatchers.eq -import org.mockito.Mock -import org.mockito.Mockito.`when` -import org.mockito.MockitoAnnotations.initMocks -import org.mockito.MockitoSession -import org.mockito.quality.Strictness -import java.io.File - -@RunWith(AndroidJUnit4::class) -class RuntimePermissionsPersistenceTest { - private val context = InstrumentationRegistry.getInstrumentation().context - - private lateinit var mockDataDirectory: File - - private lateinit var mockitoSession: MockitoSession - @Mock - lateinit var apexEnvironment: ApexEnvironment - - private val persistence = RuntimePermissionsPersistence.createInstance() - private val permissionState = RuntimePermissionsState.PermissionState("permission", true, 3) - private val state = RuntimePermissionsState( - 1, "fingerprint", mapOf("package" to listOf(permissionState)), - mapOf("sharedUser" to listOf(permissionState)) - ) - private val user = Process.myUserHandle() - - @Before - fun createMockDataDirectory() { - mockDataDirectory = context.getDir("mock_data", Context.MODE_PRIVATE) - mockDataDirectory.listFiles()!!.forEach { assertThat(it.deleteRecursively()).isTrue() } - } - - @Before - fun mockApexEnvironment() { - initMocks(this) - mockitoSession = mockitoSession() - .mockStatic(ApexEnvironment::class.java) - .strictness(Strictness.LENIENT) - .startMocking() - `when`(ApexEnvironment.getApexEnvironment(eq(APEX_MODULE_NAME))).thenReturn(apexEnvironment) - `when`(apexEnvironment.getDeviceProtectedDataDirForUser(any(UserHandle::class.java))).then { - File(mockDataDirectory, it.arguments[0].toString()).also { it.mkdirs() } - } - } - - @After - fun finishMockingApexEnvironment() { - mockitoSession.finishMocking() - } - - @Test - fun testReadWrite() { - persistence.writeForUser(state, user) - val persistedState = persistence.readForUser(user) - - assertThat(persistedState).isEqualTo(state) - assertThat(persistedState!!.version).isEqualTo(state.version) - assertThat(persistedState.fingerprint).isEqualTo(state.fingerprint) - assertThat(persistedState.packagePermissions).isEqualTo(state.packagePermissions) - val persistedPermissionState = persistedState.packagePermissions.values.first().first() - assertThat(persistedPermissionState.name).isEqualTo(permissionState.name) - assertThat(persistedPermissionState.isGranted).isEqualTo(permissionState.isGranted) - assertThat(persistedPermissionState.flags).isEqualTo(permissionState.flags) - assertThat(persistedState.sharedUserPermissions).isEqualTo(state.sharedUserPermissions) - } - - @Test - fun testDelete() { - persistence.writeForUser(state, user) - persistence.deleteForUser(user) - val persistedState = persistence.readForUser(user) - - assertThat(persistedState).isNull() - } - - companion object { - private const val APEX_MODULE_NAME = "com.android.permission" - } -} diff --git a/apex/permission/tests/java/com/android/role/persistence/RolesPersistenceTest.kt b/apex/permission/tests/java/com/android/role/persistence/RolesPersistenceTest.kt deleted file mode 100644 index f9d9d5afb25db..0000000000000 --- a/apex/permission/tests/java/com/android/role/persistence/RolesPersistenceTest.kt +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * 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. - */ - -package com.android.role.persistence - -import android.content.ApexEnvironment -import android.content.Context -import android.os.Process -import android.os.UserHandle -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.platform.app.InstrumentationRegistry -import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession -import com.google.common.truth.Truth.assertThat -import org.junit.After -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.ArgumentMatchers.any -import org.mockito.ArgumentMatchers.eq -import org.mockito.Mock -import org.mockito.Mockito.`when` -import org.mockito.MockitoAnnotations.initMocks -import org.mockito.MockitoSession -import org.mockito.quality.Strictness -import java.io.File - -@RunWith(AndroidJUnit4::class) -class RolesPersistenceTest { - private val context = InstrumentationRegistry.getInstrumentation().context - - private lateinit var mockDataDirectory: File - - private lateinit var mockitoSession: MockitoSession - @Mock - lateinit var apexEnvironment: ApexEnvironment - - private val persistence = RolesPersistence.createInstance() - private val state = RolesState(1, "packagesHash", mapOf("role" to setOf("holder1", "holder2"))) - private val user = Process.myUserHandle() - - @Before - fun createMockDataDirectory() { - mockDataDirectory = context.getDir("mock_data", Context.MODE_PRIVATE) - mockDataDirectory.listFiles()!!.forEach { assertThat(it.deleteRecursively()).isTrue() } - } - - @Before - fun mockApexEnvironment() { - initMocks(this) - mockitoSession = mockitoSession() - .mockStatic(ApexEnvironment::class.java) - .strictness(Strictness.LENIENT) - .startMocking() - `when`(ApexEnvironment.getApexEnvironment(eq(APEX_MODULE_NAME))).thenReturn(apexEnvironment) - `when`(apexEnvironment.getDeviceProtectedDataDirForUser(any(UserHandle::class.java))).then { - File(mockDataDirectory, it.arguments[0].toString()).also { it.mkdirs() } - } - } - - @After - fun finishMockingApexEnvironment() { - mockitoSession.finishMocking() - } - - @Test - fun testReadWrite() { - persistence.writeForUser(state, user) - val persistedState = persistence.readForUser(user) - - assertThat(persistedState).isEqualTo(state) - assertThat(persistedState!!.version).isEqualTo(state.version) - assertThat(persistedState.packagesHash).isEqualTo(state.packagesHash) - assertThat(persistedState.roles).isEqualTo(state.roles) - } - - @Test - fun testDelete() { - persistence.writeForUser(state, user) - persistence.deleteForUser(user) - val persistedState = persistence.readForUser(user) - - assertThat(persistedState).isNull() - } - - companion object { - private const val APEX_MODULE_NAME = "com.android.permission" - } -} diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto index 48094198c2e95..2b665c0fe9fc8 100644 --- a/core/proto/android/os/incident.proto +++ b/core/proto/android/os/incident.proto @@ -41,7 +41,6 @@ import "frameworks/base/core/proto/android/server/jobscheduler.proto"; import "frameworks/base/core/proto/android/server/location/context_hub.proto"; import "frameworks/base/core/proto/android/server/powermanagerservice.proto"; import "frameworks/base/core/proto/android/server/powerstatsservice.proto"; -import "frameworks/base/apex/permission/service/proto/com/android/role/roleservice.proto"; import "frameworks/base/core/proto/android/server/windowmanagerservice.proto"; import "frameworks/base/core/proto/android/service/appwidget.proto"; import "frameworks/base/core/proto/android/service/battery.proto"; @@ -63,6 +62,7 @@ import "frameworks/base/core/proto/android/privacy.proto"; import "frameworks/base/core/proto/android/section.proto"; import "frameworks/base/proto/src/ipconnectivity.proto"; import "frameworks/proto_logging/stats/enums/service/usb.proto"; +import "packages/modules/Permission/service/proto/com/android/role/roleservice.proto"; package android.os;