Loading services/core/java/com/android/server/am/PersistentConnection.java +20 −3 Original line number Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * Copyright (C) 2025 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. Loading Loading @@ -38,8 +38,6 @@ import java.io.PrintWriter; * - Call {@link #bind()} to create a connection. * - Call {@link #unbind()} to disconnect. Make sure to disconnect when the user stops. * * Add onConnected/onDisconnected callbacks as needed. * * When the target process gets killed (by OOM-killer, etc), then the activity manager will * re-connect the connection automatically, in which case onServiceDisconnected() gets called * and then onServiceConnected(). Loading Loading @@ -138,6 +136,7 @@ public abstract class PersistentConnection<T> { scheduleStableCheckLocked(); } onConnected(mService); } @Override Loading @@ -153,6 +152,7 @@ public abstract class PersistentConnection<T> { // Note we won't increase the rebind timeout here, because we don't explicitly // rebind in this case. } onDisconnected(); } @Override Loading @@ -173,6 +173,7 @@ public abstract class PersistentConnection<T> { scheduleRebindLocked(); } onDisconnected(); } }; Loading Loading @@ -206,6 +207,22 @@ public abstract class PersistentConnection<T> { protected abstract int getBindFlags(); /** * Called when the service is successfully connected. * * <p>Note: This method is called without holding {@link #mLock}. * * @param service The interface to the connected service. */ protected void onConnected(@NonNull T service) {} /** * Called when the service is disconnected or the binding dies. * * <p>Note: This method is called without holding {@link #mLock}. */ protected void onDisconnected() {} /** * @return whether {@link #bind()} has been called and {@link #unbind()} hasn't. * Loading services/core/java/com/android/server/appbinding/AppBindingService.java +26 −7 Original line number Diff line number Diff line Loading @@ -143,7 +143,15 @@ public class AppBindingService extends Binder { } } /** Get the list of services bound to a specific finder class. */ /** * Get the list of services bound to a specific finder class. * * This method will block until all connections are established or a timeout occurs. * * <p><b>NOTE: This method should be called from a background thread other than * {@link BackgroundThread}, otherwise the {@link PersistentConnection} callbacks will not be * delivered until after this method returns.</b></p> */ public List<AppServiceConnection> getAppServiceConnections( Class<? extends AppServiceFinder<?, ?>> appServiceFinderClass, int userId) { List<AppServiceConnection> serviceConnections = new ArrayList<>(); Loading @@ -153,15 +161,21 @@ public class AppBindingService extends Binder { if (app.getClass() != appServiceFinderClass) { continue; } serviceConnections.addAll(getBoundConnectionsLocked(userId, app)); serviceConnections.addAll(getBoundConnectionsBlockingLocked(userId, app)); } } return serviceConnections; } /** Get the connection bound to a specific finder. If the connection does not * already exist, create one. */ private List<AppServiceConnection> getBoundConnectionsLocked(int userId, AppServiceFinder app) { /** * Get the connection bound to a specific finder, ensuring it's bound. * * This method will block until all connections are established or a timeout occurs. * * <p><b>NOTE: This method must be called from a background thread.</b></p> */ private List<AppServiceConnection> getBoundConnectionsBlockingLocked(int userId, AppServiceFinder app) { Set<String> targetPackages = app.getTargetPackages(userId); List<AppServiceConnection> connections = new ArrayList<>(); for (String targetPackage : targetPackages) { Loading @@ -180,11 +194,16 @@ public class AppBindingService extends Binder { targetPackage, service.getComponentName()); mConnections.add(conn); conn.bind(); } } if (conn != null) { conn.bind(); if (conn.awaitConnection()) { connections.add(conn); } else { Slogf.w(TAG, "Failed to establish connection for %s, user %d, package %s", app.getAppDescription(), userId, targetPackage); } } } return connections; Loading services/core/java/com/android/server/appbinding/AppServiceConnection.java +20 −40 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.server.appbinding; import android.annotation.NonNull; import android.content.ComponentName; import android.content.Context; import android.os.ConditionVariable; import android.os.Handler; import android.os.IBinder; import android.os.IInterface; Loading @@ -27,9 +28,6 @@ import com.android.server.am.PersistentConnection; import com.android.server.appbinding.finders.AppServiceFinder; import com.android.server.utils.Slogf; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; /** * Establishes a persistent connection to a given service component for a given user * Each connection is associated with an AppServiceFinder to facilitate the service exchange if the Loading @@ -40,19 +38,7 @@ public class AppServiceConnection extends PersistentConnection<IInterface> { private final AppBindingConstants mConstants; private final AppServiceFinder mFinder; private final String mPackageName; /** * Listener for connection status updates * TODO: Refactor this (b/423644620) */ public interface ConnectionStatusListener { void onConnected(@NonNull AppServiceConnection connection, @NonNull IInterface service); void onDisconnected(@NonNull AppServiceConnection connection); void onBinderDied(@NonNull AppServiceConnection connection); } private final List<ConnectionStatusListener> mConnectionListeners = new CopyOnWriteArrayList<>(); private final ConditionVariable mConditionVariable = new ConditionVariable(); AppServiceConnection(Context context, int userId, AppBindingConstants constants, Handler handler, AppServiceFinder finder, String packageName, Loading @@ -75,20 +61,22 @@ public class AppServiceConnection extends PersistentConnection<IInterface> { @Override protected IInterface asInterface(IBinder obj) { final IInterface service = mFinder.asInterface(obj); if (service != null) { // Notify all listeners. Slogf.d(TAG, "Service for %s is connected. Notifying %s listeners.", getComponentName(), mConnectionListeners.size()); for (ConnectionStatusListener listener : mConnectionListeners) { listener.onConnected(this, service); } } else { if (service == null) { Slogf.w(TAG, "Service for %s is null.", getComponentName()); } return service; } @Override protected void onConnected(@NonNull IInterface service) { mConditionVariable.open(); } @Override protected void onDisconnected() { mConditionVariable.close(); } public AppServiceFinder getFinder() { return mFinder; } Loading @@ -98,21 +86,13 @@ public class AppServiceConnection extends PersistentConnection<IInterface> { } /** * Adds a listener to be notified of connection changes. * If service is already connected, notify immediately. */ public void addConnectionStatusListener(@NonNull ConnectionStatusListener listener) { mConnectionListeners.add(listener); final IInterface service = getServiceBinder(); if (isConnected() && service != null) { listener.onConnected(this, service); } } /** * Removes an existing listener. * Establishes the service connection and blocks until the service is connected * or a timeout occurs. * * @return true if the service connected successfully within the timeout, false otherwise. */ public void removeConnectionStatusListener(@NonNull ConnectionStatusListener listener) { mConnectionListeners.remove(listener); public boolean awaitConnection() { long timeoutMs = mConstants.SERVICE_RECONNECT_MAX_BACKOFF_SEC * 10 * 1000L; return mConditionVariable.block(timeoutMs) && isConnected(); } } services/supervision/java/com/android/server/supervision/SupervisionService.java +43 −58 Original line number Diff line number Diff line Loading @@ -54,7 +54,6 @@ import android.content.pm.UserInfo; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; import android.os.IInterface; import android.os.PersistableBundle; import android.os.Process; import android.os.RemoteException; Loading @@ -68,6 +67,7 @@ import android.util.SparseArray; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.BackgroundThread; import com.android.internal.util.DumpUtils; import com.android.internal.util.FunctionalUtils.RemoteExceptionIgnoringConsumer; import com.android.internal.util.IndentingPrintWriter; Loading @@ -82,6 +82,7 @@ import com.android.server.utils.Slogf; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.concurrent.Executor; Loading Loading @@ -387,8 +388,7 @@ public class SupervisionService extends ISupervisionManager.Stub { mSupervisionSettings.saveUserData(); } } Binder.withCleanCallingIdentity( () -> { BackgroundThread.getExecutor().execute(() -> { updateWebContentFilters(userId, enabled); dispatchSupervisionEvent( userId, listener -> listener.onSetSupervisionEnabled(userId, enabled)); Loading Loading @@ -420,10 +420,8 @@ public class SupervisionService extends ISupervisionManager.Stub { if (binder == null) { Slogf.d( SupervisionLog.TAG, "Failed to bind to SupervisionAppService for %s now", "Failed to bind to SupervisionAppService for %s", targetPackage); dispatchSupervisionAppServiceWhenConnected(conn, action); continue; } Loading @@ -436,10 +434,10 @@ public class SupervisionService extends ISupervisionManager.Stub { private void dispatchSupervisionEvent( @UserIdInt int userId, @NonNull RemoteExceptionIgnoringConsumer<ISupervisionListener> action) { ArrayList<ISupervisionListener> listeners = new ArrayList<>(); // Add SupervisionAppServices listeners before the platform listeners. listeners.addAll(getSupervisionAppServiceListeners(userId, action)); ArrayList<ISupervisionListener> listeners = new ArrayList<>( getSupervisionAppServiceListeners(userId, action)); synchronized (getLockObject()) { mSupervisionListeners.forEach( Loading @@ -450,7 +448,7 @@ public class SupervisionService extends ISupervisionManager.Stub { }); } listeners.forEach(listener -> action.accept(listener)); listeners.forEach(action); } private void clearAllDevicePoliciesAndSuspendedPackages(@UserIdInt int userId) { Loading @@ -459,20 +457,19 @@ public class SupervisionService extends ISupervisionManager.Stub { } enforcePermission(MANAGE_ROLE_HOLDERS); List<String> supervisionPackages = new ArrayList<>(); supervisionPackages.addAll( mInjector.getRoleHoldersAsUser( RoleManager.ROLE_SUPERVISION, UserHandle.of(userId))); supervisionPackages.addAll( mInjector.getRoleHoldersAsUser( RoleManager.ROLE_SYSTEM_SUPERVISION, UserHandle.of(userId))); List<String> roles = Arrays.asList(RoleManager.ROLE_SYSTEM_SUPERVISION, RoleManager.ROLE_SUPERVISION); for (String role : roles) { List<String> supervisionPackages = mInjector.getRoleHoldersAsUser(role, UserHandle.of(userId)); for (String supervisionPackage : supervisionPackages) { clearDevicePoliciesAndSuspendedPackagesFor(userId, supervisionPackage); clearDevicePoliciesAndSuspendedPackagesFor(userId, supervisionPackage, role); } } } private void clearDevicePoliciesAndSuspendedPackagesFor(int userId, String supervisionPackage) { private void clearDevicePoliciesAndSuspendedPackagesFor(int userId, String supervisionPackage, String roleName) { DevicePolicyManagerInternal dpmi = mInjector.getDpmInternal(); if (dpmi != null) { dpmi.removePoliciesForAdmins(supervisionPackage, userId); Loading @@ -482,36 +479,8 @@ public class SupervisionService extends ISupervisionManager.Stub { if (pmi != null) { pmi.unsuspendForSuspendingPackage(supervisionPackage, userId, userId); } } private void dispatchSupervisionAppServiceWhenConnected( AppServiceConnection conn, @NonNull RemoteExceptionIgnoringConsumer<ISupervisionListener> action) { // This listener will be notified when the connection changes. AppServiceConnection.ConnectionStatusListener connectionListener = new AppServiceConnection.ConnectionStatusListener() { @Override public void onConnected( @NonNull AppServiceConnection connection, @NonNull IInterface service) { try { ISupervisionListener binder = (ISupervisionListener) service; Binder.withCleanCallingIdentity(() -> action.accept(binder)); } finally { connection.removeConnectionStatusListener(this); } } @Override public void onDisconnected(@NonNull AppServiceConnection connection) { connection.removeConnectionStatusListener(this); } @Override public void onBinderDied(@NonNull AppServiceConnection connection) { connection.removeConnectionStatusListener(this); } }; conn.addConnectionStatusListener(connectionListener); mInjector.removeRoleHoldersAsUser(roleName, supervisionPackage, UserHandle.of(userId)); } /** Loading Loading @@ -618,13 +587,13 @@ public class SupervisionService extends ISupervisionManager.Stub { static class Injector { public Context context; private DevicePolicyManagerInternal mDpmInternal; private AppBindingService mAppBindingService; private DevicePolicyManagerInternal mDpmInternal; private KeyguardManager mKeyguardManager; private PackageManager mPackageManager; private PackageManagerInternal mPackageManagerInternal; private UserManagerInternal mUserManagerInternal; private RoleManager mRoleManager; private UserManagerInternal mUserManagerInternal; Injector(Context context) { this.context = context; Loading Loading @@ -686,6 +655,22 @@ public class SupervisionService extends ISupervisionManager.Stub { List<String> getRoleHoldersAsUser(String roleName, UserHandle user) { return mRoleManager.getRoleHoldersAsUser(roleName, user); } void removeRoleHoldersAsUser(String roleName, String packageName, UserHandle user) { mRoleManager.removeRoleHolderAsUser( roleName, packageName, 0, user, context.getMainExecutor(), success -> { if (!success) { Slogf.e(SupervisionLog.TAG, "Failed to remove role %s fro %s", packageName, roleName); } }); } } /** Publishes local and binder services and allows the service to act during initialization. */ Loading services/tests/servicestests/src/com/android/server/supervision/SupervisionServiceTest.kt +117 −71 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
services/core/java/com/android/server/am/PersistentConnection.java +20 −3 Original line number Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * Copyright (C) 2025 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. Loading Loading @@ -38,8 +38,6 @@ import java.io.PrintWriter; * - Call {@link #bind()} to create a connection. * - Call {@link #unbind()} to disconnect. Make sure to disconnect when the user stops. * * Add onConnected/onDisconnected callbacks as needed. * * When the target process gets killed (by OOM-killer, etc), then the activity manager will * re-connect the connection automatically, in which case onServiceDisconnected() gets called * and then onServiceConnected(). Loading Loading @@ -138,6 +136,7 @@ public abstract class PersistentConnection<T> { scheduleStableCheckLocked(); } onConnected(mService); } @Override Loading @@ -153,6 +152,7 @@ public abstract class PersistentConnection<T> { // Note we won't increase the rebind timeout here, because we don't explicitly // rebind in this case. } onDisconnected(); } @Override Loading @@ -173,6 +173,7 @@ public abstract class PersistentConnection<T> { scheduleRebindLocked(); } onDisconnected(); } }; Loading Loading @@ -206,6 +207,22 @@ public abstract class PersistentConnection<T> { protected abstract int getBindFlags(); /** * Called when the service is successfully connected. * * <p>Note: This method is called without holding {@link #mLock}. * * @param service The interface to the connected service. */ protected void onConnected(@NonNull T service) {} /** * Called when the service is disconnected or the binding dies. * * <p>Note: This method is called without holding {@link #mLock}. */ protected void onDisconnected() {} /** * @return whether {@link #bind()} has been called and {@link #unbind()} hasn't. * Loading
services/core/java/com/android/server/appbinding/AppBindingService.java +26 −7 Original line number Diff line number Diff line Loading @@ -143,7 +143,15 @@ public class AppBindingService extends Binder { } } /** Get the list of services bound to a specific finder class. */ /** * Get the list of services bound to a specific finder class. * * This method will block until all connections are established or a timeout occurs. * * <p><b>NOTE: This method should be called from a background thread other than * {@link BackgroundThread}, otherwise the {@link PersistentConnection} callbacks will not be * delivered until after this method returns.</b></p> */ public List<AppServiceConnection> getAppServiceConnections( Class<? extends AppServiceFinder<?, ?>> appServiceFinderClass, int userId) { List<AppServiceConnection> serviceConnections = new ArrayList<>(); Loading @@ -153,15 +161,21 @@ public class AppBindingService extends Binder { if (app.getClass() != appServiceFinderClass) { continue; } serviceConnections.addAll(getBoundConnectionsLocked(userId, app)); serviceConnections.addAll(getBoundConnectionsBlockingLocked(userId, app)); } } return serviceConnections; } /** Get the connection bound to a specific finder. If the connection does not * already exist, create one. */ private List<AppServiceConnection> getBoundConnectionsLocked(int userId, AppServiceFinder app) { /** * Get the connection bound to a specific finder, ensuring it's bound. * * This method will block until all connections are established or a timeout occurs. * * <p><b>NOTE: This method must be called from a background thread.</b></p> */ private List<AppServiceConnection> getBoundConnectionsBlockingLocked(int userId, AppServiceFinder app) { Set<String> targetPackages = app.getTargetPackages(userId); List<AppServiceConnection> connections = new ArrayList<>(); for (String targetPackage : targetPackages) { Loading @@ -180,11 +194,16 @@ public class AppBindingService extends Binder { targetPackage, service.getComponentName()); mConnections.add(conn); conn.bind(); } } if (conn != null) { conn.bind(); if (conn.awaitConnection()) { connections.add(conn); } else { Slogf.w(TAG, "Failed to establish connection for %s, user %d, package %s", app.getAppDescription(), userId, targetPackage); } } } return connections; Loading
services/core/java/com/android/server/appbinding/AppServiceConnection.java +20 −40 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.server.appbinding; import android.annotation.NonNull; import android.content.ComponentName; import android.content.Context; import android.os.ConditionVariable; import android.os.Handler; import android.os.IBinder; import android.os.IInterface; Loading @@ -27,9 +28,6 @@ import com.android.server.am.PersistentConnection; import com.android.server.appbinding.finders.AppServiceFinder; import com.android.server.utils.Slogf; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; /** * Establishes a persistent connection to a given service component for a given user * Each connection is associated with an AppServiceFinder to facilitate the service exchange if the Loading @@ -40,19 +38,7 @@ public class AppServiceConnection extends PersistentConnection<IInterface> { private final AppBindingConstants mConstants; private final AppServiceFinder mFinder; private final String mPackageName; /** * Listener for connection status updates * TODO: Refactor this (b/423644620) */ public interface ConnectionStatusListener { void onConnected(@NonNull AppServiceConnection connection, @NonNull IInterface service); void onDisconnected(@NonNull AppServiceConnection connection); void onBinderDied(@NonNull AppServiceConnection connection); } private final List<ConnectionStatusListener> mConnectionListeners = new CopyOnWriteArrayList<>(); private final ConditionVariable mConditionVariable = new ConditionVariable(); AppServiceConnection(Context context, int userId, AppBindingConstants constants, Handler handler, AppServiceFinder finder, String packageName, Loading @@ -75,20 +61,22 @@ public class AppServiceConnection extends PersistentConnection<IInterface> { @Override protected IInterface asInterface(IBinder obj) { final IInterface service = mFinder.asInterface(obj); if (service != null) { // Notify all listeners. Slogf.d(TAG, "Service for %s is connected. Notifying %s listeners.", getComponentName(), mConnectionListeners.size()); for (ConnectionStatusListener listener : mConnectionListeners) { listener.onConnected(this, service); } } else { if (service == null) { Slogf.w(TAG, "Service for %s is null.", getComponentName()); } return service; } @Override protected void onConnected(@NonNull IInterface service) { mConditionVariable.open(); } @Override protected void onDisconnected() { mConditionVariable.close(); } public AppServiceFinder getFinder() { return mFinder; } Loading @@ -98,21 +86,13 @@ public class AppServiceConnection extends PersistentConnection<IInterface> { } /** * Adds a listener to be notified of connection changes. * If service is already connected, notify immediately. */ public void addConnectionStatusListener(@NonNull ConnectionStatusListener listener) { mConnectionListeners.add(listener); final IInterface service = getServiceBinder(); if (isConnected() && service != null) { listener.onConnected(this, service); } } /** * Removes an existing listener. * Establishes the service connection and blocks until the service is connected * or a timeout occurs. * * @return true if the service connected successfully within the timeout, false otherwise. */ public void removeConnectionStatusListener(@NonNull ConnectionStatusListener listener) { mConnectionListeners.remove(listener); public boolean awaitConnection() { long timeoutMs = mConstants.SERVICE_RECONNECT_MAX_BACKOFF_SEC * 10 * 1000L; return mConditionVariable.block(timeoutMs) && isConnected(); } }
services/supervision/java/com/android/server/supervision/SupervisionService.java +43 −58 Original line number Diff line number Diff line Loading @@ -54,7 +54,6 @@ import android.content.pm.UserInfo; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; import android.os.IInterface; import android.os.PersistableBundle; import android.os.Process; import android.os.RemoteException; Loading @@ -68,6 +67,7 @@ import android.util.SparseArray; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.BackgroundThread; import com.android.internal.util.DumpUtils; import com.android.internal.util.FunctionalUtils.RemoteExceptionIgnoringConsumer; import com.android.internal.util.IndentingPrintWriter; Loading @@ -82,6 +82,7 @@ import com.android.server.utils.Slogf; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.concurrent.Executor; Loading Loading @@ -387,8 +388,7 @@ public class SupervisionService extends ISupervisionManager.Stub { mSupervisionSettings.saveUserData(); } } Binder.withCleanCallingIdentity( () -> { BackgroundThread.getExecutor().execute(() -> { updateWebContentFilters(userId, enabled); dispatchSupervisionEvent( userId, listener -> listener.onSetSupervisionEnabled(userId, enabled)); Loading Loading @@ -420,10 +420,8 @@ public class SupervisionService extends ISupervisionManager.Stub { if (binder == null) { Slogf.d( SupervisionLog.TAG, "Failed to bind to SupervisionAppService for %s now", "Failed to bind to SupervisionAppService for %s", targetPackage); dispatchSupervisionAppServiceWhenConnected(conn, action); continue; } Loading @@ -436,10 +434,10 @@ public class SupervisionService extends ISupervisionManager.Stub { private void dispatchSupervisionEvent( @UserIdInt int userId, @NonNull RemoteExceptionIgnoringConsumer<ISupervisionListener> action) { ArrayList<ISupervisionListener> listeners = new ArrayList<>(); // Add SupervisionAppServices listeners before the platform listeners. listeners.addAll(getSupervisionAppServiceListeners(userId, action)); ArrayList<ISupervisionListener> listeners = new ArrayList<>( getSupervisionAppServiceListeners(userId, action)); synchronized (getLockObject()) { mSupervisionListeners.forEach( Loading @@ -450,7 +448,7 @@ public class SupervisionService extends ISupervisionManager.Stub { }); } listeners.forEach(listener -> action.accept(listener)); listeners.forEach(action); } private void clearAllDevicePoliciesAndSuspendedPackages(@UserIdInt int userId) { Loading @@ -459,20 +457,19 @@ public class SupervisionService extends ISupervisionManager.Stub { } enforcePermission(MANAGE_ROLE_HOLDERS); List<String> supervisionPackages = new ArrayList<>(); supervisionPackages.addAll( mInjector.getRoleHoldersAsUser( RoleManager.ROLE_SUPERVISION, UserHandle.of(userId))); supervisionPackages.addAll( mInjector.getRoleHoldersAsUser( RoleManager.ROLE_SYSTEM_SUPERVISION, UserHandle.of(userId))); List<String> roles = Arrays.asList(RoleManager.ROLE_SYSTEM_SUPERVISION, RoleManager.ROLE_SUPERVISION); for (String role : roles) { List<String> supervisionPackages = mInjector.getRoleHoldersAsUser(role, UserHandle.of(userId)); for (String supervisionPackage : supervisionPackages) { clearDevicePoliciesAndSuspendedPackagesFor(userId, supervisionPackage); clearDevicePoliciesAndSuspendedPackagesFor(userId, supervisionPackage, role); } } } private void clearDevicePoliciesAndSuspendedPackagesFor(int userId, String supervisionPackage) { private void clearDevicePoliciesAndSuspendedPackagesFor(int userId, String supervisionPackage, String roleName) { DevicePolicyManagerInternal dpmi = mInjector.getDpmInternal(); if (dpmi != null) { dpmi.removePoliciesForAdmins(supervisionPackage, userId); Loading @@ -482,36 +479,8 @@ public class SupervisionService extends ISupervisionManager.Stub { if (pmi != null) { pmi.unsuspendForSuspendingPackage(supervisionPackage, userId, userId); } } private void dispatchSupervisionAppServiceWhenConnected( AppServiceConnection conn, @NonNull RemoteExceptionIgnoringConsumer<ISupervisionListener> action) { // This listener will be notified when the connection changes. AppServiceConnection.ConnectionStatusListener connectionListener = new AppServiceConnection.ConnectionStatusListener() { @Override public void onConnected( @NonNull AppServiceConnection connection, @NonNull IInterface service) { try { ISupervisionListener binder = (ISupervisionListener) service; Binder.withCleanCallingIdentity(() -> action.accept(binder)); } finally { connection.removeConnectionStatusListener(this); } } @Override public void onDisconnected(@NonNull AppServiceConnection connection) { connection.removeConnectionStatusListener(this); } @Override public void onBinderDied(@NonNull AppServiceConnection connection) { connection.removeConnectionStatusListener(this); } }; conn.addConnectionStatusListener(connectionListener); mInjector.removeRoleHoldersAsUser(roleName, supervisionPackage, UserHandle.of(userId)); } /** Loading Loading @@ -618,13 +587,13 @@ public class SupervisionService extends ISupervisionManager.Stub { static class Injector { public Context context; private DevicePolicyManagerInternal mDpmInternal; private AppBindingService mAppBindingService; private DevicePolicyManagerInternal mDpmInternal; private KeyguardManager mKeyguardManager; private PackageManager mPackageManager; private PackageManagerInternal mPackageManagerInternal; private UserManagerInternal mUserManagerInternal; private RoleManager mRoleManager; private UserManagerInternal mUserManagerInternal; Injector(Context context) { this.context = context; Loading Loading @@ -686,6 +655,22 @@ public class SupervisionService extends ISupervisionManager.Stub { List<String> getRoleHoldersAsUser(String roleName, UserHandle user) { return mRoleManager.getRoleHoldersAsUser(roleName, user); } void removeRoleHoldersAsUser(String roleName, String packageName, UserHandle user) { mRoleManager.removeRoleHolderAsUser( roleName, packageName, 0, user, context.getMainExecutor(), success -> { if (!success) { Slogf.e(SupervisionLog.TAG, "Failed to remove role %s fro %s", packageName, roleName); } }); } } /** Publishes local and binder services and allows the service to act during initialization. */ Loading
services/tests/servicestests/src/com/android/server/supervision/SupervisionServiceTest.kt +117 −71 File changed.Preview size limit exceeded, changes collapsed. Show changes