diff options
67 files changed, 1 insertions, 5426 deletions
diff --git a/apex/permission/Android.bp b/apex/permission/Android.bp deleted file mode 100644 index be51143e4730..000000000000 --- 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 957e10a582a0..000000000000 --- 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 6e67ce92a27e..000000000000 --- 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 6350d54d695e..000000000000 --- 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 Binary files differdeleted file mode 100644 index 9eaf85259637..000000000000 --- a/apex/permission/com.android.permission.avbpubkey +++ /dev/null diff --git a/apex/permission/com.android.permission.pem b/apex/permission/com.android.permission.pem deleted file mode 100644 index 3d584be5440d..000000000000 --- a/apex/permission/com.android.permission.pem +++ /dev/null @@ -1,51 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIJKgIBAAKCAgEA6snt4eqoz85xiL9Sf6w1S1b9FgSHK05zYTh2JYPvQKQ3yeZp -E6avJ6FN6XcbmkDzSd658BvUGDBSPhOlzuUO4BsoKBuLMxP6TxIQXFKidzDqY0vQ -4qkS++bdIhUjwBP3OSZ3Czu0BiihK8GC75Abr//EyCyObGIGGfHEGANiOgrpP4X5 -+OmLzQLCjk4iE1kg+U6cRSRI/XLaoWC0TvIIuzxznrQ6r5GmzgTOwyBWyIB+bj73 -bmsweHTU+w9Y7kGOx4hO3XCLIhoBWEw0EbuW9nZmQ4sZls5Jo/CbyJlCclF11yVo -SCf2LG/T+9pah5NOmDQ1kPbU+0iKZIV4YFHGTIhyGDE/aPOuUT05ziCGDifgHr0u -SG1x/RLqsVh/POvNxnvP9cQFMQ08BvbEJaTTgB785iwKsvdqCfmng/SAyxSetmzP -StXVB3fh1OoZ8vunRbQYxnmUxycVqaA96zmBx2wLvbvzKo7pZFDE6nbhnT5+MRAM -z/VIK89W26uB4gj8sBFslqZjT0jPqsAZuvDm7swOtMwIcEolyGJuFLqlhN7UwMz2 -9y8+IpYixR+HvD1TZI9NtmuCmv3kPrWgoMZg6yvaBayTIr8RdYzi6FO/C1lLiraz -48dH3sXWRa8cgw6VcSUwYrEBIc3sotdsupO1iOjcFybIwaee0YTZJfjvbqkCAwEA -AQKCAgEArRnfdpaJi1xLPGTCMDsIt9kUku0XswgN7PmxsYsKFAB+2S40/jYAIRm9 -1YjpItsMA8RgFfSOdJ77o6TctCMQyo17F8bm4+uwuic5RLfv7Cx2QmsdQF8jDfFx -y7UGPJD7znjbf76uxXOjEB2FqZX3s9TAgkzHXIUQtoQW7RVhkCWHPjxKxgd5+NY2 -FrDoUpd9xhD9CcTsw1+wbRZdGW88nL6/B50dP2AFORM2VYo8MWr6y9FEn3YLsGOC -uu7fxBk1aUrHyl81VRkTMMROB1zkuiUk1FtzrEm+5U15rXXBFYOVe9+qeLhtuOlh -wueDoz0pzvF/JLe24uTik6YL0Ae6SD0pFXQ2KDrdH3cUHLok3r76/yGzaDNTFjS2 -2WbQ8dEJV8veNHk8gjGpFTJIsBUlcZpmUCDHlfvVMb3+2ahQ+28piQUt5t3zqJdZ -NDqsOHzY6BRPc+Wm85Xii/lWiQceZSee/b1Enu+nchsyXhSenBfC6bIGZReyMI0K -KKKuVhyR6OSOiR5ZdZ/NyXGqsWy05fn/h0X9hnpETsNaNYNKWvpHLfKll+STJpf7 -AZquJPIclQyiq5NONx6kfPztoCLkKV/zOgIj3Sx5oSZq+5gpO91nXWVwkTbqK1d1 -004q2Mah6UQyAk1XGQc2pHx7ouVcWawjU30vZ4C015Hv2lm/gVkCggEBAPltATYS -OqOSL1YAtIHPiHxMjNAgUdglq8JiJFXVfkocGU9eNub3Ed3sSWu6GB9Myu/sSKje -bJ5DZqxJnvB2Fqmu9I9OunLGFSD0aXs4prwsQ1Rm5FcbImtrxcciASdkoo8Pj0z4 -vk2r2NZD3VtER5Uh+YjSDkxcS9gBStXUpCL6gj69UpOxMmWqZVjyHatVB4lEvYJl -N82uT7N7QVNL1DzcZ9z4C4r7ks1Pm7ka12s5m/oaAlAMdVeofiPJe1xA9zRToSr4 -tIbMkOeXFLVRLuji/7XsOgal5Rl59p+OwLshX5cswPVOMrH6zt+hbsJ5q8M5dqnX -VAOBK7KNQ/EKZwcCggEBAPD6KVvyCim46n5EbcEqCkO7gevwZkw/9vLwmM5YsxTh -z9FQkPO0iB7mwbX8w04I91Pre4NdfcgMG0pP1b13Sb4KHBchqW1a+TCs3kSGC6gn -1SxmXHnA9jRxAkrWlGkoAQEz+aP61cXiiy2tXpQwJ8xQCKprfoqWZwhkCtEVU6CE -S7v9cscOHIqgNxx4WoceMmq4EoihHAZzHxTcNVbByckMjb2XQJ0iNw3lDP4ddvc+ -a4HzHfHkhzeQ5ZNc8SvWU8z80aSCOKRsSD3aUTZzxhZ4O2tZSW7v7p+FpvVee7bC -g8YCfszTdpVUMlLRLjScimAcovcFLSvtyupinxWg4M8CggEAN9YGEmOsSte7zwXj -YrfhtumwEBtcFwX/2Ej+F1Tuq4p0xAa0RaoDjumJWhtTsRYQy/raHSuFpzwxbNoi -QXQ+CIhI6RfXtz/OlQ0B2/rHoJJMFEXgUfuaDfAXW0eqeHYXyezSyIlamKqipPyW -Pgsf9yue39keKEv1EorfhNTQVaA8rezV4oglXwrxGyNALw2e3UTNI7ai8mFWKDis -XAg6n9E7UwUYGGnO6DUtCBgRJ0jDOQ6/e8n+LrxiWIKPIgzNCiK6jpMUXqTGv4Fb -umdNGAdQ9RnHt5tFmRlrczaSwJFtA7uaCpAR2zPpQbiywchZAiAIB2dTwGEXNiZX -kksg2wKCAQEA6pNad3qhkgPDoK6T+Jkn7M82paoaqtcJWWwEE7oceZNnbWZz9Agl -CY+vuawXonrv5+0vCq2Tp4zBdBFLC2h3jFrjBVFrUFxifpOIukOSTVqZFON/2bWQ -9XOcu6UuSz7522Xw+UNPnZXtzcUacD6AP08ZYGvLfrTyDyTzspyED5k48ALEHCkM -d5WGkFxII4etpF0TDZVnZo/iDbhe49k4yFFEGO6Ho26PESOLBkNAb2V/2bwDxlij -l9+g21Z6HiZA5SamHPH2mXgeyrcen1cL2QupK9J6vVcqfnboE6qp2zp2c+Yx8MlY -gfy4EA44YFaSDQVTTgrn8f9Eq+zc130H2QKCAQEAqOKgv68nIPdDSngNyCVyWego -boFiDaEJoBBg8FrBjTJ6wFLrNAnXmbvfTtgNmNAzF1cUPJZlIIsHgGrMCfpehbXq -WQQIw+E+yFbTGLxseGRfsLrV0CsgnAoOVeod+yIHmqc3livaUbrWhL1V2f6Ue+sE -7YLp/iP43NaMfA4kYk2ep7+ZJoEVkCjHJJaHWgAG3RynPJHkTJlSgu7wLYvGc9uE -ZsEFUM46lX02t7rrtMfasVGrUy1c2xOxFb4v1vG6iEZ7+YWeq5o3AkxUwEGn+mG4 -/3p+k4AaTXJDXgyZ0Sv6CkGuPHenAYG4cswcUUEf/G4Ag77x6LBNMgycJBxUJA== ------END RSA PRIVATE KEY----- diff --git a/apex/permission/com.android.permission.pk8 b/apex/permission/com.android.permission.pk8 Binary files differdeleted file mode 100644 index d51673dbc2fc..000000000000 --- a/apex/permission/com.android.permission.pk8 +++ /dev/null diff --git a/apex/permission/com.android.permission.x509.pem b/apex/permission/com.android.permission.x509.pem deleted file mode 100644 index 4b146c9edd4f..000000000000 --- 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 e71cc43f13fe..000000000000 --- 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 4ecc98980c43..000000000000 --- 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 d7c9a2395c04..000000000000 --- 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 d802177e249b..000000000000 --- 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 d802177e249b..000000000000 --- 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 6778d4826841..000000000000 --- 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<java.lang.Boolean>); - 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<java.lang.Boolean>); - method @Deprecated @NonNull @RequiresPermission("com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER") public java.util.List<java.lang.String> getHeldRolesFromController(@NonNull String); - method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public java.util.List<java.lang.String> getRoleHolders(@NonNull String); - method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public java.util.List<java.lang.String> 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<java.lang.Boolean>); - method @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public void isRoleVisible(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>); - 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<java.lang.Boolean>); - 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<java.lang.String>); - 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 d802177e249b..000000000000 --- 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 6cf961fad2c4..000000000000 --- 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 8a43d7fa9036..000000000000 --- 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 5fc25f0422e2..000000000000 --- 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<String> 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<String> roleNames); - - boolean addRoleHolderFromController(in String roleName, in String packageName); - - boolean removeRoleHolderFromController(in String roleName, in String packageName); - - List<String> 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 5958debc86dd..000000000000 --- 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 93a7ae0c82c0..000000000000 --- 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<ServiceConnector<IRoleController>> sRemoteServices = - new SparseArray<>(); - - @NonNull - private final ServiceConnector<IRoleController> 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<IRoleController> remoteService = sRemoteServices.get(userId); - if (remoteService == null) { - remoteService = new ServiceConnector.Impl<IRoleController>(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<Boolean> callback) { - AndroidFuture<Bundle> operation = mRemoteService.postAsync(service -> { - AndroidFuture<Bundle> 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<Bundle> operation = mRemoteService.postAsync(service -> { - AndroidFuture<Bundle> 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<Bundle> operation = mRemoteService.postAsync(service -> { - AndroidFuture<Bundle> 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<Bundle> operation = mRemoteService.postAsync(service -> { - AndroidFuture<Bundle> 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<Boolean> callback) { - AndroidFuture<Bundle> operation = mRemoteService.postAsync(service -> { - AndroidFuture<Bundle> 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<Boolean> callback) { - AndroidFuture<Bundle> operation = mRemoteService.postAsync(service -> { - AndroidFuture<Bundle> future = new AndroidFuture<>(); - service.isRoleVisible(roleName, new RemoteCallback(future::complete)); - return future; - }); - propagateCallback(operation, "isRoleVisible", executor, callback); - } - - private void propagateCallback(AndroidFuture<Bundle> operation, String opName, - @CallbackExecutor @NonNull Executor executor, - Consumer<Boolean> 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<Bundle> 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 cf7872913f26..000000000000 --- 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. - * <p> - * 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. - * <p> - * 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. - * <p> - * 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 7a97770ecf0f..000000000000 --- 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. - * - * <p>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 ceccc4cfc9f7..000000000000 --- 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. - * <p> - * 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 <a href="{@docRoot}reference/androidx/core/role/package-summary.html">AndroidX Role - * library</a>. - * <p> - * 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)}. - * <p> - * 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. - * <p> - * 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<ArrayMap<OnRoleHoldersChangedListener, - OnRoleHoldersChangedListenerDelegate>> 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. - * <p> - * 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. - * <p> - * <strong>Note:</strong> 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<String> getRoleHolders(@NonNull String roleName) { - return getRoleHoldersAsUser(roleName, Process.myUserHandle()); - } - - /** - * Get package names of the applications holding the role. - * <p> - * <strong>Note:</strong> 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<String> 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. - * <p> - * <strong>Note:</strong> 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<Boolean> 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. - * <p> - * <strong>Note:</strong> 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<Boolean> 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. - * <p> - * <strong>Note:</strong> 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<Boolean> 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<Boolean> 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 - * <p> - * <strong>Note:</strong> 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<OnRoleHoldersChangedListener, OnRoleHoldersChangedListenerDelegate> 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 - * <p> - * <strong>Note:</strong> 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<OnRoleHoldersChangedListener, OnRoleHoldersChangedListenerDelegate> 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}. - * <p> - * <strong>Note:</strong> 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<String> 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}. - * <p> - * <strong>Note:</strong> 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}. - * <p> - * <strong>Note:</strong> 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<String> 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<Boolean> 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<Boolean> 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 f8f140dd716e..000000000000 --- 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 52a61674a596..000000000000 --- 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 d802177e249b..000000000000 --- 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 d802177e249b..000000000000 --- 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 d802177e249b..000000000000 --- 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 d802177e249b..000000000000 --- 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 d802177e249b..000000000000 --- 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 d802177e249b..000000000000 --- 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 e810db8ecbfe..000000000000 --- 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 4729ed13dc4c..000000000000 --- 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 d0fc5b9d7c14..000000000000 --- 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 d802177e249b..000000000000 --- 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 d802177e249b..000000000000 --- 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 b1869c2c731d..000000000000 --- 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<java.lang.String,java.util.List<com.android.permission.persistence.RuntimePermissionsState.PermissionState>>, @NonNull java.util.Map<java.lang.String,java.util.List<com.android.permission.persistence.RuntimePermissionsState.PermissionState>>); - method @Nullable public String getFingerprint(); - method @NonNull public java.util.Map<java.lang.String,java.util.List<com.android.permission.persistence.RuntimePermissionsState.PermissionState>> getPackagePermissions(); - method @NonNull public java.util.Map<java.lang.String,java.util.List<com.android.permission.persistence.RuntimePermissionsState.PermissionState>> 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<java.lang.String,java.util.Set<java.lang.String>> 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<java.lang.String,java.util.Set<java.lang.String>>); - method @Nullable public String getPackagesHash(); - method @NonNull public java.util.Map<java.lang.String,java.util.Set<java.lang.String>> 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 d802177e249b..000000000000 --- 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 7c711d301f00..000000000000 --- 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 c89cc8eabb92..000000000000 --- 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 569a78c0ab41..000000000000 --- 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 aedba290db1f..000000000000 --- 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 e43f59a3377a..000000000000 --- 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<String, List<RuntimePermissionsState.PermissionState>> packagePermissions = - new ArrayMap<>(); - Map<String, List<RuntimePermissionsState.PermissionState>> 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<RuntimePermissionsState.PermissionState> permissions = parsePermissions( - parser); - packagePermissions.put(packageName, permissions); - break; - } - case TAG_SHARED_USER: { - String sharedUserName = parser.getAttributeValue(null, ATTRIBUTE_NAME); - List<RuntimePermissionsState.PermissionState> permissions = parsePermissions( - parser); - sharedUserPermissions.put(sharedUserName, permissions); - break; - } - } - } - - return new RuntimePermissionsState(version, fingerprint, packagePermissions, - sharedUserPermissions); - } - - @NonNull - private static List<RuntimePermissionsState.PermissionState> parsePermissions( - @NonNull XmlPullParser parser) throws IOException, XmlPullParserException { - List<RuntimePermissionsState.PermissionState> 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<String, List<RuntimePermissionsState.PermissionState>> entry - : runtimePermissions.getPackagePermissions().entrySet()) { - String packageName = entry.getKey(); - List<RuntimePermissionsState.PermissionState> 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<String, List<RuntimePermissionsState.PermissionState>> entry - : runtimePermissions.getSharedUserPermissions().entrySet()) { - String sharedUserName = entry.getKey(); - List<RuntimePermissionsState.PermissionState> 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<RuntimePermissionsState.PermissionState> 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 c6bfc6d32989..000000000000 --- 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<String, List<PermissionState>> mPackagePermissions; - - /** - * The runtime permissions by shared users. - */ - @NonNull - private final Map<String, List<PermissionState>> 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<String, List<PermissionState>> packagePermissions, - @NonNull Map<String, List<PermissionState>> 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<String, List<PermissionState>> getPackagePermissions() { - return mPackagePermissions; - } - - /** - * Get the runtime permissions by shared users. - * - * @return the runtime permissions by shared users - */ - @NonNull - public Map<String, List<PermissionState>> 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 5d5cd78201bd..000000000000 --- 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 <T> 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 <T> the type of the elements of the array - * @return first element of an array, or {@code null} if none - */ - public static <T> T firstOrNull(@Nullable T[] array) { - return !isEmpty(array) ? array[0] : null; - } - - /** - * @see java.util.List#indexOf(Object) - */ - public static <T> 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 <T> 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 7308eec98500..000000000000 --- 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 ea4952404179..000000000000 --- 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 <E> the element type of the {@link List} - * @return the first element of the {@link List}, or {@code 0} if none - */ - @Nullable - public static <E> E firstOrNull(@Nullable List<E> 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 cd6f6057030b..000000000000 --- 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 ba1c3939f73e..000000000000 --- 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 18fada534424..000000000000 --- 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 e243e2e0db66..000000000000 --- 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<String, Set<String>> 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 5f7eb22a42a7..000000000000 --- 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<RoleUserState> mUserStates = new SparseArray<>(); - - /** - * Maps user id to its controller. - */ - @GuardedBy("mLock") - @NonNull - private final SparseArray<RoleControllerManager> mControllers = new SparseArray<>(); - - /** - * Maps user id to its list of listeners. - */ - @GuardedBy("mLock") - @NonNull - private final SparseArray<RemoteCallbackList<IOnRoleHoldersChangedListener>> 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<ThrottledRunnable> 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.<UserHandle>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<Void> 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<Void> 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<Void> 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<IOnRoleHoldersChangedListener> getListeners(@UserIdInt int userId) { - synchronized (mLock) { - return mListeners.get(userId); - } - } - - @NonNull - private RemoteCallbackList<IOnRoleHoldersChangedListener> getOrCreateListeners( - @UserIdInt int userId) { - synchronized (mLock) { - RemoteCallbackList<IOnRoleHoldersChangedListener> listeners = mListeners.get(userId); - if (listeners == null) { - listeners = new RemoteCallbackList<>(); - mListeners.put(userId, listeners); - } - return listeners; - } - } - - private void onRemoveUser(@UserIdInt int userId) { - RemoteCallbackList<IOnRoleHoldersChangedListener> 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<IOnRoleHoldersChangedListener> listeners = getListeners(userId); - if (listeners != null) { - notifyRoleHoldersChangedForListeners(listeners, roleName, userId); - } - - RemoteCallbackList<IOnRoleHoldersChangedListener> allUsersListeners = getListeners( - UserHandleCompat.USER_ALL); - if (allUsersListeners != null) { - notifyRoleHoldersChangedForListeners(allUsersListeners, roleName, userId); - } - } - - @WorkerThread - private void notifyRoleHoldersChangedForListeners( - @NonNull RemoteCallbackList<IOnRoleHoldersChangedListener> 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<String> roleHolders = getOrCreateUserState(userId).getRoleHolders(roleName); - if (roleHolders == null) { - return false; - } - return roleHolders.contains(packageName); - } - - @NonNull - @Override - public List<String> 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<String> 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<IOnRoleHoldersChangedListener> 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<IOnRoleHoldersChangedListener> listeners = getListeners(userId); - if (listener == null) { - return; - } - listeners.unregister(listener); - } - - @Override - public void setRoleNamesFromController(@NonNull List<String> 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<String> 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<Void> 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<String, Set<String>> getRolesAndHolders(@UserIdInt int userId) { - // Convert ArrayMap<String, ArraySet<String>> to Map<String, Set<String>> for the API. - //noinspection unchecked - return (Map<String, Set<String>>) (Map<String, ?>) - 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 03b7c76d2df5..000000000000 --- 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<Void> { - @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 78d8d15bbe60..000000000000 --- 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<String, ArraySet<String>> 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<String> getRoleHolders(@NonNull String roleName) { - synchronized (mLock) { - ArraySet<String> 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<String> 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<String> 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<String> 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<String> 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<String> getHeldRoles(@NonNull String packageName) { - synchronized (mLock) { - List<String> 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<String, Set<String>>) (Map<String, ?>) snapshotRolesLocked()); - } - - mPersistence.writeForUser(roles, UserHandle.of(mUserId)); - } - - private void readFile() { - synchronized (mLock) { - RolesState roleState = mPersistence.readForUser(UserHandle.of(mUserId)); - - Map<String, Set<String>> roles; - if (roleState != null) { - mVersion = roleState.getVersion(); - mPackagesHash = roleState.getPackagesHash(); - roles = roleState.getRoles(); - } else { - roles = mPlatformHelper.getLegacyRoleState(mUserId); - } - mRoles.clear(); - for (Map.Entry<String, Set<String>> entry : roles.entrySet()) { - String roleName = entry.getKey(); - ArraySet<String> 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<String, ArraySet<String>> 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<String> 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<String, ArraySet<String>> getRolesAndHolders() { - synchronized (mLock) { - return snapshotRolesLocked(); - } - } - - @GuardedBy("mLock") - @NonNull - private ArrayMap<String, ArraySet<String>> snapshotRolesLocked() { - ArrayMap<String, ArraySet<String>> roles = new ArrayMap<>(); - for (int i = 0, size = CollectionUtils.size(mRoles); i < size; ++i) { - String roleName = mRoles.keyAt(i); - ArraySet<String> 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 0d7bc1476bd1..000000000000 --- 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 8b5b2516105f..000000000000 --- 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 2e5a28aa1d6a..000000000000 --- 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 f66257f13ef6..000000000000 --- 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<String, Set<String>> 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<String> roleHolders = parseRoleHolders(parser); - roles.put(roleName, roleHolders); - } - } - - return new RolesState(version, packagesHash, roles); - } - - @NonNull - private static Set<String> parseRoleHolders(@NonNull XmlPullParser parser) - throws IOException, XmlPullParserException { - Set<String> 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<String, Set<String>> entry : roles.getRoles().entrySet()) { - String roleName = entry.getKey(); - Set<String> 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<String> 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 f61efa0e840d..000000000000 --- 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<String, Set<String>> 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<String, Set<String>> 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<String, Set<String>> 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 79c42299207c..000000000000 --- 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 63bf0a08e956..000000000000 --- 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 bc19a9ea0172..000000000000 --- 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 271e328c1139..000000000000 --- 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 57ee6417aeb3..000000000000 --- a/apex/permission/tests/AndroidManifest.xml +++ /dev/null @@ -1,32 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<!-- - ~ 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. - --> - -<manifest - xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.permission.test"> - - <!-- The application has to be debuggable for static mocking to work. --> - <application android:debuggable="true"> - <uses-library android:name="android.test.runner" /> - </application> - - <instrumentation - android:name="androidx.test.runner.AndroidJUnitRunner" - android:targetPackage="com.android.permission.test" - android:label="Permission APEX Tests" /> -</manifest> 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 2987da087e51..000000000000 --- 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 f9d9d5afb25d..000000000000 --- 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 48094198c2e9..2b665c0fe9fc 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; |