diff options
5 files changed, 97 insertions, 2 deletions
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index 277348a318b9..aacd5da58640 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -3010,6 +3010,13 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM reply.writeNoException(); return true; } + case SET_HAS_TOP_UI: { + data.enforceInterface(IActivityManager.descriptor); + final boolean hasTopUi = data.readInt() != 0; + setHasTopUi(hasTopUi); + reply.writeNoException(); + return true; + } } return super.onTransact(code, data, reply, flags); @@ -7072,5 +7079,18 @@ class ActivityManagerProxy implements IActivityManager return; } + public void setHasTopUi(boolean hasTopUi) + throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeInt(hasTopUi ? 1 : 0); + mRemote.transact(SET_HAS_TOP_UI, data, reply, 0); + reply.readException(); + data.recycle(); + reply.recycle(); + return; + } + private IBinder mRemote; } diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 4a4202aa4ce8..d54ce4bd3f05 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -661,6 +661,14 @@ public interface IActivityManager extends IInterface { public void setVrThread(int tid) throws RemoteException; public void setRenderThread(int tid) throws RemoteException; + /** + * Let's activity manager know whether the calling process is currently showing "top-level" UI + * that is not an activity, i.e. windows on the screen the user is currently interacting with. + * + * @param hasTopUi Whether the calling process has "top-level" UI. + */ + public void setHasTopUi(boolean hasTopUi) throws RemoteException; + /* * Private non-Binder interfaces */ @@ -1051,4 +1059,5 @@ public interface IActivityManager extends IInterface { // Start of N MR1 transactions int SET_VR_THREAD_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 377; int SET_RENDER_THREAD_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 378; + int SET_HAS_TOP_UI = IBinder.FIRST_CALL_TRANSACTION + 379; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java index 888e19c50f38..527148189588 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java @@ -16,11 +16,16 @@ package com.android.systemui.statusbar.phone; +import android.app.ActivityManagerNative; +import android.app.IActivityManager; import android.content.Context; import android.content.pm.ActivityInfo; import android.content.res.Resources; import android.graphics.PixelFormat; +import android.os.RemoteException; import android.os.SystemProperties; +import android.os.Trace; +import android.util.Log; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; @@ -41,11 +46,16 @@ import java.lang.reflect.Field; */ public class StatusBarWindowManager implements RemoteInputController.Callback { + private static final String TAG = "StatusBarWindowManager"; + private final Context mContext; private final WindowManager mWindowManager; + private final IActivityManager mActivityManager; private View mStatusBarView; private WindowManager.LayoutParams mLp; private WindowManager.LayoutParams mLpChanged; + private boolean mHasTopUi; + private boolean mHasTopUiChanged; private int mBarHeight; private final boolean mKeyguardScreenRotation; private final float mScreenBrightnessDoze; @@ -54,6 +64,7 @@ public class StatusBarWindowManager implements RemoteInputController.Callback { public StatusBarWindowManager(Context context) { mContext = context; mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + mActivityManager = ActivityManagerNative.getDefault(); mKeyguardScreenRotation = shouldEnableKeyguardScreenRotation(); mScreenBrightnessDoze = mContext.getResources().getInteger( com.android.internal.R.integer.config_screenBrightnessDoze) / 255f; @@ -193,9 +204,18 @@ public class StatusBarWindowManager implements RemoteInputController.Callback { applyFitsSystemWindows(state); applyModalFlag(state); applyBrightness(state); + applyHasTopUi(state); if (mLp.copyFrom(mLpChanged) != 0) { mWindowManager.updateViewLayout(mStatusBarView, mLp); } + if (mHasTopUi != mHasTopUiChanged) { + try { + mActivityManager.setHasTopUi(mHasTopUiChanged); + } catch (RemoteException e) { + Log.e(TAG, "Failed to call setHasTopUi", e); + } + mHasTopUi = mHasTopUiChanged; + } } private void applyForceStatusBarVisibleFlag(State state) { @@ -224,6 +244,10 @@ public class StatusBarWindowManager implements RemoteInputController.Callback { } } + private void applyHasTopUi(State state) { + mHasTopUiChanged = isExpanded(state); + } + public void setKeyguardShowing(boolean showing) { mCurrentState.keyguardShowing = showing; apply(mCurrentState); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 59e309662302..236f083ab112 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -63,6 +63,7 @@ import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; import android.Manifest; +import android.Manifest.permission; import android.annotation.NonNull; import android.annotation.UserIdInt; import android.app.Activity; @@ -6280,6 +6281,9 @@ public final class ActivityManagerService extends ActivityManagerNative enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE); } proc.uidRecord = uidRec; + + // Reset render thread tid if it was already set, so new process can set it again. + proc.renderThreadTid = 0; uidRec.numProcs++; mProcessNames.put(proc.processName, proc.uid, proc); if (proc.isolated) { @@ -12672,6 +12676,42 @@ public final class ActivityManagerService extends ActivityManagerNative } } + @Override + public void setHasTopUi(boolean hasTopUi) throws RemoteException { + if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) { + String msg = "Permission Denial: setHasTopUi() from pid=" + + Binder.getCallingPid() + + ", uid=" + Binder.getCallingUid() + + " requires " + permission.INTERNAL_SYSTEM_WINDOW; + Slog.w(TAG, msg); + throw new SecurityException(msg); + } + final int pid = Binder.getCallingPid(); + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (this) { + boolean changed = false; + ProcessRecord pr; + synchronized (mPidsSelfLocked) { + pr = mPidsSelfLocked.get(pid); + if (pr == null) { + Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid); + return; + } + if (pr.hasTopUi != hasTopUi) { + pr.hasTopUi = hasTopUi; + changed = true; + } + } + if (changed) { + updateOomAdjLocked(pr); + } + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + public final void enterSafeMode() { synchronized(this) { // It only makes sense to do this before the system is ready @@ -19148,7 +19188,7 @@ public final class ActivityManagerService extends ActivityManagerNative // facilitate this, here we need to determine whether or not it // is currently showing UI. app.systemNoUi = true; - if (app == TOP_APP) { + if (app == TOP_APP || app.hasTopUi) { app.systemNoUi = false; app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP; app.adjType = "pers-top-activity"; @@ -19177,7 +19217,7 @@ public final class ActivityManagerService extends ActivityManagerNative int procState; boolean foregroundActivities = false; BroadcastQueue queue; - if (app == TOP_APP) { + if (app == TOP_APP || app.hasTopUi) { // The last app on the list is the foreground app. adj = ProcessList.FOREGROUND_APP_ADJ; schedGroup = ProcessList.SCHED_GROUP_TOP_APP; diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index dad383dff22f..e74b3a32a2b8 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -116,6 +116,8 @@ 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 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 |