diff options
author | 2019-03-06 20:12:24 -0800 | |
---|---|---|
committer | 2019-03-08 15:51:02 -0800 | |
commit | f5e8ccd88fa0d2a7ea0a53b2e5b38c1ff60d2cc3 (patch) | |
tree | e183b90c1881720b953c4a55f8612bc70340893c | |
parent | 908309feb5f789a45d0e959776b72a4b2fac2271 (diff) |
Use a boolean Consumer instead of RoleManagerCallback.
And use RemoteCallback for it under the hood. This removes one AIDL
interface and allows using lambda, while aligning with what
PermissionControllerService does.
Bug: 127691087
Test: manual
Change-Id: Ia94e5bac59773380b2a4764d766bf6ff1dd5b7ff
-rw-r--r-- | Android.bp | 1 | ||||
-rw-r--r-- | api/system-current.txt | 21 | ||||
-rw-r--r-- | api/test-current.txt | 11 | ||||
-rw-r--r-- | core/java/android/app/role/IRoleController.aidl | 11 | ||||
-rw-r--r-- | core/java/android/app/role/IRoleManager.aidl | 9 | ||||
-rw-r--r-- | core/java/android/app/role/IRoleManagerCallback.aidl | 27 | ||||
-rw-r--r-- | core/java/android/app/role/RoleControllerManager.java | 213 | ||||
-rw-r--r-- | core/java/android/app/role/RoleControllerService.java | 178 | ||||
-rw-r--r-- | core/java/android/app/role/RoleManager.java | 80 | ||||
-rw-r--r-- | core/java/android/app/role/RoleManagerCallback.java | 56 | ||||
-rw-r--r-- | services/core/java/com/android/server/role/RoleManagerService.java | 99 | ||||
-rw-r--r-- | services/core/java/com/android/server/role/RoleManagerShellCommand.java | 47 | ||||
-rw-r--r-- | telecomm/java/android/telecom/DefaultDialerManager.java | 16 | ||||
-rw-r--r-- | telecomm/java/android/telecom/TelecomManager.java | 5 | ||||
-rw-r--r-- | telephony/java/com/android/internal/telephony/SmsApplication.java | 16 |
15 files changed, 337 insertions, 453 deletions
diff --git a/Android.bp b/Android.bp index e14281a2c464..9bf1a123e4ec 100644 --- a/Android.bp +++ b/Android.bp @@ -110,7 +110,6 @@ java_defaults { "core/java/android/app/role/IOnRoleHoldersChangedListener.aidl", "core/java/android/app/role/IRoleController.aidl", "core/java/android/app/role/IRoleManager.aidl", - "core/java/android/app/role/IRoleManagerCallback.aidl", "core/java/android/app/slice/ISliceManager.aidl", "core/java/android/app/slice/ISliceListener.aidl", "core/java/android/app/timedetector/ITimeDetectorService.aidl", diff --git a/api/system-current.txt b/api/system-current.txt index 0f1ab294c67a..e6319e3762b1 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -1118,37 +1118,32 @@ package android.app.role { public abstract class RoleControllerService extends android.app.Service { ctor public RoleControllerService(); - method public abstract void onAddRoleHolder(@NonNull String, @NonNull String, int, @NonNull android.app.role.RoleManagerCallback); + method @WorkerThread public abstract boolean onAddRoleHolder(@NonNull String, @NonNull String, int); method @Nullable public final android.os.IBinder onBind(@Nullable android.content.Intent); - method public abstract void onClearRoleHolders(@NonNull String, int, @NonNull android.app.role.RoleManagerCallback); - method public abstract void onGrantDefaultRoles(@NonNull android.app.role.RoleManagerCallback); + method @WorkerThread public abstract boolean onClearRoleHolders(@NonNull String, int); + method @WorkerThread public abstract boolean onGrantDefaultRoles(); method public abstract boolean onIsApplicationQualifiedForRole(@NonNull String, @NonNull String); method public abstract boolean onIsRoleVisible(@NonNull String); - method public abstract void onRemoveRoleHolder(@NonNull String, @NonNull String, int, @NonNull android.app.role.RoleManagerCallback); - method public abstract void onSmsKillSwitchToggled(boolean); + method @WorkerThread public abstract boolean onRemoveRoleHolder(@NonNull String, @NonNull String, int); + method @WorkerThread public abstract void onSmsKillSwitchToggled(boolean); field public static final String SERVICE_INTERFACE = "android.app.role.RoleControllerService"; } 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 android.app.role.RoleManagerCallback); + 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 @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 android.app.role.RoleManagerCallback); + 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 @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.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 android.app.role.RoleManagerCallback); + 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 @RequiresPermission("com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER") public boolean removeRoleHolderFromController(@NonNull String, @NonNull String); method @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 } - public interface RoleManagerCallback { - method public void onFailure(); - method public void onSuccess(); - } - } package android.app.usage { diff --git a/api/test-current.txt b/api/test-current.txt index 0bceddc09eef..7b11c5badf08 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -512,24 +512,19 @@ package android.app.role { public final class RoleManager { method @RequiresPermission("android.permission.OBSERVE_ROLE_HOLDERS") public void addOnRoleHoldersChangedListenerAsUser(@NonNull java.util.concurrent.Executor, @NonNull android.app.role.OnRoleHoldersChangedListener, @NonNull android.os.UserHandle); - method @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public void addRoleHolderAsUser(@NonNull String, @NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.role.RoleManagerCallback); + method @RequiresPermission("android.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 @RequiresPermission("com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER") public boolean addRoleHolderFromController(@NonNull String, @NonNull String); - method @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public void clearRoleHoldersAsUser(@NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.role.RoleManagerCallback); + method @RequiresPermission("android.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 @NonNull @RequiresPermission("com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER") public java.util.List<java.lang.String> getHeldRolesFromController(@NonNull String); method @NonNull @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public java.util.List<java.lang.String> getRoleHolders(@NonNull String); method @NonNull @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public java.util.List<java.lang.String> getRoleHoldersAsUser(@NonNull String, @NonNull android.os.UserHandle); method @RequiresPermission("android.permission.OBSERVE_ROLE_HOLDERS") public void removeOnRoleHoldersChangedListenerAsUser(@NonNull android.app.role.OnRoleHoldersChangedListener, @NonNull android.os.UserHandle); - method @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public void removeRoleHolderAsUser(@NonNull String, @NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.role.RoleManagerCallback); + method @RequiresPermission("android.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 @RequiresPermission("com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER") public boolean removeRoleHolderFromController(@NonNull String, @NonNull String); method @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 } - public interface RoleManagerCallback { - method public void onFailure(); - method public void onSuccess(); - } - } package android.app.usage { diff --git a/core/java/android/app/role/IRoleController.aidl b/core/java/android/app/role/IRoleController.aidl index e8f6ce2780b2..a472eacb28a1 100644 --- a/core/java/android/app/role/IRoleController.aidl +++ b/core/java/android/app/role/IRoleController.aidl @@ -16,7 +16,6 @@ package android.app.role; -import android.app.role.IRoleManagerCallback; import android.os.RemoteCallback; /** @@ -24,20 +23,20 @@ import android.os.RemoteCallback; */ oneway interface IRoleController { - void onGrantDefaultRoles(in IRoleManagerCallback callback); + void grantDefaultRoles(in RemoteCallback callback); void onAddRoleHolder(in String roleName, in String packageName, int flags, - in IRoleManagerCallback callback); + in RemoteCallback callback); void onRemoveRoleHolder(in String roleName, in String packageName, int flags, - in IRoleManagerCallback callback); + in RemoteCallback callback); - void onClearRoleHolders(in String roleName, int flags, in IRoleManagerCallback callback); + void onClearRoleHolders(in String roleName, int flags, in RemoteCallback callback); void onSmsKillSwitchToggled(boolean enabled); void isApplicationQualifiedForRole(in String roleName, in String packageName, - in RemoteCallback callback); + in RemoteCallback callback); void isRoleVisible(in String roleName, in RemoteCallback callback); } diff --git a/core/java/android/app/role/IRoleManager.aidl b/core/java/android/app/role/IRoleManager.aidl index 76dbf7e4504b..d8cea2860aa8 100644 --- a/core/java/android/app/role/IRoleManager.aidl +++ b/core/java/android/app/role/IRoleManager.aidl @@ -17,8 +17,8 @@ package android.app.role; import android.app.role.IOnRoleHoldersChangedListener; -import android.app.role.IRoleManagerCallback; import android.os.Bundle; +import android.os.RemoteCallback; import android.telephony.IFinancialSmsCallback; /** @@ -33,13 +33,13 @@ interface IRoleManager { List<String> getRoleHoldersAsUser(in String roleName, int userId); void addRoleHolderAsUser(in String roleName, in String packageName, int flags, int userId, - in IRoleManagerCallback callback); + in RemoteCallback callback); void removeRoleHolderAsUser(in String roleName, in String packageName, int flags, int userId, - in IRoleManagerCallback callback); + in RemoteCallback callback); void clearRoleHoldersAsUser(in String roleName, int flags, int userId, - in IRoleManagerCallback callback); + in RemoteCallback callback); void addOnRoleHoldersChangedListenerAsUser(IOnRoleHoldersChangedListener listener, int userId); @@ -55,6 +55,7 @@ interface IRoleManager { List<String> getHeldRolesFromController(in String packageName); String getDefaultSmsPackage(int userId); + /** * Get filtered SMS messages for financial app. */ diff --git a/core/java/android/app/role/IRoleManagerCallback.aidl b/core/java/android/app/role/IRoleManagerCallback.aidl deleted file mode 100644 index c0f8eea51a25..000000000000 --- a/core/java/android/app/role/IRoleManagerCallback.aidl +++ /dev/null @@ -1,27 +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 IRoleManagerCallback { - - void onSuccess(); - - void onFailure(); -} diff --git a/core/java/android/app/role/RoleControllerManager.java b/core/java/android/app/role/RoleControllerManager.java index 2edc526ff261..e96c9a541c3f 100644 --- a/core/java/android/app/role/RoleControllerManager.java +++ b/core/java/android/app/role/RoleControllerManager.java @@ -52,11 +52,6 @@ public class RoleControllerManager { private static final String LOG_TAG = RoleControllerManager.class.getSimpleName(); - /** - * The key for retrieving the result from a bundle. - */ - public static final String KEY_RESULT = "android.app.role.RoleControllerManager.key.RESULT"; - private static final Object sRemoteServicesLock = new Object(); /** * Global remote services (per user) used by all {@link RoleControllerManager managers}. @@ -90,35 +85,37 @@ public class RoleControllerManager { } /** - * @see RoleControllerService#onGrantDefaultRoles(RoleManagerCallback) + * @see RoleControllerService#onGrantDefaultRoles() */ - public void onGrantDefaultRoles(@NonNull IRoleManagerCallback callback) { - mRemoteService.scheduleRequest(new OnGrantDefaultRolesRequest(mRemoteService, callback)); + public void grantDefaultRoles(@NonNull @CallbackExecutor Executor executor, + @NonNull Consumer<Boolean> callback) { + mRemoteService.scheduleRequest(new GrantDefaultRolesRequest(mRemoteService, executor, + callback)); } /** - * @see RoleControllerService#onAddRoleHolder(String, String, int, RoleManagerCallback) + * @see RoleControllerService#onAddRoleHolder(String, String, int) */ public void onAddRoleHolder(@NonNull String roleName, @NonNull String packageName, - @RoleManager.ManageHoldersFlags int flags, @NonNull IRoleManagerCallback callback) { + @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) { mRemoteService.scheduleRequest(new OnAddRoleHolderRequest(mRemoteService, roleName, packageName, flags, callback)); } /** - * @see RoleControllerService#onRemoveRoleHolder(String, String, int, RoleManagerCallback) + * @see RoleControllerService#onRemoveRoleHolder(String, String, int) */ public void onRemoveRoleHolder(@NonNull String roleName, @NonNull String packageName, - @RoleManager.ManageHoldersFlags int flags, @NonNull IRoleManagerCallback callback) { + @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) { mRemoteService.scheduleRequest(new OnRemoveRoleHolderRequest(mRemoteService, roleName, packageName, flags, callback)); } /** - * @see RoleControllerService#onClearRoleHolders(String, int, RoleManagerCallback) + * @see RoleControllerService#onClearRoleHolders(String, int) */ public void onClearRoleHolders(@NonNull String roleName, - @RoleManager.ManageHoldersFlags int flags, @NonNull IRoleManagerCallback callback) { + @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) { mRemoteService.scheduleRequest(new OnClearRoleHoldersRequest(mRemoteService, roleName, flags, callback)); } @@ -210,68 +207,55 @@ public class RoleControllerManager { } /** - * Request for {@link #onGrantDefaultRoles(IRoleManagerCallback)}. + * Request for {@link #grantDefaultRoles(Executor, Consumer)}. */ - private static final class OnGrantDefaultRolesRequest + private static final class GrantDefaultRolesRequest extends AbstractRemoteService.PendingRequest<RemoteService, IRoleController> { @NonNull - private final IRoleManagerCallback mCallback; + private final Executor mExecutor; + @NonNull + private final Consumer<Boolean> mCallback; @NonNull - private final IRoleManagerCallback mRemoteCallback; + private final RemoteCallback mRemoteCallback; - private OnGrantDefaultRolesRequest(@NonNull RemoteService service, - @NonNull IRoleManagerCallback callback) { + private GrantDefaultRolesRequest(@NonNull RemoteService service, + @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> callback) { super(service); + mExecutor = executor; mCallback = callback; - mRemoteCallback = new IRoleManagerCallback.Stub() { - @Override - public void onSuccess() throws RemoteException { - long token = Binder.clearCallingIdentity(); - try { - mCallback.onSuccess(); - } finally { - Binder.restoreCallingIdentity(token); - finish(); - } - } - @Override - public void onFailure() throws RemoteException { - long token = Binder.clearCallingIdentity(); - try { - mCallback.onSuccess(); - } finally { - Binder.restoreCallingIdentity(token); - finish(); - } + mRemoteCallback = new RemoteCallback(result -> mExecutor.execute(() -> { + long token = Binder.clearCallingIdentity(); + try { + boolean successful = result != null; + mCallback.accept(successful); + } finally { + Binder.restoreCallingIdentity(token); + finish(); } - }; + })); } @Override protected void onTimeout(@NonNull RemoteService remoteService) { - try { - mCallback.onFailure(); - } catch (RemoteException e) { - Log.e(LOG_TAG, "Error calling onFailure() on callback", e); - } + mExecutor.execute(() -> mCallback.accept(false)); } @Override public void run() { try { - getService().getServiceInterface().onGrantDefaultRoles(mRemoteCallback); + getService().getServiceInterface().grantDefaultRoles(mRemoteCallback); } catch (RemoteException e) { - Log.e(LOG_TAG, "Error calling onGrantDefaultRoles()", e); + Log.e(LOG_TAG, "Error calling grantDefaultRoles()", e); } } } /** - * Request for {@link #onAddRoleHolder(String, String, int, IRoleManagerCallback)}. + * Request for {@link #onAddRoleHolder(String, String, int, RemoteCallback)}. */ private static final class OnAddRoleHolderRequest extends AbstractRemoteService.PendingRequest<RemoteService, IRoleController> { @@ -283,14 +267,14 @@ public class RoleControllerManager { @RoleManager.ManageHoldersFlags private final int mFlags; @NonNull - private final IRoleManagerCallback mCallback; + private final RemoteCallback mCallback; @NonNull - private final IRoleManagerCallback mRemoteCallback; + private final RemoteCallback mRemoteCallback; private OnAddRoleHolderRequest(@NonNull RemoteService service, @NonNull String roleName, @NonNull String packageName, @RoleManager.ManageHoldersFlags int flags, - @NonNull IRoleManagerCallback callback) { + @NonNull RemoteCallback callback) { super(service); mRoleName = roleName; @@ -298,37 +282,20 @@ public class RoleControllerManager { mFlags = flags; mCallback = callback; - mRemoteCallback = new IRoleManagerCallback.Stub() { - @Override - public void onSuccess() throws RemoteException { - long token = Binder.clearCallingIdentity(); - try { - mCallback.onSuccess(); - } finally { - Binder.restoreCallingIdentity(token); - finish(); - } - } - @Override - public void onFailure() throws RemoteException { - long token = Binder.clearCallingIdentity(); - try { - mCallback.onSuccess(); - } finally { - Binder.restoreCallingIdentity(token); - finish(); - } + mRemoteCallback = new RemoteCallback(result -> { + long token = Binder.clearCallingIdentity(); + try { + mCallback.sendResult(result); + } finally { + Binder.restoreCallingIdentity(token); + finish(); } - }; + }); } @Override protected void onTimeout(@NonNull RemoteService remoteService) { - try { - mCallback.onFailure(); - } catch (RemoteException e) { - Log.e(LOG_TAG, "Error calling onFailure() on callback", e); - } + mCallback.sendResult(null); } @Override @@ -343,7 +310,7 @@ public class RoleControllerManager { } /** - * Request for {@link #onRemoveRoleHolder(String, String, int, IRoleManagerCallback)}. + * Request for {@link #onRemoveRoleHolder(String, String, int, RemoteCallback)}. */ private static final class OnRemoveRoleHolderRequest extends AbstractRemoteService.PendingRequest<RemoteService, IRoleController> { @@ -355,14 +322,14 @@ public class RoleControllerManager { @RoleManager.ManageHoldersFlags private final int mFlags; @NonNull - private final IRoleManagerCallback mCallback; + private final RemoteCallback mCallback; @NonNull - private final IRoleManagerCallback mRemoteCallback; + private final RemoteCallback mRemoteCallback; private OnRemoveRoleHolderRequest(@NonNull RemoteService service, @NonNull String roleName, @NonNull String packageName, @RoleManager.ManageHoldersFlags int flags, - @NonNull IRoleManagerCallback callback) { + @NonNull RemoteCallback callback) { super(service); mRoleName = roleName; @@ -370,37 +337,20 @@ public class RoleControllerManager { mFlags = flags; mCallback = callback; - mRemoteCallback = new IRoleManagerCallback.Stub() { - @Override - public void onSuccess() throws RemoteException { - long token = Binder.clearCallingIdentity(); - try { - mCallback.onSuccess(); - } finally { - Binder.restoreCallingIdentity(token); - finish(); - } - } - @Override - public void onFailure() throws RemoteException { - long token = Binder.clearCallingIdentity(); - try { - mCallback.onSuccess(); - } finally { - Binder.restoreCallingIdentity(token); - finish(); - } + mRemoteCallback = new RemoteCallback(result -> { + long token = Binder.clearCallingIdentity(); + try { + mCallback.sendResult(result); + } finally { + Binder.restoreCallingIdentity(token); + finish(); } - }; + }); } @Override protected void onTimeout(@NonNull RemoteService remoteService) { - try { - mCallback.onFailure(); - } catch (RemoteException e) { - Log.e(LOG_TAG, "Error calling onFailure() on callback", e); - } + mCallback.sendResult(null); } @Override @@ -415,7 +365,7 @@ public class RoleControllerManager { } /** - * Request for {@link #onClearRoleHolders(String, int, IRoleManagerCallback)}. + * Request for {@link #onClearRoleHolders(String, int, RemoteCallback)}. */ private static final class OnClearRoleHoldersRequest extends AbstractRemoteService.PendingRequest<RemoteService, IRoleController> { @@ -425,50 +375,33 @@ public class RoleControllerManager { @RoleManager.ManageHoldersFlags private final int mFlags; @NonNull - private final IRoleManagerCallback mCallback; + private final RemoteCallback mCallback; @NonNull - private final IRoleManagerCallback mRemoteCallback; + private final RemoteCallback mRemoteCallback; private OnClearRoleHoldersRequest(@NonNull RemoteService service, @NonNull String roleName, - @RoleManager.ManageHoldersFlags int flags, @NonNull IRoleManagerCallback callback) { + @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) { super(service); mRoleName = roleName; mFlags = flags; mCallback = callback; - mRemoteCallback = new IRoleManagerCallback.Stub() { - @Override - public void onSuccess() throws RemoteException { - long token = Binder.clearCallingIdentity(); - try { - mCallback.onSuccess(); - } finally { - Binder.restoreCallingIdentity(token); - finish(); - } - } - @Override - public void onFailure() throws RemoteException { - long token = Binder.clearCallingIdentity(); - try { - mCallback.onSuccess(); - } finally { - Binder.restoreCallingIdentity(token); - finish(); - } + mRemoteCallback = new RemoteCallback(result -> { + long token = Binder.clearCallingIdentity(); + try { + mCallback.sendResult(result); + } finally { + Binder.restoreCallingIdentity(token); + finish(); } - }; + }); } @Override protected void onTimeout(@NonNull RemoteService remoteService) { - try { - mCallback.onFailure(); - } catch (RemoteException e) { - Log.e(LOG_TAG, "Error calling onFailure() on callback", e); - } + mCallback.sendResult(null); } @Override @@ -535,7 +468,7 @@ public class RoleControllerManager { mRemoteCallback = new RemoteCallback(result -> mExecutor.execute(() -> { long token = Binder.clearCallingIdentity(); try { - boolean qualified = result != null && result.getBoolean(KEY_RESULT); + boolean qualified = result != null; mCallback.accept(qualified); } finally { Binder.restoreCallingIdentity(token); @@ -587,7 +520,7 @@ public class RoleControllerManager { mRemoteCallback = new RemoteCallback(result -> mExecutor.execute(() -> { long token = Binder.clearCallingIdentity(); try { - boolean visible = result != null && result.getBoolean(KEY_RESULT); + boolean visible = result != null; mCallback.accept(visible); } finally { Binder.restoreCallingIdentity(token); diff --git a/core/java/android/app/role/RoleControllerService.java b/core/java/android/app/role/RoleControllerService.java index 47be38561b45..dd4d9d378e83 100644 --- a/core/java/android/app/role/RoleControllerService.java +++ b/core/java/android/app/role/RoleControllerService.java @@ -20,16 +20,20 @@ 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.RemoteException; import android.os.UserHandle; -import android.util.Log; import com.android.internal.util.Preconditions; +import com.android.internal.util.function.pooled.PooledLambda; import java.util.concurrent.Executor; @@ -45,59 +49,102 @@ import java.util.concurrent.Executor; @SystemApi public abstract class RoleControllerService extends Service { - private static final String LOG_TAG = RoleControllerService.class.getSimpleName(); - /** * 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 onGrantDefaultRoles(IRoleManagerCallback callback) { + public void grantDefaultRoles(RemoteCallback callback) { + enforceCallerSystemUid("grantDefaultRoles"); + Preconditions.checkNotNull(callback, "callback cannot be null"); - RoleControllerService.this.onGrantDefaultRoles(new RoleManagerCallbackDelegate( + + mWorkerHandler.sendMessage(PooledLambda.obtainMessage( + RoleControllerService::grantDefaultRoles, RoleControllerService.this, callback)); } @Override public void onAddRoleHolder(String roleName, String packageName, int flags, - IRoleManagerCallback callback) { + RemoteCallback callback) { + enforceCallerSystemUid("onAddRoleHolder"); + Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); Preconditions.checkNotNull(callback, "callback cannot be null"); - RoleControllerService.this.onAddRoleHolder(roleName, packageName, flags, - new RoleManagerCallbackDelegate(callback)); + + mWorkerHandler.sendMessage(PooledLambda.obtainMessage( + RoleControllerService::onAddRoleHolder, RoleControllerService.this, + roleName, packageName, flags, callback)); } @Override public void onRemoveRoleHolder(String roleName, String packageName, int flags, - IRoleManagerCallback callback) { + RemoteCallback callback) { + enforceCallerSystemUid("onRemoveRoleHolder"); + Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); Preconditions.checkNotNull(callback, "callback cannot be null"); - RoleControllerService.this.onRemoveRoleHolder(roleName, packageName, flags, - new RoleManagerCallbackDelegate(callback)); + + mWorkerHandler.sendMessage(PooledLambda.obtainMessage( + RoleControllerService::onRemoveRoleHolder, RoleControllerService.this, + roleName, packageName, flags, callback)); } @Override - public void onClearRoleHolders(String roleName, int flags, - IRoleManagerCallback callback) { + public void onClearRoleHolders(String roleName, int flags, RemoteCallback callback) { + enforceCallerSystemUid("onClearRoleHolders"); + Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); Preconditions.checkNotNull(callback, "callback cannot be null"); - RoleControllerService.this.onClearRoleHolders(roleName, flags, - new RoleManagerCallbackDelegate(callback)); + + mWorkerHandler.sendMessage(PooledLambda.obtainMessage( + RoleControllerService::onClearRoleHolders, RoleControllerService.this, + roleName, flags, callback)); } @Override - public void onSmsKillSwitchToggled(boolean smsRestrictionEnabled) { - RoleControllerService.this.onSmsKillSwitchToggled(smsRestrictionEnabled); + public void onSmsKillSwitchToggled(boolean enabled) { + enforceCallerSystemUid("onSmsKillSwitchToggled"); + + mWorkerHandler.sendMessage(PooledLambda.obtainMessage( + RoleControllerService::onSmsKillSwitchToggled, RoleControllerService.this, + enabled)); + } + + private void enforceCallerSystemUid(@NonNull String methodName) { + if (Binder.getCallingUid() != Process.SYSTEM_UID) { + throw new SecurityException("Only the system process can call " + methodName + + "()"); + } } @Override @@ -111,9 +158,7 @@ public abstract class RoleControllerService extends Service { Preconditions.checkNotNull(callback, "callback cannot be null"); boolean qualified = onIsApplicationQualifiedForRole(roleName, packageName); - Bundle result = new Bundle(); - result.putBoolean(RoleControllerManager.KEY_RESULT, qualified); - callback.sendResult(result); + callback.sendResult(qualified ? Bundle.EMPTY : null); } @Override @@ -124,22 +169,44 @@ public abstract class RoleControllerService extends Service { Preconditions.checkNotNull(callback, "callback cannot be null"); boolean visible = onIsRoleVisible(roleName); - Bundle result = new Bundle(); - result.putBoolean(RoleControllerManager.KEY_RESULT, visible); - callback.sendResult(result); + 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 * - * @param callback the callback for whether this call is successful + * @return whether this call was successful */ - public abstract void onGrantDefaultRoles(@NonNull RoleManagerCallback callback); + @WorkerThread + public abstract boolean onGrantDefaultRoles(); /** * Add a specific application to the holders of a role. If the role is exclusive, the previous @@ -151,13 +218,15 @@ public abstract class RoleControllerService extends Service { * @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 callback the callback for whether this call is successful + * + * @return whether this call was successful * * @see RoleManager#addRoleHolderAsUser(String, String, int, UserHandle, Executor, - * RoleManagerCallback) + * RemoteCallback) */ - public abstract void onAddRoleHolder(@NonNull String roleName, @NonNull String packageName, - @RoleManager.ManageHoldersFlags int flags, @NonNull RoleManagerCallback callback); + @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. @@ -165,26 +234,29 @@ public abstract class RoleControllerService extends Service { * @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 callback the callback for whether this call is successful + * + * @return whether this call was successful * * @see RoleManager#removeRoleHolderAsUser(String, String, int, UserHandle, Executor, - * RoleManagerCallback) + * RemoteCallback) */ - public abstract void onRemoveRoleHolder(@NonNull String roleName, @NonNull String packageName, - @RoleManager.ManageHoldersFlags int flags, @NonNull RoleManagerCallback callback); + @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 - * @param callback the callback for whether this call is successful * - * @see RoleManager#clearRoleHoldersAsUser(String, int, UserHandle, Executor, - * RoleManagerCallback) + * @return whether this call was successful + * + * @see RoleManager#clearRoleHoldersAsUser(String, int, UserHandle, Executor, RemoteCallback) */ - public abstract void onClearRoleHolders(@NonNull String roleName, - @RoleManager.ManageHoldersFlags int flags, @NonNull RoleManagerCallback callback); + @WorkerThread + public abstract boolean onClearRoleHolders(@NonNull String roleName, + @RoleManager.ManageHoldersFlags int flags); /** * Cleanup appop/permissions state in response to sms kill switch toggle @@ -192,6 +264,7 @@ public abstract class RoleControllerService extends Service { * @param enabled whether kill switch was turned on */ //STOPSHIP: remove this api before shipping a final version + @WorkerThread public abstract void onSmsKillSwitchToggled(boolean enabled); /** @@ -213,31 +286,4 @@ public abstract class RoleControllerService extends Service { * @return whether the role should be visible to user */ public abstract boolean onIsRoleVisible(@NonNull String roleName); - - private static class RoleManagerCallbackDelegate implements RoleManagerCallback { - - private IRoleManagerCallback mCallback; - - RoleManagerCallbackDelegate(IRoleManagerCallback callback) { - mCallback = callback; - } - - @Override - public void onSuccess() { - try { - mCallback.onSuccess(); - } catch (RemoteException e) { - Log.e(LOG_TAG, "Error calling onSuccess() callback"); - } - } - - @Override - public void onFailure() { - try { - mCallback.onFailure(); - } catch (RemoteException e) { - Log.e(LOG_TAG, "Error calling onFailure() callback"); - } - } - } } diff --git a/core/java/android/app/role/RoleManager.java b/core/java/android/app/role/RoleManager.java index a663498d9057..d1f8ed20cf0f 100644 --- a/core/java/android/app/role/RoleManager.java +++ b/core/java/android/app/role/RoleManager.java @@ -30,6 +30,7 @@ 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.ServiceManager; import android.os.UserHandle; @@ -42,6 +43,7 @@ import com.android.internal.util.function.pooled.PooledLambda; import java.util.List; import java.util.concurrent.Executor; +import java.util.function.Consumer; /** * This class provides information about and manages roles. @@ -315,9 +317,9 @@ public final class RoleManager { * * @return a list of package names of the role holders, or an empty list if none. * - * @see #addRoleHolderAsUser(String, String, int, UserHandle, Executor, RoleManagerCallback) - * @see #removeRoleHolderAsUser(String, String, int, UserHandle, Executor, RoleManagerCallback) - * @see #clearRoleHoldersAsUser(String, int, UserHandle, Executor, RoleManagerCallback) + * @see #addRoleHolderAsUser(String, String, int, UserHandle, Executor, Consumer) + * @see #removeRoleHolderAsUser(String, String, int, UserHandle, Executor, Consumer) + * @see #clearRoleHoldersAsUser(String, int, UserHandle, Executor, Consumer) * * @hide */ @@ -351,8 +353,8 @@ public final class RoleManager { * @param callback the callback for whether this call is successful * * @see #getRoleHoldersAsUser(String, UserHandle) - * @see #removeRoleHolderAsUser(String, String, int, UserHandle, Executor, RoleManagerCallback) - * @see #clearRoleHoldersAsUser(String, int, UserHandle, Executor, RoleManagerCallback) + * @see #removeRoleHolderAsUser(String, String, int, UserHandle, Executor, Consumer) + * @see #clearRoleHoldersAsUser(String, int, UserHandle, Executor, Consumer) * * @hide */ @@ -361,7 +363,7 @@ public final class RoleManager { @TestApi public void addRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName, @ManageHoldersFlags int flags, @NonNull UserHandle user, - @CallbackExecutor @NonNull Executor executor, @NonNull RoleManagerCallback callback) { + @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"); Preconditions.checkNotNull(user, "user cannot be null"); @@ -369,7 +371,7 @@ public final class RoleManager { Preconditions.checkNotNull(callback, "callback cannot be null"); try { mService.addRoleHolderAsUser(roleName, packageName, flags, user.getIdentifier(), - new RoleManagerCallbackDelegate(executor, callback)); + createRemoteCallback(executor, callback)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -390,8 +392,8 @@ public final class RoleManager { * @param callback the callback for whether this call is successful * * @see #getRoleHoldersAsUser(String, UserHandle) - * @see #addRoleHolderAsUser(String, String, int, UserHandle, Executor, RoleManagerCallback) - * @see #clearRoleHoldersAsUser(String, int, UserHandle, Executor, RoleManagerCallback) + * @see #addRoleHolderAsUser(String, String, int, UserHandle, Executor, Consumer) + * @see #clearRoleHoldersAsUser(String, int, UserHandle, Executor, Consumer) * * @hide */ @@ -400,7 +402,7 @@ public final class RoleManager { @TestApi public void removeRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName, @ManageHoldersFlags int flags, @NonNull UserHandle user, - @CallbackExecutor @NonNull Executor executor, @NonNull RoleManagerCallback callback) { + @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"); Preconditions.checkNotNull(user, "user cannot be null"); @@ -408,7 +410,7 @@ public final class RoleManager { Preconditions.checkNotNull(callback, "callback cannot be null"); try { mService.removeRoleHolderAsUser(roleName, packageName, flags, user.getIdentifier(), - new RoleManagerCallbackDelegate(executor, callback)); + createRemoteCallback(executor, callback)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -428,8 +430,8 @@ public final class RoleManager { * @param callback the callback for whether this call is successful * * @see #getRoleHoldersAsUser(String, UserHandle) - * @see #addRoleHolderAsUser(String, String, int, UserHandle, Executor, RoleManagerCallback) - * @see #removeRoleHolderAsUser(String, String, int, UserHandle, Executor, RoleManagerCallback) + * @see #addRoleHolderAsUser(String, String, int, UserHandle, Executor, Consumer) + * @see #removeRoleHolderAsUser(String, String, int, UserHandle, Executor, Consumer) * * @hide */ @@ -438,19 +440,33 @@ public final class RoleManager { @TestApi public void clearRoleHoldersAsUser(@NonNull String roleName, @ManageHoldersFlags int flags, @NonNull UserHandle user, @CallbackExecutor @NonNull Executor executor, - @NonNull RoleManagerCallback callback) { + @NonNull Consumer<Boolean> callback) { Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); Preconditions.checkNotNull(user, "user cannot be null"); Preconditions.checkNotNull(executor, "executor cannot be null"); Preconditions.checkNotNull(callback, "callback cannot be null"); try { mService.clearRoleHoldersAsUser(roleName, flags, user.getIdentifier(), - new RoleManagerCallbackDelegate(executor, callback)); + 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; + long token = Binder.clearCallingIdentity(); + try { + callback.accept(successful); + } finally { + Binder.restoreCallingIdentity(token); + } + })); + } + /** * Add a listener to observe role holder changes * <p> @@ -669,40 +685,6 @@ public final class RoleManager { } } - private static class RoleManagerCallbackDelegate extends IRoleManagerCallback.Stub { - - @NonNull - private final Executor mExecutor; - @NonNull - private final RoleManagerCallback mCallback; - - RoleManagerCallbackDelegate(@NonNull Executor executor, - @NonNull RoleManagerCallback callback) { - mExecutor = executor; - mCallback = callback; - } - - @Override - public void onSuccess() { - long token = Binder.clearCallingIdentity(); - try { - mExecutor.execute(mCallback::onSuccess); - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void onFailure() { - long token = Binder.clearCallingIdentity(); - try { - mExecutor.execute(mCallback::onFailure); - } finally { - Binder.restoreCallingIdentity(token); - } - } - } - private static class OnRoleHoldersChangedListenerDelegate extends IOnRoleHoldersChangedListener.Stub { diff --git a/core/java/android/app/role/RoleManagerCallback.java b/core/java/android/app/role/RoleManagerCallback.java deleted file mode 100644 index a92ef327de3c..000000000000 --- a/core/java/android/app/role/RoleManagerCallback.java +++ /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. - */ - -package android.app.role; - -import android.annotation.SystemApi; -import android.annotation.TestApi; - -import java.util.concurrent.CompletableFuture; - -/** - * Callback for a {@link RoleManager} request. - * - * @hide - */ -@SystemApi -@TestApi -public interface RoleManagerCallback { - - /** - * Signals a success. - */ - void onSuccess(); - - /** - * Signals a failure. - */ - void onFailure(); - - /** @hide */ - class Future extends CompletableFuture<Void> implements RoleManagerCallback { - - @Override - public void onSuccess() { - complete(null); - } - - @Override - public void onFailure() { - completeExceptionally(new RuntimeException()); - } - } -} diff --git a/services/core/java/com/android/server/role/RoleManagerService.java b/services/core/java/com/android/server/role/RoleManagerService.java index 059e6d70064e..f4e10ede19d5 100644 --- a/services/core/java/com/android/server/role/RoleManagerService.java +++ b/services/core/java/com/android/server/role/RoleManagerService.java @@ -27,7 +27,6 @@ import android.app.ActivityManager; import android.app.AppOpsManager; import android.app.role.IOnRoleHoldersChangedListener; import android.app.role.IRoleManager; -import android.app.role.IRoleManagerCallback; import android.app.role.RoleControllerManager; import android.app.role.RoleManager; import android.content.BroadcastReceiver; @@ -245,14 +244,11 @@ public class RoleManagerService extends SystemService implements RoleUserState.C // Run grants again Slog.i(LOG_TAG, "Granting default permissions..."); CompletableFuture<Void> result = new CompletableFuture<>(); - getOrCreateControllerService(userId).onGrantDefaultRoles( - new IRoleManagerCallback.Stub() { - @Override - public void onSuccess() { + getOrCreateControllerService(userId).grantDefaultRoles(FgThread.getExecutor(), + successful -> { + if (successful) { result.complete(null); - } - @Override - public void onFailure() { + } else { result.completeExceptionally(new RuntimeException()); } }); @@ -434,11 +430,12 @@ public class RoleManagerService extends SystemService implements RoleUserState.C @Override public boolean isRoleHeld(@NonNull String roleName, @NonNull String packageName) { - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); 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 = UserHandle.getUserId(callingUid); ArraySet<String> roleHolders = getOrCreateUserState(userId).getRoleHolders(roleName); if (roleHolders == null) { @@ -450,7 +447,6 @@ public class RoleManagerService extends SystemService implements RoleUserState.C @NonNull @Override public List<String> getRoleHoldersAsUser(@NonNull String roleName, @UserIdInt int userId) { - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); if (!mUserManagerInternal.exists(userId)) { Slog.e(LOG_TAG, "user " + userId + " does not exist"); return Collections.emptyList(); @@ -459,6 +455,8 @@ public class RoleManagerService extends SystemService implements RoleUserState.C 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(); @@ -469,10 +467,7 @@ public class RoleManagerService extends SystemService implements RoleUserState.C @Override public void addRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName, @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId, - @NonNull IRoleManagerCallback callback) { - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); - Preconditions.checkNotNull(callback, "callback cannot be null"); + @NonNull RemoteCallback callback) { if (!mUserManagerInternal.exists(userId)) { Slog.e(LOG_TAG, "user " + userId + " does not exist"); return; @@ -481,6 +476,10 @@ public class RoleManagerService extends SystemService implements RoleUserState.C 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"); + Preconditions.checkNotNull(callback, "callback cannot be null"); + getOrCreateControllerService(userId).onAddRoleHolder(roleName, packageName, flags, callback); } @@ -488,10 +487,7 @@ public class RoleManagerService extends SystemService implements RoleUserState.C @Override public void removeRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName, @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId, - @NonNull IRoleManagerCallback callback) { - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); - Preconditions.checkNotNull(callback, "callback cannot be null"); + @NonNull RemoteCallback callback) { if (!mUserManagerInternal.exists(userId)) { Slog.e(LOG_TAG, "user " + userId + " does not exist"); return; @@ -500,6 +496,10 @@ public class RoleManagerService extends SystemService implements RoleUserState.C 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"); + Preconditions.checkNotNull(callback, "callback cannot be null"); + getOrCreateControllerService(userId).onRemoveRoleHolder(roleName, packageName, flags, callback); } @@ -507,9 +507,7 @@ public class RoleManagerService extends SystemService implements RoleUserState.C @Override public void clearRoleHoldersAsUser(@NonNull String roleName, @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId, - @NonNull IRoleManagerCallback callback) { - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Preconditions.checkNotNull(callback, "callback cannot be null"); + @NonNull RemoteCallback callback) { if (!mUserManagerInternal.exists(userId)) { Slog.e(LOG_TAG, "user " + userId + " does not exist"); return; @@ -518,13 +516,15 @@ public class RoleManagerService extends SystemService implements RoleUserState.C getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS, "clearRoleHoldersAsUser"); + Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); + Preconditions.checkNotNull(callback, "callback cannot be null"); + getOrCreateControllerService(userId).onClearRoleHolders(roleName, flags, callback); } @Override public void addOnRoleHoldersChangedListenerAsUser( @NonNull IOnRoleHoldersChangedListener listener, @UserIdInt int userId) { - Preconditions.checkNotNull(listener, "listener cannot be null"); if (userId != UserHandle.USER_ALL && !mUserManagerInternal.exists(userId)) { Slog.e(LOG_TAG, "user " + userId + " does not exist"); return; @@ -533,6 +533,8 @@ public class RoleManagerService extends SystemService implements RoleUserState.C getContext().enforceCallingOrSelfPermission(Manifest.permission.OBSERVE_ROLE_HOLDERS, "addOnRoleHoldersChangedListenerAsUser"); + Preconditions.checkNotNull(listener, "listener cannot be null"); + RemoteCallbackList<IOnRoleHoldersChangedListener> listeners = getOrCreateListeners( userId); listeners.register(listener); @@ -541,7 +543,6 @@ public class RoleManagerService extends SystemService implements RoleUserState.C @Override public void removeOnRoleHoldersChangedListenerAsUser( @NonNull IOnRoleHoldersChangedListener listener, @UserIdInt int userId) { - Preconditions.checkNotNull(listener, "listener cannot be null"); if (userId != UserHandle.USER_ALL && !mUserManagerInternal.exists(userId)) { Slog.e(LOG_TAG, "user " + userId + " does not exist"); return; @@ -550,6 +551,8 @@ public class RoleManagerService extends SystemService implements RoleUserState.C getContext().enforceCallingOrSelfPermission(Manifest.permission.OBSERVE_ROLE_HOLDERS, "removeOnRoleHoldersChangedListenerAsUser"); + Preconditions.checkNotNull(listener, "listener cannot be null"); + RemoteCallbackList<IOnRoleHoldersChangedListener> listeners = getListeners(userId); if (listener == null) { return; @@ -559,11 +562,12 @@ public class RoleManagerService extends SystemService implements RoleUserState.C @Override public void setRoleNamesFromController(@NonNull List<String> roleNames) { - Preconditions.checkNotNull(roleNames, "roleNames cannot be null"); getContext().enforceCallingOrSelfPermission( RoleManager.PERMISSION_MANAGE_ROLES_FROM_CONTROLLER, "setRoleNamesFromController"); + Preconditions.checkNotNull(roleNames, "roleNames cannot be null"); + int userId = UserHandle.getCallingUserId(); getOrCreateUserState(userId).setRoleNames(roleNames); } @@ -571,12 +575,13 @@ public class RoleManagerService extends SystemService implements RoleUserState.C @Override 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"); 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 = UserHandle.getCallingUserId(); return getOrCreateUserState(userId).addRoleHolder(roleName, packageName); } @@ -584,23 +589,25 @@ public class RoleManagerService extends SystemService implements RoleUserState.C @Override 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"); 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 = UserHandle.getCallingUserId(); return getOrCreateUserState(userId).removeRoleHolder(roleName, packageName); } @Override public List<String> getHeldRolesFromController(@NonNull String packageName) { - Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); getContext().enforceCallingOrSelfPermission( RoleManager.PERMISSION_MANAGE_ROLES_FROM_CONTROLLER, "getRolesHeldFromController"); + Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); + int userId = UserHandle.getCallingUserId(); return getOrCreateUserState(userId).getHeldRoles(packageName); } @@ -728,16 +735,14 @@ public class RoleManagerService extends SystemService implements RoleUserState.C @Override public boolean setDefaultBrowser(@Nullable String packageName, @UserIdInt int userId) { CompletableFuture<Void> future = new CompletableFuture<>(); - IRoleManagerCallback callback = new IRoleManagerCallback.Stub() { - @Override - public void onSuccess() { + RemoteCallback callback = new RemoteCallback(result -> { + boolean successful = result != null; + if (successful) { future.complete(null); - } - @Override - public void onFailure() { + } else { future.completeExceptionally(new RuntimeException()); } - }; + }); if (packageName != null) { getOrCreateControllerService(userId).onAddRoleHolder(RoleManager.ROLE_BROWSER, packageName, 0, callback); @@ -756,14 +761,12 @@ public class RoleManagerService extends SystemService implements RoleUserState.C @Override public void setDefaultBrowserAsync(@Nullable String packageName, @UserIdInt int userId) { - IRoleManagerCallback callback = new IRoleManagerCallback.Stub() { - @Override - public void onSuccess() {} - @Override - public void onFailure() { + RemoteCallback callback = new RemoteCallback(result -> { + boolean successful = result != null; + if (!successful) { Slog.e(LOG_TAG, "Failed to set default browser: " + packageName); } - }; + }); if (packageName != null) { getOrCreateControllerService(userId).onAddRoleHolder(RoleManager.ROLE_BROWSER, packageName, 0, callback); @@ -785,14 +788,12 @@ public class RoleManagerService extends SystemService implements RoleUserState.C @Override public void setDefaultHomeAsync(@Nullable String packageName, @UserIdInt int userId) { - IRoleManagerCallback callback = new IRoleManagerCallback.Stub() { - @Override - public void onSuccess() {} - @Override - public void onFailure() { + RemoteCallback callback = new RemoteCallback(result -> { + boolean successful = result != null; + if (!successful) { Slog.e(LOG_TAG, "Failed to set default home: " + packageName); } - }; + }); if (packageName != null) { getOrCreateControllerService(userId).onAddRoleHolder(RoleManager.ROLE_HOME, packageName, 0, callback); diff --git a/services/core/java/com/android/server/role/RoleManagerShellCommand.java b/services/core/java/com/android/server/role/RoleManagerShellCommand.java index 00021d7fb986..b26a070f3978 100644 --- a/services/core/java/com/android/server/role/RoleManagerShellCommand.java +++ b/services/core/java/com/android/server/role/RoleManagerShellCommand.java @@ -19,7 +19,7 @@ package com.android.server.role; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.role.IRoleManager; -import android.app.role.IRoleManagerCallback; +import android.os.RemoteCallback; import android.os.RemoteException; import android.os.ShellCommand; import android.os.UserHandle; @@ -38,14 +38,23 @@ class RoleManagerShellCommand extends ShellCommand { mRoleManager = roleManager; } - private class Callback extends IRoleManagerCallback.Stub { + private class CallbackFuture extends CompletableFuture<Void> { @NonNull - private final CompletableFuture<Void> mResult = new CompletableFuture<>(); + public RemoteCallback createCallback() { + return new RemoteCallback(result -> { + boolean successful = result != null; + if (successful) { + complete(null); + } else { + completeExceptionally(new RuntimeException("Failed")); + } + }); + } public int waitForResult() { try { - mResult.get(5, TimeUnit.SECONDS); + get(5, TimeUnit.SECONDS); return 0; } catch (Exception e) { getErrPrintWriter().println("Error: see logcat for details.\n" @@ -53,16 +62,6 @@ class RoleManagerShellCommand extends ShellCommand { return -1; } } - - @Override - public void onSuccess() { - mResult.complete(null); - } - - @Override - public void onFailure() { - mResult.completeExceptionally(new RuntimeException("Failed")); - } } @Override @@ -112,9 +111,10 @@ class RoleManagerShellCommand extends ShellCommand { String packageName = getNextArgRequired(); int flags = getFlagsMaybe(); - Callback callback = new Callback(); - mRoleManager.addRoleHolderAsUser(roleName, packageName, flags, userId, callback); - return callback.waitForResult(); + CallbackFuture future = new CallbackFuture(); + mRoleManager.addRoleHolderAsUser(roleName, packageName, flags, userId, + future.createCallback()); + return future.waitForResult(); } private int runRemoveRoleHolder() throws RemoteException { @@ -123,9 +123,10 @@ class RoleManagerShellCommand extends ShellCommand { String packageName = getNextArgRequired(); int flags = getFlagsMaybe(); - Callback callback = new Callback(); - mRoleManager.removeRoleHolderAsUser(roleName, packageName, flags, userId, callback); - return callback.waitForResult(); + CallbackFuture future = new CallbackFuture(); + mRoleManager.removeRoleHolderAsUser(roleName, packageName, flags, userId, + future.createCallback()); + return future.waitForResult(); } private int runClearRoleHolders() throws RemoteException { @@ -133,9 +134,9 @@ class RoleManagerShellCommand extends ShellCommand { String roleName = getNextArgRequired(); int flags = getFlagsMaybe(); - Callback callback = new Callback(); - mRoleManager.clearRoleHoldersAsUser(roleName, flags, userId, callback); - return callback.waitForResult(); + CallbackFuture future = new CallbackFuture(); + mRoleManager.clearRoleHoldersAsUser(roleName, flags, userId, future.createCallback()); + return future.waitForResult(); } @Override diff --git a/telecomm/java/android/telecom/DefaultDialerManager.java b/telecomm/java/android/telecom/DefaultDialerManager.java index e43b2b715321..5b806a6e57da 100644 --- a/telecomm/java/android/telecom/DefaultDialerManager.java +++ b/telecomm/java/android/telecom/DefaultDialerManager.java @@ -16,7 +16,6 @@ package android.telecom; import android.app.ActivityManager; import android.app.role.RoleManager; -import android.app.role.RoleManagerCallback; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; @@ -34,9 +33,11 @@ import com.android.internal.util.CollectionUtils; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import java.util.function.Consumer; /** * Class for managing the default dialer application that will receive incoming calls, and be @@ -75,11 +76,18 @@ public class DefaultDialerManager { int user) { long identity = Binder.clearCallingIdentity(); try { - RoleManagerCallback.Future cb = new RoleManagerCallback.Future(); + CompletableFuture<Void> future = new CompletableFuture<>(); + Consumer<Boolean> callback = successful -> { + if (successful) { + future.complete(null); + } else { + future.completeExceptionally(new RuntimeException()); + } + }; context.getSystemService(RoleManager.class).addRoleHolderAsUser( RoleManager.ROLE_DIALER, packageName, 0, UserHandle.of(user), - AsyncTask.THREAD_POOL_EXECUTOR, cb); - cb.get(5, TimeUnit.SECONDS); + AsyncTask.THREAD_POOL_EXECUTOR, callback); + future.get(5, TimeUnit.SECONDS); return true; } catch (InterruptedException | ExecutionException | TimeoutException e) { Slog.e(TAG, "Failed to set default dialer to " + packageName + " for user " + user, e); diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index 7688ac6857af..25758407e7d8 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -25,7 +25,6 @@ import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; -import android.app.role.RoleManagerCallback; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -1221,8 +1220,8 @@ public class TelecomManager { * * @hide * @deprecated Use - * {@link android.app.role.RoleManager#addRoleHolderAsUser(String, String, UserHandle, Executor, - * RoleManagerCallback)} instead. + * {@link android.app.role.RoleManager#addRoleHolderAsUser(String, String, int, UserHandle, + * Executor, java.util.function.Consumer)} instead. */ @SystemApi @Deprecated diff --git a/telephony/java/com/android/internal/telephony/SmsApplication.java b/telephony/java/com/android/internal/telephony/SmsApplication.java index 7478a00009c0..ef7c60545ba0 100644 --- a/telephony/java/com/android/internal/telephony/SmsApplication.java +++ b/telephony/java/com/android/internal/telephony/SmsApplication.java @@ -19,7 +19,6 @@ package com.android.internal.telephony; import android.Manifest.permission; import android.app.AppOpsManager; import android.app.role.RoleManager; -import android.app.role.RoleManagerCallback; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -51,9 +50,11 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import java.util.Collection; import java.util.HashMap; import java.util.List; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import java.util.function.Consumer; /** * Class for managing the primary application that we will deliver SMS/MMS messages to @@ -634,12 +635,19 @@ public final class SmsApplication { } // Update the setting. - RoleManagerCallback.Future res = new RoleManagerCallback.Future(); + CompletableFuture<Void> future = new CompletableFuture<>(); + Consumer<Boolean> callback = successful -> { + if (successful) { + future.complete(null); + } else { + future.completeExceptionally(new RuntimeException()); + } + }; context.getSystemService(RoleManager.class).addRoleHolderAsUser( RoleManager.ROLE_SMS, applicationData.mPackageName, 0, UserHandle.of(userId), - AsyncTask.THREAD_POOL_EXECUTOR, res); + AsyncTask.THREAD_POOL_EXECUTOR, callback); try { - res.get(5, TimeUnit.SECONDS); + future.get(5, TimeUnit.SECONDS); } catch (InterruptedException | ExecutionException | TimeoutException e) { Log.e(LOG_TAG, "Exception while adding sms role holder " + applicationData, e); return; |