summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/ActivityManagerInternal.java9
-rw-r--r--core/java/android/view/WindowManager.java5
-rw-r--r--core/java/android/view/WindowManagerPolicy.java6
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java34
-rw-r--r--services/core/java/com/android/server/am/ProcessRecord.java21
-rw-r--r--services/core/java/com/android/server/wm/Session.java62
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java5
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java4
8 files changed, 114 insertions, 32 deletions
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 89510d9f2d15..fa64a0f55337 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -224,4 +224,13 @@ public abstract class ActivityManagerInternal {
* Called when the trusted state of Keyguard has changed.
*/
public abstract void notifyKeyguardTrustedChanged();
+
+ /**
+ * Sets if the given pid has an overlay UI or not.
+ *
+ * @param pid The pid we are setting overlay UI for.
+ * @param hasOverlayUi True if the process has overlay UI.
+ * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
+ */
+ public abstract void setHasOverlayUi(int pid, boolean hasOverlayUi);
}
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 5a640faf08d3..e02d405928c7 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -726,7 +726,10 @@ public interface WindowManager extends ViewManager {
* <p>
* Requires {@link android.Manifest.permission#SYSTEM_ALERT_WINDOW} permission.
* <p>
- * In mult-iuser systems shows only on the owning user's screen.
+ * The system will adjust the importance of processes with this window type to reduce the
+ * chance of the low-memory-killer killing them.
+ * <p>
+ * In multi-user systems shows only on the owning user's screen.
*/
public static final int TYPE_APPLICATION_OVERLAY = FIRST_SYSTEM_WINDOW + 38;
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 8e597dc40894..2617d45a6a02 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -786,13 +786,13 @@ public interface WindowManagerPolicy {
case TYPE_PRIORITY_PHONE:
// SIM errors and unlock. Not sure if this really should be in a high layer.
return 9;
- case TYPE_DREAM:
- // used for Dreams (screensavers with TYPE_DREAM windows)
- return 10;
case TYPE_SYSTEM_ALERT:
// like the ANR / app crashed dialogs
return canAddInternalSystemWindow ? 11 : 10;
case TYPE_APPLICATION_OVERLAY:
+ return 12;
+ case TYPE_DREAM:
+ // used for Dreams (screensavers with TYPE_DREAM windows)
return 13;
case TYPE_INPUT_METHOD:
// on-screen keyboards and other such input method user interfaces go here.
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 69a3a263bbf8..d5075f153106 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -20141,6 +20141,13 @@ public class ActivityManagerService extends IActivityManager.Stub
app.adjType = "force-fg";
app.adjSource = app.forcingToForeground;
schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
+ } else if (app.hasOverlayUi) {
+ // The process is display an overlay UI.
+ adj = ProcessList.PERCEPTIBLE_APP_ADJ;
+ procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+ app.cached = false;
+ app.adjType = "has-overlay-ui";
+ schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
}
}
@@ -22860,6 +22867,33 @@ public class ActivityManagerService extends IActivityManager.Stub
}
}
}
+
+ /**
+ * Sets if the given pid has an overlay UI or not.
+ *
+ * @param pid The pid we are setting overlay UI for.
+ * @param hasOverlayUi True if the process has overlay UI.
+ * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
+ */
+ @Override
+ public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
+ synchronized (ActivityManagerService.this) {
+ final ProcessRecord pr;
+ synchronized (mPidsSelfLocked) {
+ pr = mPidsSelfLocked.get(pid);
+ if (pr == null) {
+ Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
+ return;
+ }
+ }
+ if (pr.hasOverlayUi == hasOverlayUi) {
+ return;
+ }
+ pr.hasOverlayUi = hasOverlayUi;
+ //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
+ updateOomAdjLocked(pr);
+ }
+ }
}
private final class SleepTokenImpl extends SleepToken {
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 356781fc7956..2d2720458fbb 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -31,14 +31,11 @@ import com.android.internal.os.BatteryStatsImpl;
import android.app.ActivityManager;
import android.app.Dialog;
import android.app.IApplicationThread;
-import android.app.IInstrumentationWatcher;
-import android.app.IUiAutomationConnection;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.res.CompatibilityInfo;
import android.os.Binder;
-import android.os.Bundle;
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
@@ -46,7 +43,6 @@ import android.os.SystemClock;
import android.os.Trace;
import android.os.UserHandle;
import android.util.ArrayMap;
-import android.util.PrintWriterPrinter;
import android.util.TimeUtils;
import java.io.PrintWriter;
@@ -116,8 +112,18 @@ final class ProcessRecord {
boolean repForegroundActivities; // Last reported foreground activities.
boolean systemNoUi; // This is a system process, but not currently showing UI.
boolean hasShownUi; // Has UI been shown in this process since it was started?
- boolean hasTopUi; // Is this process currently showing "top-level" UI that is not an
- // activity?
+ boolean hasTopUi; // Is this process currently showing a non-activity UI that the user
+ // is interacting with? E.g. The status bar when it is expanded, but
+ // not when it is minimized. When true the
+ // process will be set to use the ProcessList#SCHED_GROUP_TOP_APP
+ // scheduling group to boost performance.
+ boolean hasOverlayUi; // Is the process currently showing a non-activity UI that
+ // overlays on-top of activity UIs on screen. E.g. display a window
+ // of type
+ // android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
+ // When true the process will oom adj score will be set to
+ // ProcessList#PERCEPTIBLE_APP_ADJ at minimum to reduce the chance
+ // of the process getting killed.
boolean pendingUiClean; // Want to clean up resources from showing UI?
boolean hasAboveClient; // Bound using BIND_ABOVE_CLIENT, so want to be lower
boolean treatLikeActivity; // Bound using BIND_TREAT_LIKE_ACTIVITY
@@ -425,6 +431,9 @@ final class ProcessRecord {
if (hasTopUi) {
pw.print(prefix); pw.print("hasTopUi="); pw.print(hasTopUi);
}
+ if (hasOverlayUi) {
+ pw.print(prefix); pw.print("hasOverlayUi="); pw.print(hasOverlayUi);
+ }
}
ProcessRecord(BatteryStatsImpl _batteryStats, ApplicationInfo _info,
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index ead70e184e5c..782f9f2f6611 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
@@ -69,6 +70,7 @@ public class Session extends IWindowSession.Stub
private final String mStringName;
SurfaceSession mSurfaceSession;
private int mNumWindow = 0;
+ private int mNumOverlayWindow = 0;
private boolean mClientDead = false;
private float mLastReportedAnimatorScale;
@@ -542,7 +544,7 @@ public class Session extends IWindowSession.Stub
}
}
- void windowAddedLocked() {
+ void windowAddedLocked(int type) {
if (mSurfaceSession == null) {
if (WindowManagerService.localLOGV) Slog.v(
TAG_WM, "First window added to " + this + ", creating SurfaceSession");
@@ -555,36 +557,56 @@ public class Session extends IWindowSession.Stub
}
}
mNumWindow++;
+ if (type == TYPE_APPLICATION_OVERLAY) {
+ mNumOverlayWindow++;
+ setHasOverlayUi(true);
+ }
}
- void windowRemovedLocked() {
+ void windowRemovedLocked(int type) {
mNumWindow--;
+ if (type == TYPE_APPLICATION_OVERLAY) {
+ mNumOverlayWindow--;
+ if (mNumOverlayWindow == 0) {
+ setHasOverlayUi(false);
+ } else if (mNumOverlayWindow < 0) {
+ throw new IllegalStateException("mNumOverlayWindow=" + mNumOverlayWindow
+ + " less than 0 for session=" + this);
+ }
+ }
killSessionLocked();
}
- void killSessionLocked() {
- if (mNumWindow <= 0 && mClientDead) {
- mService.mSessions.remove(this);
- if (mSurfaceSession != null) {
- if (WindowManagerService.localLOGV) Slog.v(
- TAG_WM, "Last window removed from " + this
- + ", destroying " + mSurfaceSession);
- if (SHOW_TRANSACTIONS) Slog.i(
- TAG_WM, " KILL SURFACE SESSION " + mSurfaceSession);
- try {
- mSurfaceSession.kill();
- } catch (Exception e) {
- Slog.w(TAG_WM, "Exception thrown when killing surface session "
- + mSurfaceSession + " in session " + this
- + ": " + e.toString());
- }
- mSurfaceSession = null;
- }
+ private void killSessionLocked() {
+ if (mNumWindow > 0 || !mClientDead) {
+ return;
}
+
+ mService.mSessions.remove(this);
+ if (mSurfaceSession == null) {
+ return;
+ }
+
+ if (WindowManagerService.localLOGV) Slog.v(TAG_WM, "Last window removed from " + this
+ + ", destroying " + mSurfaceSession);
+ if (SHOW_TRANSACTIONS) Slog.i(TAG_WM, " KILL SURFACE SESSION " + mSurfaceSession);
+ try {
+ mSurfaceSession.kill();
+ } catch (Exception e) {
+ Slog.w(TAG_WM, "Exception thrown when killing surface session " + mSurfaceSession
+ + " in session " + this + ": " + e.toString());
+ }
+ mSurfaceSession = null;
+ setHasOverlayUi(false);
+ }
+
+ private void setHasOverlayUi(boolean hasOverlayUi) {
+ mService.mH.obtainMessage(H.SET_HAS_OVERLAY_UI, mPid, hasOverlayUi ? 1 : 0).sendToTarget();
}
void dump(PrintWriter pw, String prefix) {
pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow);
+ pw.print(" mNumOverlayWindow="); pw.print(mNumOverlayWindow);
pw.print(" mClientDead="); pw.print(mClientDead);
pw.print(" mSurfaceSession="); pw.println(mSurfaceSession);
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index be0771ae97b5..1c864e8cf2e7 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -5268,6 +5268,7 @@ public class WindowManagerService extends IWindowManager.Stub
public static final int RESTORE_POINTER_ICON = 55;
public static final int NOTIFY_KEYGUARD_FLAGS_CHANGED = 56;
public static final int NOTIFY_KEYGUARD_TRUSTED_CHANGED = 57;
+ public static final int SET_HAS_OVERLAY_UI = 58;
/**
* Used to denote that an integer field in a message will not be used.
@@ -5751,6 +5752,10 @@ public class WindowManagerService extends IWindowManager.Stub
mAmInternal.notifyKeyguardTrustedChanged();
}
break;
+ case SET_HAS_OVERLAY_UI: {
+ mAmInternal.setHasOverlayUi(msg.arg1, msg.arg2 == 1);
+ }
+ break;
}
if (DEBUG_WINDOW_TRACE) {
Slog.v(TAG_WM, "handleMessage: exit");
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 867080ed2450..65e1f84eae35 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -665,7 +665,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
void attach() {
if (localLOGV) Slog.v(TAG, "Attaching " + this + " token=" + mToken);
- mSession.windowAddedLocked();
+ mSession.windowAddedLocked(mAttrs.type);
}
@Override
@@ -1738,7 +1738,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mWinAnimator.destroyDeferredSurfaceLocked();
mWinAnimator.destroySurfaceLocked();
- mSession.windowRemovedLocked();
+ mSession.windowRemovedLocked(mAttrs.type);
try {
mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
} catch (RuntimeException e) {