Loading core/java/android/permission/RuntimePermissionPresenter.java +168 −153 Original line number Original line Diff line number Diff line Loading @@ -16,27 +16,28 @@ package android.permission; package android.permission; import static android.permission.RuntimePermissionPresenterService.SERVICE_INTERFACE; import static com.android.internal.util.Preconditions.checkCollectionElementsNotNull; import static com.android.internal.util.Preconditions.checkCollectionElementsNotNull; import static com.android.internal.util.Preconditions.checkNotNull; import static com.android.internal.util.Preconditions.checkNotNull; import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.content.ComponentName; import android.content.ComponentName; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.Intent; import android.content.ServiceConnection; import android.content.pm.ResolveInfo; import android.os.Handler; import android.os.Handler; import android.os.IBinder; import android.os.IBinder; import android.os.Message; import android.os.RemoteCallback; import android.os.RemoteCallback; import android.os.RemoteException; import android.os.RemoteException; import android.os.UserHandle; import android.util.Log; import android.util.Log; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.function.pooled.PooledLambda; import com.android.internal.infra.AbstractMultiplePendingRequestsRemoteService; import com.android.internal.infra.AbstractRemoteService; import java.util.ArrayList; import java.util.Collections; import java.util.Collections; import java.util.List; import java.util.List; Loading Loading @@ -80,7 +81,7 @@ public final class RuntimePermissionPresenter { */ */ public interface OnCountPermissionAppsResultCallback { public interface OnCountPermissionAppsResultCallback { /** /** * The result for {@link #countPermissionApps(List, boolean, * The result for {@link #countPermissionApps(List, boolean, boolean, * OnCountPermissionAppsResultCallback, Handler)}. * OnCountPermissionAppsResultCallback, Handler)}. * * * @param numApps The number of apps that have one of the permissions * @param numApps The number of apps that have one of the permissions Loading Loading @@ -110,8 +111,13 @@ public final class RuntimePermissionPresenter { } } } } private RuntimePermissionPresenter(Context context) { private RuntimePermissionPresenter(@NonNull Context context) { mRemoteService = new RemoteService(context); Intent intent = new Intent(SERVICE_INTERFACE); intent.setPackage(context.getPackageManager().getPermissionControllerPackageName()); ResolveInfo serviceInfo = context.getPackageManager().resolveService(intent, 0); mRemoteService = new RemoteService(context, serviceInfo.getComponentInfo().getComponentName()); } } /** /** Loading @@ -126,8 +132,8 @@ public final class RuntimePermissionPresenter { checkNotNull(packageName); checkNotNull(packageName); checkNotNull(callback); checkNotNull(callback); mRemoteService.processMessage(obtainMessage(RemoteService::getAppPermissions, mRemoteService.scheduleRequest(new PendingGetAppPermissionRequest(mRemoteService, mRemoteService, packageName, callback, handler)); packageName, callback, handler == null ? mRemoteService.getHandler() : handler)); } } /** /** Loading @@ -141,8 +147,8 @@ public final class RuntimePermissionPresenter { checkNotNull(packageName); checkNotNull(packageName); checkNotNull(permissionName); checkNotNull(permissionName); mRemoteService.processMessage(obtainMessage(RemoteService::revokeAppPermissions, mRemoteService.scheduleAsyncRequest(new PendingRevokeAppPermissionRequest(packageName, mRemoteService, packageName, permissionName)); permissionName)); } } /** /** Loading @@ -160,76 +166,87 @@ public final class RuntimePermissionPresenter { checkCollectionElementsNotNull(permissionNames, "permissionNames"); checkCollectionElementsNotNull(permissionNames, "permissionNames"); checkNotNull(callback); checkNotNull(callback); mRemoteService.processMessage(obtainMessage(RemoteService::countPermissionApps, mRemoteService.scheduleRequest(new PendingCountPermissionAppsRequest(mRemoteService, mRemoteService, permissionNames, countOnlyGranted, countSystem, callback, handler)); permissionNames, countOnlyGranted, countSystem, callback, handler == null ? mRemoteService.getHandler() : handler)); } } private static final class RemoteService /** extends Handler implements ServiceConnection { * A connection to the remote service */ static final class RemoteService extends AbstractMultiplePendingRequestsRemoteService<RemoteService, IRuntimePermissionPresenter> { private static final long UNBIND_TIMEOUT_MILLIS = 10000; private static final long UNBIND_TIMEOUT_MILLIS = 10000; private static final long MESSAGE_TIMEOUT_MILLIS = 30000; public static final int MSG_UNBIND = 0; /** * Create a connection to the remote service private final Object mLock = new Object(); * * @param context A context to use private final Context mContext; * @param componentName The component of the service to connect to */ @GuardedBy("mLock") RemoteService(@NonNull Context context, @NonNull ComponentName componentName) { private final List<Message> mPendingWork = new ArrayList<>(); super(context, SERVICE_INTERFACE, componentName, UserHandle.myUserId(), service -> Log.e(TAG, "RuntimePermPresenterService " + service + " died"), @GuardedBy("mLock") false, false, 1); private IRuntimePermissionPresenter mRemoteInstance; @GuardedBy("mLock") private boolean mBound; RemoteService(Context context) { super(context.getMainLooper(), null, false); mContext = context; } } public void processMessage(Message message) { /** synchronized (mLock) { * @return The default handler used by this service. if (!mBound) { */ Intent intent = new Intent( Handler getHandler() { RuntimePermissionPresenterService.SERVICE_INTERFACE); return mHandler; intent.setPackage(mContext.getPackageManager() .getPermissionControllerPackageName()); mBound = mContext.bindService(intent, this, Context.BIND_AUTO_CREATE); } mPendingWork.add(message); scheduleNextMessageIfNeededLocked(); } } } @Override @Override public void onServiceConnected(ComponentName name, IBinder service) { protected @NonNull IRuntimePermissionPresenter getServiceInterface( synchronized (mLock) { @NonNull IBinder binder) { mRemoteInstance = IRuntimePermissionPresenter.Stub.asInterface(service); return IRuntimePermissionPresenter.Stub.asInterface(binder); scheduleNextMessageIfNeededLocked(); } } @Override protected long getTimeoutIdleBindMillis() { return UNBIND_TIMEOUT_MILLIS; } } @Override @Override public void onServiceDisconnected(ComponentName name) { protected long getRemoteRequestMillis() { synchronized (mLock) { return MESSAGE_TIMEOUT_MILLIS; mRemoteInstance = null; } } @Override public void scheduleRequest(@NonNull PendingRequest<RemoteService, IRuntimePermissionPresenter> pendingRequest) { super.scheduleRequest(pendingRequest); } } private void getAppPermissions(@NonNull String packageName, @Override @NonNull OnGetAppPermissionResultCallback callback, @Nullable Handler handler) { public void scheduleAsyncRequest( final IRuntimePermissionPresenter remoteInstance; @NonNull AsyncRequest<IRuntimePermissionPresenter> request) { synchronized (mLock) { super.scheduleAsyncRequest(request); remoteInstance = mRemoteInstance; } } if (remoteInstance == null) { return; } } try { remoteInstance.getAppPermissions(packageName, /** new RemoteCallback(result -> { * Request for {@link #getAppPermissions} */ private static final class PendingGetAppPermissionRequest extends AbstractRemoteService.PendingRequest<RemoteService, IRuntimePermissionPresenter> { private final @NonNull String mPackageName; private final @NonNull OnGetAppPermissionResultCallback mCallback; private final @NonNull RemoteCallback mRemoteCallback; private PendingGetAppPermissionRequest(@NonNull RemoteService service, @NonNull String packageName, @NonNull OnGetAppPermissionResultCallback callback, @NonNull Handler handler) { super(service); mPackageName = packageName; mCallback = callback; mRemoteCallback = new RemoteCallback(result -> { final List<RuntimePermissionPresentationInfo> reportedPermissions; final List<RuntimePermissionPresentationInfo> reportedPermissions; List<RuntimePermissionPresentationInfo> permissions = null; List<RuntimePermissionPresentationInfo> permissions = null; if (result != null) { if (result != null) { Loading @@ -239,58 +256,76 @@ public final class RuntimePermissionPresenter { permissions = Collections.emptyList(); permissions = Collections.emptyList(); } } reportedPermissions = permissions; reportedPermissions = permissions; if (handler != null) { handler.post( () -> callback.onGetAppPermissions(reportedPermissions)); } else { callback.onGetAppPermissions(reportedPermissions); callback.onGetAppPermissions(reportedPermissions); } }, this)); } catch (RemoteException re) { Log.e(TAG, "Error getting app permissions", re); } scheduleUnbind(); synchronized (mLock) { finish(); scheduleNextMessageIfNeededLocked(); }, handler); } } } private void revokeAppPermissions(@NonNull String packageName, @Override @NonNull String permissionName) { protected void onTimeout(RemoteService remoteService) { final IRuntimePermissionPresenter remoteInstance; mCallback.onGetAppPermissions(Collections.emptyList()); synchronized (mLock) { remoteInstance = mRemoteInstance; } if (remoteInstance == null) { return; } } @Override public void run() { try { try { remoteInstance.revokeRuntimePermission(packageName, permissionName); getService().getServiceInterface().getAppPermissions(mPackageName, mRemoteCallback); } catch (RemoteException re) { } catch (RemoteException e) { Log.e(TAG, "Error getting app permissions", re); Log.e(TAG, "Error getting app permission", e); } } synchronized (mLock) { scheduleNextMessageIfNeededLocked(); } } } } private void countPermissionApps(@NonNull List<String> permissionNames, /** boolean countOnlyGranted, boolean countSystem, * Request for {@link #revokeRuntimePermission} @NonNull OnCountPermissionAppsResultCallback callback, @Nullable Handler handler) { */ final IRuntimePermissionPresenter remoteInstance; private static final class PendingRevokeAppPermissionRequest implements AbstractRemoteService.AsyncRequest<IRuntimePermissionPresenter> { private final @NonNull String mPackageName; private final @NonNull String mPermissionName; synchronized (mLock) { private PendingRevokeAppPermissionRequest(@NonNull String packageName, remoteInstance = mRemoteInstance; @NonNull String permissionName) { } mPackageName = packageName; if (remoteInstance == null) { mPermissionName = permissionName; return; } } @Override public void run(IRuntimePermissionPresenter remoteInterface) { try { try { remoteInstance.countPermissionApps(permissionNames, countOnlyGranted, countSystem, remoteInterface.revokeRuntimePermission(mPackageName, mPermissionName); new RemoteCallback(result -> { } catch (RemoteException e) { Log.e(TAG, "Error revoking app permission", e); } } } /** * Request for {@link #countPermissionApps} */ private static final class PendingCountPermissionAppsRequest extends AbstractRemoteService.PendingRequest<RemoteService, IRuntimePermissionPresenter> { private final @NonNull List<String> mPermissionNames; private final @NonNull OnCountPermissionAppsResultCallback mCallback; private final boolean mCountOnlyGranted; private final boolean mCountSystem; private final @NonNull RemoteCallback mRemoteCallback; private PendingCountPermissionAppsRequest(@NonNull RemoteService service, @NonNull List<String> permissionNames, boolean countOnlyGranted, boolean countSystem, @NonNull OnCountPermissionAppsResultCallback callback, @NonNull Handler handler) { super(service); mPermissionNames = permissionNames; mCountOnlyGranted = countOnlyGranted; mCountSystem = countSystem; mCallback = callback; mRemoteCallback = new RemoteCallback(result -> { final int numApps; final int numApps; if (result != null) { if (result != null) { numApps = result.getInt(KEY_RESULT); numApps = result.getInt(KEY_RESULT); Loading @@ -298,45 +333,25 @@ public final class RuntimePermissionPresenter { numApps = 0; numApps = 0; } } if (handler != null) { handler.post(() -> callback.onCountPermissionApps(numApps)); } else { callback.onCountPermissionApps(numApps); callback.onCountPermissionApps(numApps); } }, this)); } catch (RemoteException re) { Log.e(TAG, "Error counting permission apps", re); } scheduleUnbind(); synchronized (mLock) { finish(); scheduleNextMessageIfNeededLocked(); }, handler); } } } private void unbind() { @Override synchronized (mLock) { protected void onTimeout(RemoteService remoteService) { if (mBound) { mCallback.onCountPermissionApps(0); mContext.unbindService(this); mBound = false; } mRemoteInstance = null; } } } @GuardedBy("mLock") @Override private void scheduleNextMessageIfNeededLocked() { public void run() { if (mBound && mRemoteInstance != null && !mPendingWork.isEmpty()) { try { Message nextMessage = mPendingWork.remove(0); getService().getServiceInterface().countPermissionApps(mPermissionNames, sendMessage(nextMessage); mCountOnlyGranted, mCountSystem, mRemoteCallback); } } catch (RemoteException e) { Log.e(TAG, "Error counting permission apps", e); } } private void scheduleUnbind() { removeMessages(MSG_UNBIND); sendMessageDelayed(PooledLambda.obtainMessage(RemoteService::unbind, this) .setWhat(MSG_UNBIND), UNBIND_TIMEOUT_MILLIS); } } } } } } core/java/com/android/internal/infra/AbstractRemoteService.java +10 −0 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.internal.infra; import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.ComponentName; import android.content.ComponentName; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.Intent; Loading Loading @@ -164,6 +165,15 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I */ */ protected abstract long getRemoteRequestMillis(); protected abstract long getRemoteRequestMillis(); /** * Gets the currently registered service interface or {@code null} if the service is not * connected. */ @Nullable public final I getServiceInterface() { return mService; } private void handleDestroy() { private void handleDestroy() { if (checkIfDestroyed()) return; if (checkIfDestroyed()) return; handleOnDestroy(); handleOnDestroy(); Loading Loading
core/java/android/permission/RuntimePermissionPresenter.java +168 −153 Original line number Original line Diff line number Diff line Loading @@ -16,27 +16,28 @@ package android.permission; package android.permission; import static android.permission.RuntimePermissionPresenterService.SERVICE_INTERFACE; import static com.android.internal.util.Preconditions.checkCollectionElementsNotNull; import static com.android.internal.util.Preconditions.checkCollectionElementsNotNull; import static com.android.internal.util.Preconditions.checkNotNull; import static com.android.internal.util.Preconditions.checkNotNull; import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.content.ComponentName; import android.content.ComponentName; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.Intent; import android.content.ServiceConnection; import android.content.pm.ResolveInfo; import android.os.Handler; import android.os.Handler; import android.os.IBinder; import android.os.IBinder; import android.os.Message; import android.os.RemoteCallback; import android.os.RemoteCallback; import android.os.RemoteException; import android.os.RemoteException; import android.os.UserHandle; import android.util.Log; import android.util.Log; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.function.pooled.PooledLambda; import com.android.internal.infra.AbstractMultiplePendingRequestsRemoteService; import com.android.internal.infra.AbstractRemoteService; import java.util.ArrayList; import java.util.Collections; import java.util.Collections; import java.util.List; import java.util.List; Loading Loading @@ -80,7 +81,7 @@ public final class RuntimePermissionPresenter { */ */ public interface OnCountPermissionAppsResultCallback { public interface OnCountPermissionAppsResultCallback { /** /** * The result for {@link #countPermissionApps(List, boolean, * The result for {@link #countPermissionApps(List, boolean, boolean, * OnCountPermissionAppsResultCallback, Handler)}. * OnCountPermissionAppsResultCallback, Handler)}. * * * @param numApps The number of apps that have one of the permissions * @param numApps The number of apps that have one of the permissions Loading Loading @@ -110,8 +111,13 @@ public final class RuntimePermissionPresenter { } } } } private RuntimePermissionPresenter(Context context) { private RuntimePermissionPresenter(@NonNull Context context) { mRemoteService = new RemoteService(context); Intent intent = new Intent(SERVICE_INTERFACE); intent.setPackage(context.getPackageManager().getPermissionControllerPackageName()); ResolveInfo serviceInfo = context.getPackageManager().resolveService(intent, 0); mRemoteService = new RemoteService(context, serviceInfo.getComponentInfo().getComponentName()); } } /** /** Loading @@ -126,8 +132,8 @@ public final class RuntimePermissionPresenter { checkNotNull(packageName); checkNotNull(packageName); checkNotNull(callback); checkNotNull(callback); mRemoteService.processMessage(obtainMessage(RemoteService::getAppPermissions, mRemoteService.scheduleRequest(new PendingGetAppPermissionRequest(mRemoteService, mRemoteService, packageName, callback, handler)); packageName, callback, handler == null ? mRemoteService.getHandler() : handler)); } } /** /** Loading @@ -141,8 +147,8 @@ public final class RuntimePermissionPresenter { checkNotNull(packageName); checkNotNull(packageName); checkNotNull(permissionName); checkNotNull(permissionName); mRemoteService.processMessage(obtainMessage(RemoteService::revokeAppPermissions, mRemoteService.scheduleAsyncRequest(new PendingRevokeAppPermissionRequest(packageName, mRemoteService, packageName, permissionName)); permissionName)); } } /** /** Loading @@ -160,76 +166,87 @@ public final class RuntimePermissionPresenter { checkCollectionElementsNotNull(permissionNames, "permissionNames"); checkCollectionElementsNotNull(permissionNames, "permissionNames"); checkNotNull(callback); checkNotNull(callback); mRemoteService.processMessage(obtainMessage(RemoteService::countPermissionApps, mRemoteService.scheduleRequest(new PendingCountPermissionAppsRequest(mRemoteService, mRemoteService, permissionNames, countOnlyGranted, countSystem, callback, handler)); permissionNames, countOnlyGranted, countSystem, callback, handler == null ? mRemoteService.getHandler() : handler)); } } private static final class RemoteService /** extends Handler implements ServiceConnection { * A connection to the remote service */ static final class RemoteService extends AbstractMultiplePendingRequestsRemoteService<RemoteService, IRuntimePermissionPresenter> { private static final long UNBIND_TIMEOUT_MILLIS = 10000; private static final long UNBIND_TIMEOUT_MILLIS = 10000; private static final long MESSAGE_TIMEOUT_MILLIS = 30000; public static final int MSG_UNBIND = 0; /** * Create a connection to the remote service private final Object mLock = new Object(); * * @param context A context to use private final Context mContext; * @param componentName The component of the service to connect to */ @GuardedBy("mLock") RemoteService(@NonNull Context context, @NonNull ComponentName componentName) { private final List<Message> mPendingWork = new ArrayList<>(); super(context, SERVICE_INTERFACE, componentName, UserHandle.myUserId(), service -> Log.e(TAG, "RuntimePermPresenterService " + service + " died"), @GuardedBy("mLock") false, false, 1); private IRuntimePermissionPresenter mRemoteInstance; @GuardedBy("mLock") private boolean mBound; RemoteService(Context context) { super(context.getMainLooper(), null, false); mContext = context; } } public void processMessage(Message message) { /** synchronized (mLock) { * @return The default handler used by this service. if (!mBound) { */ Intent intent = new Intent( Handler getHandler() { RuntimePermissionPresenterService.SERVICE_INTERFACE); return mHandler; intent.setPackage(mContext.getPackageManager() .getPermissionControllerPackageName()); mBound = mContext.bindService(intent, this, Context.BIND_AUTO_CREATE); } mPendingWork.add(message); scheduleNextMessageIfNeededLocked(); } } } @Override @Override public void onServiceConnected(ComponentName name, IBinder service) { protected @NonNull IRuntimePermissionPresenter getServiceInterface( synchronized (mLock) { @NonNull IBinder binder) { mRemoteInstance = IRuntimePermissionPresenter.Stub.asInterface(service); return IRuntimePermissionPresenter.Stub.asInterface(binder); scheduleNextMessageIfNeededLocked(); } } @Override protected long getTimeoutIdleBindMillis() { return UNBIND_TIMEOUT_MILLIS; } } @Override @Override public void onServiceDisconnected(ComponentName name) { protected long getRemoteRequestMillis() { synchronized (mLock) { return MESSAGE_TIMEOUT_MILLIS; mRemoteInstance = null; } } @Override public void scheduleRequest(@NonNull PendingRequest<RemoteService, IRuntimePermissionPresenter> pendingRequest) { super.scheduleRequest(pendingRequest); } } private void getAppPermissions(@NonNull String packageName, @Override @NonNull OnGetAppPermissionResultCallback callback, @Nullable Handler handler) { public void scheduleAsyncRequest( final IRuntimePermissionPresenter remoteInstance; @NonNull AsyncRequest<IRuntimePermissionPresenter> request) { synchronized (mLock) { super.scheduleAsyncRequest(request); remoteInstance = mRemoteInstance; } } if (remoteInstance == null) { return; } } try { remoteInstance.getAppPermissions(packageName, /** new RemoteCallback(result -> { * Request for {@link #getAppPermissions} */ private static final class PendingGetAppPermissionRequest extends AbstractRemoteService.PendingRequest<RemoteService, IRuntimePermissionPresenter> { private final @NonNull String mPackageName; private final @NonNull OnGetAppPermissionResultCallback mCallback; private final @NonNull RemoteCallback mRemoteCallback; private PendingGetAppPermissionRequest(@NonNull RemoteService service, @NonNull String packageName, @NonNull OnGetAppPermissionResultCallback callback, @NonNull Handler handler) { super(service); mPackageName = packageName; mCallback = callback; mRemoteCallback = new RemoteCallback(result -> { final List<RuntimePermissionPresentationInfo> reportedPermissions; final List<RuntimePermissionPresentationInfo> reportedPermissions; List<RuntimePermissionPresentationInfo> permissions = null; List<RuntimePermissionPresentationInfo> permissions = null; if (result != null) { if (result != null) { Loading @@ -239,58 +256,76 @@ public final class RuntimePermissionPresenter { permissions = Collections.emptyList(); permissions = Collections.emptyList(); } } reportedPermissions = permissions; reportedPermissions = permissions; if (handler != null) { handler.post( () -> callback.onGetAppPermissions(reportedPermissions)); } else { callback.onGetAppPermissions(reportedPermissions); callback.onGetAppPermissions(reportedPermissions); } }, this)); } catch (RemoteException re) { Log.e(TAG, "Error getting app permissions", re); } scheduleUnbind(); synchronized (mLock) { finish(); scheduleNextMessageIfNeededLocked(); }, handler); } } } private void revokeAppPermissions(@NonNull String packageName, @Override @NonNull String permissionName) { protected void onTimeout(RemoteService remoteService) { final IRuntimePermissionPresenter remoteInstance; mCallback.onGetAppPermissions(Collections.emptyList()); synchronized (mLock) { remoteInstance = mRemoteInstance; } if (remoteInstance == null) { return; } } @Override public void run() { try { try { remoteInstance.revokeRuntimePermission(packageName, permissionName); getService().getServiceInterface().getAppPermissions(mPackageName, mRemoteCallback); } catch (RemoteException re) { } catch (RemoteException e) { Log.e(TAG, "Error getting app permissions", re); Log.e(TAG, "Error getting app permission", e); } } synchronized (mLock) { scheduleNextMessageIfNeededLocked(); } } } } private void countPermissionApps(@NonNull List<String> permissionNames, /** boolean countOnlyGranted, boolean countSystem, * Request for {@link #revokeRuntimePermission} @NonNull OnCountPermissionAppsResultCallback callback, @Nullable Handler handler) { */ final IRuntimePermissionPresenter remoteInstance; private static final class PendingRevokeAppPermissionRequest implements AbstractRemoteService.AsyncRequest<IRuntimePermissionPresenter> { private final @NonNull String mPackageName; private final @NonNull String mPermissionName; synchronized (mLock) { private PendingRevokeAppPermissionRequest(@NonNull String packageName, remoteInstance = mRemoteInstance; @NonNull String permissionName) { } mPackageName = packageName; if (remoteInstance == null) { mPermissionName = permissionName; return; } } @Override public void run(IRuntimePermissionPresenter remoteInterface) { try { try { remoteInstance.countPermissionApps(permissionNames, countOnlyGranted, countSystem, remoteInterface.revokeRuntimePermission(mPackageName, mPermissionName); new RemoteCallback(result -> { } catch (RemoteException e) { Log.e(TAG, "Error revoking app permission", e); } } } /** * Request for {@link #countPermissionApps} */ private static final class PendingCountPermissionAppsRequest extends AbstractRemoteService.PendingRequest<RemoteService, IRuntimePermissionPresenter> { private final @NonNull List<String> mPermissionNames; private final @NonNull OnCountPermissionAppsResultCallback mCallback; private final boolean mCountOnlyGranted; private final boolean mCountSystem; private final @NonNull RemoteCallback mRemoteCallback; private PendingCountPermissionAppsRequest(@NonNull RemoteService service, @NonNull List<String> permissionNames, boolean countOnlyGranted, boolean countSystem, @NonNull OnCountPermissionAppsResultCallback callback, @NonNull Handler handler) { super(service); mPermissionNames = permissionNames; mCountOnlyGranted = countOnlyGranted; mCountSystem = countSystem; mCallback = callback; mRemoteCallback = new RemoteCallback(result -> { final int numApps; final int numApps; if (result != null) { if (result != null) { numApps = result.getInt(KEY_RESULT); numApps = result.getInt(KEY_RESULT); Loading @@ -298,45 +333,25 @@ public final class RuntimePermissionPresenter { numApps = 0; numApps = 0; } } if (handler != null) { handler.post(() -> callback.onCountPermissionApps(numApps)); } else { callback.onCountPermissionApps(numApps); callback.onCountPermissionApps(numApps); } }, this)); } catch (RemoteException re) { Log.e(TAG, "Error counting permission apps", re); } scheduleUnbind(); synchronized (mLock) { finish(); scheduleNextMessageIfNeededLocked(); }, handler); } } } private void unbind() { @Override synchronized (mLock) { protected void onTimeout(RemoteService remoteService) { if (mBound) { mCallback.onCountPermissionApps(0); mContext.unbindService(this); mBound = false; } mRemoteInstance = null; } } } @GuardedBy("mLock") @Override private void scheduleNextMessageIfNeededLocked() { public void run() { if (mBound && mRemoteInstance != null && !mPendingWork.isEmpty()) { try { Message nextMessage = mPendingWork.remove(0); getService().getServiceInterface().countPermissionApps(mPermissionNames, sendMessage(nextMessage); mCountOnlyGranted, mCountSystem, mRemoteCallback); } } catch (RemoteException e) { Log.e(TAG, "Error counting permission apps", e); } } private void scheduleUnbind() { removeMessages(MSG_UNBIND); sendMessageDelayed(PooledLambda.obtainMessage(RemoteService::unbind, this) .setWhat(MSG_UNBIND), UNBIND_TIMEOUT_MILLIS); } } } } } }
core/java/com/android/internal/infra/AbstractRemoteService.java +10 −0 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.internal.infra; import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.ComponentName; import android.content.ComponentName; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.Intent; Loading Loading @@ -164,6 +165,15 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I */ */ protected abstract long getRemoteRequestMillis(); protected abstract long getRemoteRequestMillis(); /** * Gets the currently registered service interface or {@code null} if the service is not * connected. */ @Nullable public final I getServiceInterface() { return mService; } private void handleDestroy() { private void handleDestroy() { if (checkIfDestroyed()) return; if (checkIfDestroyed()) return; handleOnDestroy(); handleOnDestroy(); Loading