diff options
3 files changed, 44 insertions, 12 deletions
diff --git a/services/companion/java/com/android/server/companion/CompanionApplicationController.java b/services/companion/java/com/android/server/companion/CompanionApplicationController.java index f32eebc2a31f..2a83a3c431ec 100644 --- a/services/companion/java/com/android/server/companion/CompanionApplicationController.java +++ b/services/companion/java/com/android/server/companion/CompanionApplicationController.java @@ -49,7 +49,7 @@ import java.util.Map; * The following is the list of the APIs provided by {@link CompanionApplicationController} (to be * utilized by {@link CompanionDeviceManagerService}): * <ul> - * <li> {@link #bindCompanionApplication(int, String)} + * <li> {@link #bindCompanionApplication(int, String, boolean)} * <li> {@link #unbindCompanionApplication(int, String)} * <li> {@link #notifyCompanionApplicationDeviceAppeared(AssociationInfo)} * <li> {@link #notifyCompanionApplicationDeviceDisappeared(AssociationInfo)} @@ -103,8 +103,12 @@ class CompanionApplicationController { mCompanionServicesRegister.invalidate(userId); } - void bindCompanionApplication(@UserIdInt int userId, @NonNull String packageName) { - if (DEBUG) Log.i(TAG, "bind() u" + userId + "/" + packageName); + void bindCompanionApplication(@UserIdInt int userId, @NonNull String packageName, + boolean bindImportant) { + if (DEBUG) { + Log.i(TAG, "bind() u" + userId + "/" + packageName + + " important=" + bindImportant); + } final List<ComponentName> companionServices = mCompanionServicesRegister.forPackage(userId, packageName); @@ -125,7 +129,8 @@ class CompanionApplicationController { } serviceConnectors = CollectionUtils.map(companionServices, componentName -> - new CompanionDeviceServiceConnector(mContext, userId, componentName)); + CompanionDeviceServiceConnector.newInstance(mContext, userId, + componentName, bindImportant)); mBoundCompanionApplications.setValueForPackage(userId, packageName, serviceConnectors); } diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java index eaa99f74e24e..13a5a2829945 100644 --- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java @@ -254,9 +254,12 @@ public class CompanionDeviceManagerService extends SystemService { final int userId = association.getUserId(); final String packageName = association.getPackageName(); + // Set bindImportant to true when the association is self-managed to avoid the target + // service being killed. + final boolean bindImportant = association.isSelfManaged(); if (!mCompanionAppController.isCompanionApplicationBound(userId, packageName)) { - mCompanionAppController.bindCompanionApplication(userId, packageName); + mCompanionAppController.bindCompanionApplication(userId, packageName, bindImportant); } else if (DEBUG) { Log.i(TAG, "u" + userId + "\\" + packageName + " is already bound"); } diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceServiceConnector.java b/services/companion/java/com/android/server/companion/CompanionDeviceServiceConnector.java index f2a58b74a65a..4c7b9b80d5be 100644 --- a/services/companion/java/com/android/server/companion/CompanionDeviceServiceConnector.java +++ b/services/companion/java/com/android/server/companion/CompanionDeviceServiceConnector.java @@ -16,6 +16,7 @@ package com.android.server.companion; +import static android.content.Context.BIND_ALMOST_PERCEPTIBLE; import static android.content.Context.BIND_IMPORTANT; import static android.os.Process.THREAD_PRIORITY_DEFAULT; @@ -44,20 +45,43 @@ import com.android.server.ServiceThread; class CompanionDeviceServiceConnector extends ServiceConnector.Impl<ICompanionDeviceService> { private static final String TAG = "CompanionDevice_ServiceConnector"; private static final boolean DEBUG = false; - private static final int BINDING_FLAGS = BIND_IMPORTANT; /** Listener for changes to the state of the {@link CompanionDeviceServiceConnector} */ interface Listener { void onBindingDied(@UserIdInt int userId, @NonNull String packageName); } - private final @UserIdInt int mUserId; - private final @NonNull ComponentName mComponentName; - private @Nullable Listener mListener; + @UserIdInt + private final int mUserId; + @NonNull + private final ComponentName mComponentName; + @Nullable + private Listener mListener; - CompanionDeviceServiceConnector(@NonNull Context context, @UserIdInt int userId, - @NonNull ComponentName componentName) { - super(context, buildIntent(componentName), BINDING_FLAGS, userId, null); + /** + * Create a CompanionDeviceServiceConnector instance. + * + * When bindImportant is false, the binding flag will be BIND_ALMOST_PERCEPTIBLE + * (oom_score_adj = PERCEPTIBLE_MEDIUM_APP = 225). The target service will be treated + * as important as a perceptible app (IMPORTANCE_VISIBLE = 200), and will be unbound when + * the app is removed from task manager. + * When bindImportant is true, the binding flag will be BIND_IMPORTANT + * (oom_score_adj = PERCEPTIBLE_MEDIUM_APP = -700). The target service will + * have the highest priority to avoid being killed (IMPORTANCE_FOREGROUND = 100). + * + * One time permission's importance level to keep session alive is + * IMPORTANCE_FOREGROUND_SERVICE = 125. In order to kill the one time permission session, the + * service importance level should be higher than 125. + */ + static CompanionDeviceServiceConnector newInstance(@NonNull Context context, + @UserIdInt int userId, @NonNull ComponentName componentName, boolean bindImportant) { + final int bindingFlags = bindImportant ? BIND_IMPORTANT : BIND_ALMOST_PERCEPTIBLE; + return new CompanionDeviceServiceConnector(context, userId, componentName, bindingFlags); + } + + private CompanionDeviceServiceConnector(@NonNull Context context, @UserIdInt int userId, + @NonNull ComponentName componentName, int bindingFlags) { + super(context, buildIntent(componentName), bindingFlags, userId, null); mUserId = userId; mComponentName = componentName; } |