From 5016a7891a8c5fe1c8ca5c24e83595b7973fc6b0 Mon Sep 17 00:00:00 2001 From: Amith Yamasani Date: Mon, 17 Jun 2019 16:20:24 -0700 Subject: [PATCH] Expose BIND_NOT_PERCEPTIBLE service flag Using this flag when binding to a service will allow the bound process to be held at a low oom_adj of 250, so that it can be expunged to reclaim memory if a more user-visible app needs it. Use for bindings such as job services and other connections that the caller can easily recover from and restart if necessary. Adjust the lmk thresholds to use this oom_adj as one of the levels, so they're killed before perceptible apps (such as foreground services). Bug: 135219821 Test: CtsAppTestCases Manually check notification listener oom_adj and dumpsys activity services output Change-Id: I9f6d0891d842e4d12f7995b9b1a8f57b0903a16d --- api/current.txt | 1 + core/java/android/content/Context.java | 25 ++++++++++--------- .../server/activitymanagerservice.proto | 2 ++ .../android/server/am/ConnectionRecord.java | 10 ++++++++ .../com/android/server/am/OomAdjuster.java | 2 +- .../com/android/server/am/ProcessList.java | 6 ++--- .../android/server/job/JobServiceContext.java | 2 +- .../NotificationManagerService.java | 6 ++--- 8 files changed, 34 insertions(+), 20 deletions(-) diff --git a/api/current.txt b/api/current.txt index 9c90ee67cdf73..cd78602d9cd9e 100644 --- a/api/current.txt +++ b/api/current.txt @@ -9808,6 +9808,7 @@ package android.content { field public static final int BIND_IMPORTANT = 64; // 0x40 field public static final int BIND_INCLUDE_CAPABILITIES = 4096; // 0x1000 field public static final int BIND_NOT_FOREGROUND = 4; // 0x4 + field public static final int BIND_NOT_PERCEPTIBLE = 256; // 0x100 field public static final int BIND_WAIVE_PRIORITY = 32; // 0x20 field public static final String BIOMETRIC_SERVICE = "biometric"; field public static final String BLUETOOTH_SERVICE = "bluetooth"; diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 529677aea6539..c3dd82729d6d3 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -234,7 +234,9 @@ public abstract class Context { BIND_ALLOW_OOM_MANAGEMENT, BIND_WAIVE_PRIORITY, BIND_IMPORTANT, - BIND_ADJUST_WITH_ACTIVITY + BIND_ADJUST_WITH_ACTIVITY, + BIND_NOT_PERCEPTIBLE, + BIND_INCLUDE_CAPABILITIES }) @Retention(RetentionPolicy.SOURCE) public @interface BindServiceFlags {} @@ -328,26 +330,25 @@ public abstract class Context { */ public static final int BIND_ADJUST_WITH_ACTIVITY = 0x0080; + /** + * Flag for {@link #bindService}: If binding from an app that is visible or user-perceptible, + * lower the target service's importance to below the perceptible level. This allows + * the system to (temporarily) expunge the bound process from memory to make room for more + * important user-perceptible processes. + */ + public static final int BIND_NOT_PERCEPTIBLE = 0x00000100; + /** * Flag for {@link #bindService}: If binding from an app that has specific capabilities * due to its foreground state such as an activity or foreground service, then this flag will * allow the bound app to get the same capabilities, as long as it has the required permissions * as well. */ - public static final int BIND_INCLUDE_CAPABILITIES = 0x00001000; + public static final int BIND_INCLUDE_CAPABILITIES = 0x000001000; /*********** Public flags above this line ***********/ /*********** Hidden flags below this line ***********/ - /** - * Flag for {@link #bindService}: If binding from something better than perceptible, - * still set the adjust below perceptible. This would be used for bound services that can - * afford to be evicted when under extreme memory pressure, but should be restarted as soon - * as possible. - * @hide - */ - public static final int BIND_ADJUST_BELOW_PERCEPTIBLE = 0x00040000; - /** * Flag for {@link #bindService}: This flag is intended to be used only by the system to adjust * the scheduling policy for IMEs (and any other out-of-process user-visible components that @@ -473,7 +474,7 @@ public abstract class Context { */ public static final int BIND_REDUCTION_FLAGS = Context.BIND_ALLOW_OOM_MANAGEMENT | Context.BIND_WAIVE_PRIORITY - | Context.BIND_ADJUST_BELOW_PERCEPTIBLE | Context.BIND_NOT_VISIBLE; + | Context.BIND_NOT_PERCEPTIBLE | Context.BIND_NOT_VISIBLE; /** @hide */ @IntDef(flag = true, prefix = { "RECEIVER_VISIBLE_" }, value = { diff --git a/core/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto index a7d4734f43b96..7fb6f98ab6626 100644 --- a/core/proto/android/server/activitymanagerservice.proto +++ b/core/proto/android/server/activitymanagerservice.proto @@ -591,6 +591,8 @@ message ConnectionRecordProto { SHOWING_UI = 13; NOT_VISIBLE = 14; DEAD = 15; + NOT_PERCEPTIBLE = 16; + INCLUDE_CAPABILITIES = 17; } repeated Flag flags = 3; optional string service_name = 4; diff --git a/services/core/java/com/android/server/am/ConnectionRecord.java b/services/core/java/com/android/server/am/ConnectionRecord.java index fe9554255feb8..4595084863849 100644 --- a/services/core/java/com/android/server/am/ConnectionRecord.java +++ b/services/core/java/com/android/server/am/ConnectionRecord.java @@ -65,6 +65,8 @@ final class ConnectionRecord { Context.BIND_VISIBLE, Context.BIND_SHOWING_UI, Context.BIND_NOT_VISIBLE, + Context.BIND_NOT_PERCEPTIBLE, + Context.BIND_INCLUDE_CAPABILITIES, }; private static final int[] BIND_PROTO_ENUMS = new int[] { ConnectionRecordProto.AUTO_CREATE, @@ -82,6 +84,8 @@ final class ConnectionRecord { ConnectionRecordProto.VISIBLE, ConnectionRecordProto.SHOWING_UI, ConnectionRecordProto.NOT_VISIBLE, + ConnectionRecordProto.NOT_PERCEPTIBLE, + ConnectionRecordProto.INCLUDE_CAPABILITIES, }; void dump(PrintWriter pw, String prefix) { @@ -212,6 +216,12 @@ final class ConnectionRecord { if ((flags&Context.BIND_NOT_VISIBLE) != 0) { sb.append("!VIS "); } + if ((flags & Context.BIND_NOT_PERCEPTIBLE) != 0) { + sb.append("!PRCP "); + } + if ((flags & Context.BIND_INCLUDE_CAPABILITIES) != 0) { + sb.append("CAPS "); + } if (serviceDead) { sb.append("DEAD "); } diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index 7abfcea306cca..5ade50a5f2484 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -1264,7 +1264,7 @@ public final class OomAdjuster { cr.trackProcState(procState, mAdjSeq, now); trackedProcState = true; } - } else if ((cr.flags & Context.BIND_ADJUST_BELOW_PERCEPTIBLE) != 0 + } else if ((cr.flags & Context.BIND_NOT_PERCEPTIBLE) != 0 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ && adj > ProcessList.PERCEPTIBLE_LOW_APP_ADJ) { newAdj = ProcessList.PERCEPTIBLE_LOW_APP_ADJ; diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index d64a2c210f270..b399971d1ad5d 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -184,8 +184,8 @@ public final class ProcessList { // is not entirely fatal but is generally a bad idea. static final int BACKUP_APP_ADJ = 300; - // This is a process bound by the system that's more important than services but not so - // perceptible that it affects the user immediately if killed. + // This is a process bound by the system (or other app) that's more important than services but + // not so perceptible that it affects the user immediately if killed. static final int PERCEPTIBLE_LOW_APP_ADJ = 250; // This is a process only hosting components that are perceptible to the @@ -279,7 +279,7 @@ public final class ProcessList { // can't give it a different value for every possible kind of process. private final int[] mOomAdj = new int[] { FOREGROUND_APP_ADJ, VISIBLE_APP_ADJ, PERCEPTIBLE_APP_ADJ, - BACKUP_APP_ADJ, CACHED_APP_MIN_ADJ, CACHED_APP_LMK_FIRST_ADJ + PERCEPTIBLE_LOW_APP_ADJ, CACHED_APP_MIN_ADJ, CACHED_APP_LMK_FIRST_ADJ }; // These are the low-end OOM level limits. This is appropriate for an // HVGA or smaller phone with less than 512MB. Values are in KB. diff --git a/services/core/java/com/android/server/job/JobServiceContext.java b/services/core/java/com/android/server/job/JobServiceContext.java index 65dac8bf7cdd1..7da128f9d3ecc 100644 --- a/services/core/java/com/android/server/job/JobServiceContext.java +++ b/services/core/java/com/android/server/job/JobServiceContext.java @@ -251,7 +251,7 @@ public final class JobServiceContext implements ServiceConnection { try { binding = mContext.bindServiceAsUser(intent, this, Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND - | Context.BIND_NOT_VISIBLE | Context.BIND_ADJUST_BELOW_PERCEPTIBLE, + | Context.BIND_NOT_PERCEPTIBLE, new UserHandle(job.getUserId())); } catch (SecurityException e) { // Some permission policy, for example INTERACT_ACROSS_USERS and diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 82b16dea5b49b..495a2edf80578 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -42,10 +42,10 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR; -import static android.content.Context.BIND_ADJUST_BELOW_PERCEPTIBLE; import static android.content.Context.BIND_ALLOW_WHITELIST_MANAGEMENT; import static android.content.Context.BIND_AUTO_CREATE; import static android.content.Context.BIND_FOREGROUND_SERVICE; +import static android.content.Context.BIND_NOT_PERCEPTIBLE; import static android.content.pm.ActivityInfo.DOCUMENT_LAUNCH_ALWAYS; import static android.content.pm.PackageManager.FEATURE_LEANBACK; import static android.content.pm.PackageManager.FEATURE_TELEVISION; @@ -7786,12 +7786,12 @@ public class NotificationManagerService extends SystemService { @Override protected int getBindFlags() { - // Most of the same flags as the base, but also add BIND_ADJUST_BELOW_PERCEPTIBLE + // Most of the same flags as the base, but also add BIND_NOT_PERCEPTIBLE // because too many 3P apps could be kept in memory as notification listeners and // cause extreme memory pressure. // TODO: Change the binding lifecycle of NotificationListeners to avoid this situation. return BIND_AUTO_CREATE | BIND_FOREGROUND_SERVICE - | BIND_ADJUST_BELOW_PERCEPTIBLE | BIND_ALLOW_WHITELIST_MANAGEMENT; + | BIND_NOT_PERCEPTIBLE | BIND_ALLOW_WHITELIST_MANAGEMENT; } @Override