diff options
-rw-r--r-- | PermissionController/AndroidManifest.xml | 2 | ||||
-rw-r--r-- | PermissionController/role-controller/java/com/android/role/controller/service/RoleControllerServiceImpl.java (renamed from PermissionController/src/com/android/permissioncontroller/role/service/RoleControllerServiceImpl.java) | 86 | ||||
-rw-r--r-- | service/java/com/android/role/LocalRoleController.java | 85 | ||||
-rw-r--r-- | service/java/com/android/role/RemoteRoleController.java | 65 | ||||
-rw-r--r-- | service/java/com/android/role/RoleController.java | 51 | ||||
-rw-r--r-- | service/java/com/android/role/RoleService.java | 24 |
6 files changed, 265 insertions, 48 deletions
diff --git a/PermissionController/AndroidManifest.xml b/PermissionController/AndroidManifest.xml index 288dc6c84..0d663bc05 100644 --- a/PermissionController/AndroidManifest.xml +++ b/PermissionController/AndroidManifest.xml @@ -521,7 +521,7 @@ </intent-filter> </service> - <service android:name="com.android.permissioncontroller.role.service.RoleControllerServiceImpl" + <service android:name="com.android.role.controller.service.RoleControllerServiceImpl" android:exported="true"> <intent-filter android:priority="1"> <action android:name="android.app.role.RoleControllerService"/> diff --git a/PermissionController/src/com/android/permissioncontroller/role/service/RoleControllerServiceImpl.java b/PermissionController/role-controller/java/com/android/role/controller/service/RoleControllerServiceImpl.java index 38fe22b76..d3c099d5e 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/service/RoleControllerServiceImpl.java +++ b/PermissionController/role-controller/java/com/android/role/controller/service/RoleControllerServiceImpl.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.permissioncontroller.role.service; +package com.android.role.controller.service; import android.app.role.RoleControllerService; import android.app.role.RoleManager; @@ -29,10 +29,10 @@ import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.WorkerThread; -import com.android.permissioncontroller.permission.utils.CollectionUtils; -import com.android.permissioncontroller.role.utils.PackageUtils; import com.android.role.controller.model.Role; import com.android.role.controller.model.Roles; +import com.android.role.controller.util.CollectionUtils; +import com.android.role.controller.util.PackageUtils; import com.android.role.controller.util.UserUtils; import java.util.ArrayList; @@ -48,16 +48,28 @@ public class RoleControllerServiceImpl extends RoleControllerService { private static final boolean DEBUG = false; - private UserHandle mUser; + private UserHandle mUser; + private Context mContext; private RoleManager mUserRoleManager; + public RoleControllerServiceImpl() {} + + public RoleControllerServiceImpl(@NonNull UserHandle user, @NonNull Context context) { + init(user, context); + } + @Override public void onCreate() { super.onCreate(); - mUser = Process.myUserHandle(); - Context userContext = UserUtils.getUserContext(this, mUser); + init(Process.myUserHandle(), this); + } + + private void init(@NonNull UserHandle user, @NonNull Context context) { + mUser = user; + mContext = context; + Context userContext = UserUtils.getUserContext(context, user); mUserRoleManager = userContext.getSystemService(RoleManager.class); } @@ -69,7 +81,7 @@ public class RoleControllerServiceImpl extends RoleControllerService { } // Gather the available roles for current user. - ArrayMap<String, Role> roleMap = Roles.get(this); + ArrayMap<String, Role> roleMap = Roles.get(mContext); List<Role> roles = new ArrayList<>(); List<String> roleNames = new ArrayList<>(); ArraySet<String> addedRoleNames = new ArraySet<>(); @@ -77,7 +89,7 @@ public class RoleControllerServiceImpl extends RoleControllerService { for (int i = 0; i < roleMapSize; i++) { Role role = roleMap.valueAt(i); - if (!role.isAvailableAsUser(mUser, this)) { + if (!role.isAvailableAsUser(mUser, mContext)) { continue; } roles.add(role); @@ -98,7 +110,7 @@ public class RoleControllerServiceImpl extends RoleControllerService { String roleName = addedRoleNames.valueAt(i); Role role = roleMap.get(roleName); - role.onRoleAddedAsUser(mUser, this); + role.onRoleAddedAsUser(mUser, mContext); } // Go through the holders of all roles. @@ -117,7 +129,7 @@ public class RoleControllerServiceImpl extends RoleControllerService { currentPackageNamesIndex++) { String packageName = currentPackageNames.get(currentPackageNamesIndex); - if (role.isPackageQualifiedAsUser(packageName, mUser, this)) { + if (role.isPackageQualifiedAsUser(packageName, mUser, mContext)) { // We should not override user set or fixed permissions because we are only // redoing the grant here. Otherwise, user won't be able to revoke permissions // granted by role. @@ -137,11 +149,11 @@ public class RoleControllerServiceImpl extends RoleControllerService { if (currentPackageNamesSize == 0 || isStaticRole) { List<String> packageNamesToAdd = null; if (addedRoleNames.contains(roleName) || isStaticRole) { - packageNamesToAdd = role.getDefaultHoldersAsUser(mUser, this); + packageNamesToAdd = role.getDefaultHoldersAsUser(mUser, mContext); } if (packageNamesToAdd == null || packageNamesToAdd.isEmpty()) { packageNamesToAdd = CollectionUtils.singletonOrEmpty( - role.getFallbackHolderAsUser(mUser, this)); + role.getFallbackHolderAsUser(mUser, mContext)); } int packageNamesToAddSize = packageNamesToAdd.size(); @@ -154,7 +166,7 @@ public class RoleControllerServiceImpl extends RoleControllerService { // static roles. continue; } - if (!role.isPackageQualifiedAsUser(packageName, mUser, this)) { + if (!role.isPackageQualifiedAsUser(packageName, mUser, mContext)) { Log.e(LOG_TAG, "Default/fallback role holder package doesn't qualify for" + " the role, package: " + packageName + ", role: " + roleName); continue; @@ -199,17 +211,17 @@ public class RoleControllerServiceImpl extends RoleControllerService { return false; } - Role role = Roles.get(this).get(roleName); + Role role = Roles.get(mContext).get(roleName); if (role == null) { Log.e(LOG_TAG, "Unknown role: " + roleName); return false; } - if (!role.isAvailableAsUser(mUser, this)) { + if (!role.isAvailableAsUser(mUser, mContext)) { Log.e(LOG_TAG, "Role is unavailable: " + roleName); return false; } - if (!role.isPackageQualifiedAsUser(packageName, mUser, this)) { + if (!role.isPackageQualifiedAsUser(packageName, mUser, mContext)) { Log.e(LOG_TAG, "Package does not qualify for the role, package: " + packageName + ", role: " + roleName); return false; @@ -244,8 +256,8 @@ public class RoleControllerServiceImpl extends RoleControllerService { return false; } - role.onHolderAddedAsUser(packageName, mUser, this); - role.onHolderChangedAsUser(mUser, this); + role.onHolderAddedAsUser(packageName, mUser, mContext); + role.onHolderChangedAsUser(mUser, mContext); return true; } @@ -258,12 +270,12 @@ public class RoleControllerServiceImpl extends RoleControllerService { return false; } - Role role = Roles.get(this).get(roleName); + Role role = Roles.get(mContext).get(roleName); if (role == null) { Log.e(LOG_TAG, "Unknown role: " + roleName); return false; } - if (!role.isAvailableAsUser(mUser, this)) { + if (!role.isAvailableAsUser(mUser, mContext)) { Log.e(LOG_TAG, "Role is unavailable: " + roleName); return false; } @@ -280,7 +292,7 @@ public class RoleControllerServiceImpl extends RoleControllerService { return false; } - role.onHolderChangedAsUser(mUser, this); + role.onHolderChangedAsUser(mUser, mContext); return true; } @@ -292,12 +304,12 @@ public class RoleControllerServiceImpl extends RoleControllerService { return false; } - Role role = Roles.get(this).get(roleName); + Role role = Roles.get(mContext).get(roleName); if (role == null) { Log.e(LOG_TAG, "Unknown role: " + roleName); return false; } - if (!role.isAvailableAsUser(mUser, this)) { + if (!role.isAvailableAsUser(mUser, mContext)) { Log.e(LOG_TAG, "Role is unavailable: " + roleName); return false; } @@ -314,7 +326,7 @@ public class RoleControllerServiceImpl extends RoleControllerService { return false; } - role.onHolderChangedAsUser(mUser, this); + role.onHolderChangedAsUser(mUser, mContext); return true; } @@ -328,7 +340,7 @@ public class RoleControllerServiceImpl extends RoleControllerService { @WorkerThread private boolean addRoleHolderInternal(@NonNull Role role, @NonNull String packageName, boolean dontKillApp, boolean overrideUser, boolean added) { - role.grantAsUser(packageName, dontKillApp, overrideUser, mUser, this); + role.grantAsUser(packageName, dontKillApp, overrideUser, mUser, mContext); String roleName = role.getName(); if (!added) { @@ -345,13 +357,13 @@ public class RoleControllerServiceImpl extends RoleControllerService { private boolean removeRoleHolderInternal(@NonNull Role role, @NonNull String packageName, boolean dontKillApp) { ApplicationInfo applicationInfo = PackageUtils.getApplicationInfoAsUser(packageName, - mUser, this); + mUser, mContext); if (applicationInfo == null) { Log.w(LOG_TAG, "Cannot get ApplicationInfo for package: " + packageName); } if (applicationInfo != null) { - role.revokeAsUser(packageName, dontKillApp, false, mUser, this); + role.revokeAsUser(packageName, dontKillApp, false, mUser, mContext); } String roleName = role.getName(); @@ -392,12 +404,12 @@ public class RoleControllerServiceImpl extends RoleControllerService { return true; } - String fallbackPackageName = role.getFallbackHolderAsUser(mUser, this); + String fallbackPackageName = role.getFallbackHolderAsUser(mUser, mContext); if (fallbackPackageName == null) { return true; } - if (!role.isPackageQualifiedAsUser(fallbackPackageName, mUser, this)) { + if (!role.isPackageQualifiedAsUser(fallbackPackageName, mUser, mContext)) { Log.e(LOG_TAG, "Fallback role holder package doesn't qualify for the role, package: " + fallbackPackageName + ", role: " + roleName); return false; @@ -424,20 +436,20 @@ public class RoleControllerServiceImpl extends RoleControllerService { @Override public boolean onIsApplicationVisibleForRole(@NonNull String roleName, @NonNull String packageName) { - Role role = Roles.get(this).get(roleName); + Role role = Roles.get(mContext).get(roleName); if (role == null) { return false; } - if (!role.isAvailableAsUser(mUser, this)) { + if (!role.isAvailableAsUser(mUser, mContext)) { return false; } - if (!role.isPackageQualifiedAsUser(packageName, mUser, this)) { + if (!role.isPackageQualifiedAsUser(packageName, mUser, mContext)) { return false; } ApplicationInfo applicationInfo = PackageUtils.getApplicationInfoAsUser(packageName, - mUser, this); + mUser, mContext); if (applicationInfo == null || !role.isApplicationVisibleAsUser(applicationInfo, mUser, - this)) { + mContext)) { return false; } return true; @@ -445,15 +457,15 @@ public class RoleControllerServiceImpl extends RoleControllerService { @Override public boolean onIsRoleVisible(@NonNull String roleName) { - Role role = Roles.get(this).get(roleName); + Role role = Roles.get(mContext).get(roleName); if (role == null) { return false; } - if (!role.isAvailableAsUser(mUser, this)) { + if (!role.isAvailableAsUser(mUser, mContext)) { return false; } - return role.isVisibleAsUser(mUser, this); + return role.isVisibleAsUser(mUser, mContext); } private static boolean checkFlags(int flags, int allowedFlags) { diff --git a/service/java/com/android/role/LocalRoleController.java b/service/java/com/android/role/LocalRoleController.java new file mode 100644 index 000000000..9bac68f4d --- /dev/null +++ b/service/java/com/android/role/LocalRoleController.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2023 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.app.role.RoleControllerService; +import android.app.role.RoleManager; +import android.content.Context; +import android.os.Bundle; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.RemoteCallback; +import android.os.UserHandle; + +import androidx.annotation.NonNull; + +import com.android.role.controller.service.RoleControllerServiceImpl; + +import java.util.concurrent.Executor; +import java.util.function.Consumer; + +public class LocalRoleController implements RoleController { + + @NonNull + private final RoleControllerServiceImpl mService; + @NonNull + private final HandlerThread mWorkerThread; + @NonNull + private final Handler mWorkerHandler; + + public LocalRoleController(@NonNull UserHandle user, @NonNull Context context) { + mService = new RoleControllerServiceImpl(user, context); + mWorkerThread = new HandlerThread(RoleControllerService.class.getSimpleName()); + mWorkerThread.start(); + mWorkerHandler = new Handler(mWorkerThread.getLooper()); + } + + @Override + public void grantDefaultRoles(@NonNull Executor executor, @NonNull Consumer<Boolean> callback) { + mWorkerHandler.post(() -> { + boolean successful = mService.onGrantDefaultRoles(); + executor.execute(() -> callback.accept(successful)); + }); + } + + @Override + public void onAddRoleHolder(@NonNull String roleName, @NonNull String packageName, + @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) { + mWorkerHandler.post(() -> { + boolean successful = mService.onAddRoleHolder(roleName, packageName, flags); + callback.sendResult(successful ? Bundle.EMPTY : null); + }); + } + + @Override + public void onRemoveRoleHolder(@NonNull String roleName, @NonNull String packageName, + @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) { + mWorkerHandler.post(() -> { + boolean successful = mService.onRemoveRoleHolder(roleName, packageName, flags); + callback.sendResult(successful ? Bundle.EMPTY : null); + }); + } + + @Override + public void onClearRoleHolders(@NonNull String roleName, + @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) { + mWorkerHandler.post(() -> { + boolean successful = mService.onClearRoleHolders(roleName, flags); + callback.sendResult(successful ? Bundle.EMPTY : null); + }); + } +} diff --git a/service/java/com/android/role/RemoteRoleController.java b/service/java/com/android/role/RemoteRoleController.java new file mode 100644 index 000000000..08854e118 --- /dev/null +++ b/service/java/com/android/role/RemoteRoleController.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2023 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.app.role.RoleControllerManager; +import android.app.role.RoleManager; +import android.content.Context; +import android.os.RemoteCallback; +import android.os.UserHandle; + +import androidx.annotation.NonNull; + +import com.android.permission.util.ForegroundThread; + +import java.util.concurrent.Executor; +import java.util.function.Consumer; + +public class RemoteRoleController implements RoleController { + @NonNull + private final RoleControllerManager mRoleControllerManager; + + public RemoteRoleController(@NonNull UserHandle user, @NonNull Context context) { + Context userContext = context.createContextAsUser(user, 0); + mRoleControllerManager = + RoleControllerManager.createWithInitializedRemoteServiceComponentName( + ForegroundThread.getHandler(), userContext); + } + + @Override + public void grantDefaultRoles(@NonNull Executor executor, @NonNull Consumer<Boolean> callback) { + mRoleControllerManager.grantDefaultRoles(executor, callback); + } + + @Override + public void onAddRoleHolder(@NonNull String roleName, @NonNull String packageName, + @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) { + mRoleControllerManager.onAddRoleHolder(roleName, packageName, flags, callback); + } + + @Override + public void onRemoveRoleHolder(@NonNull String roleName, @NonNull String packageName, + @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) { + mRoleControllerManager.onRemoveRoleHolder(roleName, packageName, flags, callback); + } + + @Override + public void onClearRoleHolders(@NonNull String roleName, + @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) { + mRoleControllerManager.onClearRoleHolders(roleName, flags, callback); + } +} diff --git a/service/java/com/android/role/RoleController.java b/service/java/com/android/role/RoleController.java new file mode 100644 index 000000000..4a5f2a8c2 --- /dev/null +++ b/service/java/com/android/role/RoleController.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2023 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.CallbackExecutor; +import android.annotation.NonNull; +import android.app.role.RoleManager; +import android.os.RemoteCallback; + +import java.util.concurrent.Executor; +import java.util.function.Consumer; + +public interface RoleController { + /** + * @see android.app.role.RoleControllerManager#grantDefaultRoles + */ + void grantDefaultRoles(@NonNull @CallbackExecutor Executor executor, + @NonNull Consumer<Boolean> callback); + + /** + * @see android.app.role.RoleControllerManager#onAddRoleHolder + */ + void onAddRoleHolder(@NonNull String roleName, @NonNull String packageName, + @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback); + + /** + * @see android.app.role.RoleControllerManager#onRemoveRoleHolder + */ + void onRemoveRoleHolder(@NonNull String roleName, @NonNull String packageName, + @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback); + + /** + * @see android.app.role.RoleControllerManager#onClearRoleHolders + */ + void onClearRoleHolders(@NonNull String roleName, + @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback); +} diff --git a/service/java/com/android/role/RoleService.java b/service/java/com/android/role/RoleService.java index 189b61f3e..9b733ab55 100644 --- a/service/java/com/android/role/RoleService.java +++ b/service/java/com/android/role/RoleService.java @@ -45,6 +45,7 @@ import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; +import android.permission.flags.Flags; import android.provider.Settings; import android.text.TextUtils; import android.util.ArraySet; @@ -130,7 +131,7 @@ public class RoleService extends SystemService implements RoleUserState.Callback */ @GuardedBy("mLock") @NonNull - private final SparseArray<RoleControllerManager> mControllers = new SparseArray<>(); + private final SparseArray<RoleController> mControllers = new SparseArray<>(); /** * Maps user id to its list of listeners. @@ -321,14 +322,17 @@ public class RoleService extends SystemService implements RoleUserState.Callback } @NonNull - private RoleControllerManager getOrCreateController(@UserIdInt int userId) { + private RoleController getOrCreateController(@UserIdInt int userId) { synchronized (mLock) { - RoleControllerManager controller = mControllers.get(userId); + RoleController controller = mControllers.get(userId); if (controller == null) { - Context systemContext = getContext(); - Context userContext = systemContext.createContextAsUser(UserHandle.of(userId), 0); - controller = RoleControllerManager.createWithInitializedRemoteServiceComponentName( - ForegroundThread.getHandler(), userContext); + UserHandle user = UserHandle.of(userId); + Context context = getContext(); + if (SdkLevel.isAtLeastV() && Flags.roleControllerInSystemServer()) { + controller = new LocalRoleController(user, context); + } else { + controller = new RemoteRoleController(user, context); + } mControllers.put(userId, controller); } return controller; @@ -577,11 +581,11 @@ public class RoleService extends SystemService implements RoleUserState.Callback Preconditions.checkArgumentIsSupported(DEFAULT_APPLICATION_ROLES, roleName); Objects.requireNonNull(callback, "callback cannot be null"); - RoleControllerManager roleControllerManager = getOrCreateController(userId); + RoleController roleController = getOrCreateController(userId); if (packageName != null) { - roleControllerManager.onAddRoleHolder(roleName, packageName, flags, callback); + roleController.onAddRoleHolder(roleName, packageName, flags, callback); } else { - roleControllerManager.onClearRoleHolders(roleName, flags, callback); + roleController.onClearRoleHolders(roleName, flags, callback); } } |