diff options
Diffstat (limited to 'services/java/com')
5 files changed, 143 insertions, 32 deletions
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index c957ebb..e41f642 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -1000,7 +1000,6 @@ public final class ActivityManagerService extends ActivityManagerNative static final int USER_SWITCH_TIMEOUT_MSG = 36; static final int IMMERSIVE_MODE_LOCK_MSG = 37; static final int PERSIST_URI_GRANTS = 38; - static final int SET_FOCUSED_STACK = 39; static final int FIRST_ACTIVITY_STACK_MSG = 100; static final int FIRST_BROADCAST_QUEUE_MSG = 200; @@ -1493,18 +1492,6 @@ public final class ActivityManagerService extends ActivityManagerNative writeGrantedUriPermissions(); break; } - case SET_FOCUSED_STACK: { - synchronized (ActivityManagerService.this) { - ActivityStack stack = mStackSupervisor.getStack(msg.arg1); - if (stack != null) { - ActivityRecord r = stack.topRunningActivityLocked(null); - if (r != null) { - setFocusedActivityLocked(r); - } - } - } - break; - } } } }; @@ -2081,7 +2068,26 @@ public final class ActivityManagerService extends ActivityManagerNative @Override public void setFocusedStack(int stackId) { if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); - mHandler.obtainMessage(SET_FOCUSED_STACK, stackId, 0).sendToTarget(); + synchronized (ActivityManagerService.this) { + ActivityStack stack = mStackSupervisor.getStack(stackId); + if (stack != null) { + ActivityRecord r = stack.topRunningActivityLocked(null); + if (r != null) { + setFocusedActivityLocked(r); + } + } + } + } + + @Override + public void notifyActivityDrawn(IBinder token) { + if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); + synchronized (this) { + ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); + if (r != null) { + r.task.stack.notifyActivityDrawnLocked(r); + } + } } final void applyUpdateLockStateLocked(ActivityRecord r) { @@ -8048,7 +8054,26 @@ public final class ActivityManagerService extends ActivityManagerNative } @Override - public void convertToOpaque(IBinder token) { + public void convertFromTranslucent(IBinder token) { + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (this) { + final ActivityRecord r = ActivityRecord.isInStackLocked(token); + if (r == null) { + return; + } + if (r.changeWindowTranslucency(true)) { + mWindowManager.setAppFullscreen(token, true); + mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); + } + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + + @Override + public void convertToTranslucent(IBinder token) { final long origId = Binder.clearCallingIdentity(); try { synchronized (this) { @@ -8056,8 +8081,9 @@ public final class ActivityManagerService extends ActivityManagerNative if (r == null) { return; } - if (r.convertToOpaque()) { - mWindowManager.setAppFullscreen(token); + if (r.changeWindowTranslucency(false)) { + r.task.stack.convertToTranslucent(r); + mWindowManager.setAppFullscreen(token, false); mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); } } diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java index 4f09407..2ae9ed6 100644 --- a/services/java/com/android/server/am/ActivityRecord.java +++ b/services/java/com/android/server/am/ActivityRecord.java @@ -17,6 +17,7 @@ package com.android.server.am; import android.os.Trace; +import com.android.internal.R.styleable; import com.android.internal.app.ResolverActivity; import com.android.server.AttributeCache; import com.android.server.am.ActivityStack.ActivityState; @@ -505,19 +506,23 @@ final class ActivityRecord { } } - boolean convertToOpaque() { - if (fullscreen) { + boolean changeWindowTranslucency(boolean toOpaque) { + if (fullscreen == toOpaque) { return false; } - - AttributeCache.Entry ent = AttributeCache.instance().get(packageName, - realTheme, com.android.internal.R.styleable.Window); - if (ent != null && !ent.array.getBoolean( - com.android.internal.R.styleable.Window_windowIsFloating, false)) { - fullscreen = true; - ++task.numFullscreen; + AttributeCache.Entry ent = + AttributeCache.instance().get(packageName, realTheme, styleable.Window); + if (ent == null + || !ent.array.getBoolean(styleable.Window_windowIsTranslucent, false) + || ent.array.getBoolean(styleable.Window_windowIsFloating, false)) { + return false; } - return fullscreen; + + // Keep track of the number of fullscreen activities in this task. + task.numFullscreen += toOpaque ? +1 : -1; + + fullscreen = toOpaque; + return true; } void putInHistory() { diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index 98b3ce9..be03ee3 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -118,6 +118,10 @@ final class ActivityStack { // is being started. static final boolean SHOW_APP_STARTING_PREVIEW = true; + // How long to wait for all background Activities to redraw following a call to + // convertToTranslucent(). + static final long TRANSLUCENT_CONVERSION_TIMEOUT = 2000; + enum ActivityState { INITIALIZING, RESUMED, @@ -184,6 +188,16 @@ final class ActivityStack { */ ActivityRecord mLastStartedActivity = null; + // The topmost Activity passed to convertToTranslucent(). When non-null it means we are + // waiting for all Activities in mUndrawnActivitiesBelowTopTranslucent to be removed as they + // are drawn. When the last member of mUndrawnActivitiesBelowTopTranslucent is removed the + // Activity in mTranslucentActivityWaiting is notified via + // Activity.onTranslucentConversionComplete(false). If a timeout occurs prior to the last + // background activity being drawn then the same call will be made with a true value. + ActivityRecord mTranslucentActivityWaiting = null; + ArrayList<ActivityRecord> mUndrawnActivitiesBelowTopTranslucent = + new ArrayList<ActivityRecord>(); + /** * Set when we know we are going to be calling updateConfiguration() * soon, so want to skip intermediate config checks. @@ -215,6 +229,7 @@ final class ActivityStack { static final int LAUNCH_TICK_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 3; static final int STOP_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 4; static final int DESTROY_ACTIVITIES_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 5; + static final int TRANSLUCENT_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 6; static class ScheduleDestroyArgs { final ProcessRecord mOwner; @@ -285,7 +300,12 @@ final class ActivityStack { synchronized (mService) { destroyActivitiesLocked(args.mOwner, args.mOomAdj, args.mReason); } - } + } break; + case TRANSLUCENT_TIMEOUT_MSG: { + synchronized (mService) { + notifyActivityDrawnLocked(null); + } + } break; } } } @@ -952,6 +972,16 @@ final class ActivityStack { TAG, "ensureActivitiesVisible behind " + top + " configChanges=0x" + Integer.toHexString(configChanges)); + if (mTranslucentActivityWaiting != top) { + mUndrawnActivitiesBelowTopTranslucent.clear(); + if (mTranslucentActivityWaiting != null) { + // Call the callback with a timeout indication. + notifyActivityDrawnLocked(null); + mTranslucentActivityWaiting = null; + } + mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG); + } + // If the top activity is not fullscreen, then we need to // make sure any activities under it are now visible. boolean aboveTop = true; @@ -1018,6 +1048,9 @@ final class ActivityStack { if (DEBUG_VISBILITY) Slog.v( TAG, "Making visible and scheduling visibility: " + r); try { + if (mTranslucentActivityWaiting != null) { + mUndrawnActivitiesBelowTopTranslucent.add(r); + } mWindowManager.setAppVisibility(r.appToken, true); r.sleeping = false; r.app.pendingUiClean = true; @@ -1091,6 +1124,42 @@ final class ActivityStack { return showHomeBehindStack; } + void convertToTranslucent(ActivityRecord r) { + mTranslucentActivityWaiting = r; + mUndrawnActivitiesBelowTopTranslucent.clear(); + mHandler.sendEmptyMessageDelayed(TRANSLUCENT_TIMEOUT_MSG, TRANSLUCENT_CONVERSION_TIMEOUT); + } + + /** + * Called as activities below the top translucent activity are redrawn. When the last one is + * redrawn notify the top activity by calling + * {@link Activity#onTranslucentConversionComplete}. + * + * @param r The most recent background activity to be drawn. Or, if r is null then a timeout + * occurred and the activity will be notified immediately. + */ + void notifyActivityDrawnLocked(ActivityRecord r) { + if ((r == null) + || (mUndrawnActivitiesBelowTopTranslucent.remove(r) && + mUndrawnActivitiesBelowTopTranslucent.isEmpty())) { + // The last undrawn activity below the top has just been drawn. If there is an + // opaque activity at the top, notify it that it can become translucent safely now. + final ActivityRecord waitingActivity = mTranslucentActivityWaiting; + mTranslucentActivityWaiting = null; + mUndrawnActivitiesBelowTopTranslucent.clear(); + mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG); + + if (waitingActivity != null && waitingActivity.app != null && + waitingActivity.app.thread != null) { + try { + waitingActivity.app.thread.scheduleTranslucentConversionComplete( + waitingActivity.appToken, r != null); + } catch (RemoteException e) { + } + } + } + } + /** * Ensure that the top activity in the stack is resumed. * diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java index 63f91ac..d39798d 100644 --- a/services/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/java/com/android/server/am/ActivityStackSupervisor.java @@ -2475,8 +2475,7 @@ public final class ActivityStackSupervisor { public void handleMessage(Message msg) { switch (msg.what) { case IDLE_TIMEOUT_MSG: { - if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: Callers=" + - Debug.getCallers(4)); + if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: r=" + msg.obj); if (mService.mDidDexOpt) { mService.mDidDexOpt = false; Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); @@ -2489,6 +2488,7 @@ public final class ActivityStackSupervisor { activityIdleInternal((ActivityRecord)msg.obj); } break; case IDLE_NOW_MSG: { + if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj); activityIdleInternal((ActivityRecord)msg.obj); } break; case RESUME_TOP_ACTIVITY_MSG: { diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index ee2ef37..50d267f 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -25,6 +25,7 @@ import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; import android.app.AppOpsManager; import android.util.TimeUtils; import android.view.IWindowId; + import com.android.internal.app.IBatteryStats; import com.android.internal.policy.PolicyManager; import com.android.internal.policy.impl.PhoneWindowManager; @@ -4117,10 +4118,11 @@ public class WindowManagerService extends IWindowManager.Stub } } - public void setAppFullscreen(IBinder token) { + public void setAppFullscreen(IBinder token, boolean toOpaque) { AppWindowToken atoken = findAppWindowToken(token); if (atoken != null) { - atoken.appFullscreen = true; + atoken.appFullscreen = toOpaque; + requestTraversal(); } } @@ -7020,6 +7022,7 @@ public class WindowManagerService extends IWindowManager.Stub public static final int CLIENT_FREEZE_TIMEOUT = 30; public static final int TAP_OUTSIDE_STACK = 31; + public static final int NOTIFY_ACTIVITY_DRAWN = 32; @Override public void handleMessage(Message msg) { @@ -7452,6 +7455,13 @@ public class WindowManagerService extends IWindowManager.Stub } } } + break; + case NOTIFY_ACTIVITY_DRAWN: + try { + mActivityManager.notifyActivityDrawn((IBinder) msg.obj); + } catch (RemoteException e) { + } + break; } if (DEBUG_WINDOW_TRACE) { Slog.v(TAG, "handleMessage: exit"); @@ -8759,6 +8769,7 @@ public class WindowManagerService extends IWindowManager.Stub + " interesting=" + numInteresting + " drawn=" + wtoken.numDrawnWindows); wtoken.allDrawn = true; + mH.obtainMessage(H.NOTIFY_ACTIVITY_DRAWN, wtoken.token).sendToTarget(); } } } |