diff options
14 files changed, 253 insertions, 72 deletions
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index 1954774e1177..99852b8db5e7 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -2882,6 +2882,11 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM reply.writeInt(isForeground ? 1 : 0); return true; } + case NOTIFY_PINNED_STACK_ANIMATION_ENDED_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + reply.writeNoException(); + return true; + } } return super.onTransact(code, data, reply, flags); @@ -6732,5 +6737,15 @@ class ActivityManagerProxy implements IActivityManager return isForeground; }; + @Override + public void notifyPinnedStackAnimationEnded() throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + mRemote.transact(NOTIFY_PINNED_STACK_ANIMATION_ENDED_TRANSACTION, data, reply, 0); + data.recycle(); + reply.recycle(); + }; + private IBinder mRemote; } diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index b5ca6ee5a343..98ce2734bc88 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -597,6 +597,8 @@ public interface IActivityManager extends IInterface { public boolean supportsLocalVoiceInteraction() throws RemoteException; + public void notifyPinnedStackAnimationEnded() throws RemoteException; + /* * Private non-Binder interfaces */ @@ -972,4 +974,5 @@ public interface IActivityManager extends IInterface { int START_LOCAL_VOICE_INTERACTION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 363; int STOP_LOCAL_VOICE_INTERACTION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 364; int SUPPORTS_LOCAL_VOICE_INTERACTION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 365; + int NOTIFY_PINNED_STACK_ANIMATION_ENDED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 366; } diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl index fa1123423e35..643255822cb9 100644 --- a/core/java/android/app/ITaskStackListener.aidl +++ b/core/java/android/app/ITaskStackListener.aidl @@ -30,4 +30,9 @@ oneway interface ITaskStackListener { * brought to the front or a new Intent is delivered to it. */ void onPinnedActivityRestartAttempt(); + + /** + * Called whenever the pinned stack is done animating a resize. + */ + void onPinnedStackAnimationEnded(); } diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java index 5890b5f959d3..9da5c2bd3f02 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java @@ -124,6 +124,10 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener public void onPinnedActivityRestartAttempt() { } + @Override + public void onPinnedStackAnimationEnded() { + } + /** Preloads the next task */ public void run() { RecentsConfiguration config = Recents.getConfiguration(); diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java index 42ebfa95c662..f3201d0346b4 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java +++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java @@ -318,13 +318,13 @@ public class RecentsTvActivity extends Activity implements OnPreDrawListener { switch (keyCode) { case KeyEvent.KEYCODE_DPAD_UP: { SystemServicesProxy ssp = Recents.getSystemServices(); - PipManager.getInstance().showPipMenu(); + PipManager.getInstance().resizePinnedStack(PipManager.STATE_PIP_MENU); ssp.focusPinnedStack(); return true; } case KeyEvent.KEYCODE_DPAD_DOWN: { SystemServicesProxy ssp = Recents.getSystemServices(); - PipManager.getInstance().showPipOverlay(false); + PipManager.getInstance().resizePinnedStack(PipManager.STATE_PIP_OVERLAY); ssp.focusHomeStack(); return true; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java index e20936b7dec4..08cd053b5903 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java @@ -109,6 +109,10 @@ public class CarStatusBar extends PhoneStatusBar { } @Override + public void onPinnedStackAnimationEnded() { + } + + @Override public void onTaskStackChanged() { mHandler.removeCallbacks(this); mHandler.post(this); diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java index 3e47d8571fad..3c3041016710 100644 --- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java +++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java @@ -28,6 +28,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.res.Resources; import android.graphics.Rect; +import android.os.Debug; import android.os.Handler; import android.os.RemoteException; import android.util.Log; @@ -53,13 +54,17 @@ public class PipManager { private static final int MAX_RUNNING_TASKS_COUNT = 10; - private static final int STATE_NO_PIP = 0; - private static final int STATE_PIP_OVERLAY = 1; - private static final int STATE_PIP_MENU = 2; + public static final int STATE_NO_PIP = 0; + public static final int STATE_PIP_OVERLAY = 1; + public static final int STATE_PIP_MENU = 2; private static final int TASK_ID_NO_PIP = -1; private static final int INVALID_RESOURCE_TYPE = -1; + public static final int SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_MENU_ACTIVITY_FINISH = 0x1; + public static final int SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_OVERLAY_ACTIVITY_FINISH = 0x2; + private int mSuspendPipResizingReason; + private Context mContext; private IActivityManager mActivityManager; private int mState = STATE_NO_PIP; @@ -87,7 +92,8 @@ public class PipManager { } if (DEBUG) Log.d(TAG, "PINNED_STACK:" + stackInfo); mPipTaskId = stackInfo.taskIds[stackInfo.taskIds.length - 1]; - showPipOverlay(false); + // Set state to overlay so we show it when the pinned stack animation ends. + mState = STATE_PIP_OVERLAY; launchPipOnboardingActivityIfNeeded(); } }; @@ -105,6 +111,23 @@ public class PipManager { movePipToFullscreen(); } }; + private final Runnable mOnPinnedStackAnimationEnded = new Runnable() { + @Override + public void run() { + if (mState == STATE_PIP_OVERLAY) { + showPipOverlay(); + } else if (mState == STATE_PIP_MENU) { + showPipMenu(); + } + } + }; + + private final Runnable mResizePinnedStackRunnable = new Runnable() { + @Override + public void run() { + resizePinnedStack(mState); + } + }; private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override @@ -164,7 +187,7 @@ public class PipManager { if (!hasPipTasks()) { startPip(); } else if (mState == STATE_PIP_OVERLAY) { - showPipMenu(); + resizePinnedStack(STATE_PIP_MENU); } } @@ -210,11 +233,7 @@ public class PipManager { for (int i = mListeners.size() - 1; i >= 0; --i) { mListeners.get(i).onMoveToFullscreen(); } - try { - mActivityManager.moveTasksToFullscreenStack(PINNED_STACK_ID, true); - } catch (RemoteException e) { - Log.e(TAG, "moveTasksToFullscreenStack failed", e); - } + resizePinnedStack(mState); } /** @@ -222,25 +241,83 @@ public class PipManager { * stack to the default PIP bound {@link com.android.internal.R.string * .config_defaultPictureInPictureBounds}. */ - public void showPipOverlay(boolean resizeStack) { + private void showPipOverlay() { if (DEBUG) Log.d(TAG, "showPipOverlay()"); mState = STATE_PIP_OVERLAY; Intent intent = new Intent(mContext, PipOverlayActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); final ActivityOptions options = ActivityOptions.makeBasic(); options.setLaunchStackId(PINNED_STACK_ID); - if (resizeStack) { - options.setLaunchBounds(mPipBound); - } mContext.startActivity(intent, options.toBundle()); } /** + * Suspends resizing operation on the Pip until {@link #resumePipResizing} is called + * @param reason The reason for suspending resizing operations on the Pip. + */ + public void suspendPipResizing(int reason) { + if (DEBUG) Log.d(TAG, + "suspendPipResizing() reason=" + reason + " callers=" + Debug.getCallers(2)); + mSuspendPipResizingReason |= reason; + } + + /** + * Resumes resizing operation on the Pip that was previously suspended. + * @param reason The reason resizing operations on the Pip was suspended. + */ + public void resumePipResizing(int reason) { + if ((mSuspendPipResizingReason & reason) == 0) { + return; + } + if (DEBUG) Log.d(TAG, + "resumePipResizing() reason=" + reason + " callers=" + Debug.getCallers(2)); + mSuspendPipResizingReason &= ~reason; + mHandler.post(mResizePinnedStackRunnable); + } + + /** + * Resize the Pip to the appropriate size for the input state. + * @param state In Pip state also used to determine the new size for the Pip. + */ + public void resizePinnedStack(int state) { + if (DEBUG) Log.d(TAG, "resizePinnedStack() state=" + state); + mState = state; + Rect bounds; + for (int i = mListeners.size() - 1; i >= 0; --i) { + mListeners.get(i).onPipResizeAboutToStart(); + } + switch (mState) { + case STATE_PIP_MENU: + bounds = mMenuModePipBound; + break; + case STATE_NO_PIP: + bounds = null; + break; + default: + bounds = mPipBound; + break; + } + + if (mSuspendPipResizingReason != 0) { + if (DEBUG) Log.d(TAG, + "resizePinnedStack() deferring mSuspendPipResizingReason=" + + mSuspendPipResizingReason); + return; + } + + try { + mActivityManager.resizeStack(PINNED_STACK_ID, bounds, true, true, true); + } catch (RemoteException e) { + Log.e(TAG, "showPipMenu failed", e); + } + } + + /** * Shows PIP menu UI by launching {@link PipMenuActivity}. It also locates the pinned * stack to the centered PIP bound {@link com.android.internal.R.string * .config_centeredPictureInPictureBounds}. */ - public void showPipMenu() { + private void showPipMenu() { if (DEBUG) Log.d(TAG, "showPipMenu()"); mState = STATE_PIP_MENU; for (int i = mListeners.size() - 1; i >= 0; --i) { @@ -250,20 +327,13 @@ public class PipManager { intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); final ActivityOptions options = ActivityOptions.makeBasic(); options.setLaunchStackId(PINNED_STACK_ID); - options.setLaunchBounds(mMenuModePipBound); mContext.startActivity(intent, options.toBundle()); } - /** - * Adds {@link Listener}. - */ public void addListener(Listener listener) { mListeners.add(listener); } - /** - * Removes {@link Listener}. - */ public void removeListener(Listener listener) { mListeners.remove(listener); } @@ -338,32 +408,36 @@ public class PipManager { @Override public void onActivityPinned() throws RemoteException { // Post the message back to the UI thread. + if (DEBUG) Log.d(TAG, "onActivityPinned()"); mHandler.post(mOnActivityPinnedRunnable); } @Override public void onPinnedActivityRestartAttempt() { // Post the message back to the UI thread. + if (DEBUG) Log.d(TAG, "onPinnedActivityRestartAttempt()"); mHandler.post(mOnPinnedActivityRestartAttempt); } + + @Override + public void onPinnedStackAnimationEnded() { + if (DEBUG) Log.d(TAG, "onPinnedStackAnimationEnded()"); + mHandler.post(mOnPinnedStackAnimationEnded); + } } /** * A listener interface to receive notification on changes in PIP. */ public interface Listener { - /** - * Invoked when a PIPed activity is closed. - */ + /** Invoked when a PIPed activity is closed. */ void onPipActivityClosed(); - /** - * Invoked when the PIP menu gets shown. - */ + /** Invoked when the PIP menu gets shown. */ void onShowPipMenu(); - /** - * Invoked when the PIPed activity is returned back to the fullscreen. - */ + /** Invoked when the PIPed activity is returned back to the fullscreen. */ void onMoveToFullscreen(); + /** Invoked when we are above to start resizing the Pip. */ + void onPipResizeAboutToStart(); } /** diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java index 15c55f5b26ff..7e229d4b90f4 100644 --- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java +++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java @@ -54,7 +54,7 @@ public class PipMenuActivity extends Activity implements PipManager.Listener { findViewById(R.id.cancel).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - mPipManager.showPipOverlay(true); + mPipManager.resizePinnedStack(PipManager.STATE_PIP_OVERLAY); finish(); } }); @@ -62,13 +62,15 @@ public class PipMenuActivity extends Activity implements PipManager.Listener { @Override protected void onDestroy() { - mPipManager.removeListener(this); super.onDestroy(); + mPipManager.removeListener(this); + mPipManager.resumePipResizing( + PipManager.SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_MENU_ACTIVITY_FINISH); } @Override public void onBackPressed() { - mPipManager.showPipOverlay(true); + mPipManager.resizePinnedStack(PipManager.STATE_PIP_OVERLAY); finish(); } @@ -84,4 +86,11 @@ public class PipMenuActivity extends Activity implements PipManager.Listener { public void onMoveToFullscreen() { finish(); } + + @Override + public void onPipResizeAboutToStart() { + finish(); + mPipManager.suspendPipResizing( + PipManager.SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_MENU_ACTIVITY_FINISH); + } } diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipOnboardingActivity.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipOnboardingActivity.java index a0b913ab9b2c..6f71c92f89db 100644 --- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipOnboardingActivity.java +++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipOnboardingActivity.java @@ -62,4 +62,8 @@ public class PipOnboardingActivity extends Activity implements PipManager.Listen public void onMoveToFullscreen() { finish(); } + + @Override + public void onPipResizeAboutToStart() { + } } diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java index bc59a8cb4995..b40793563b37 100644 --- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java +++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java @@ -19,8 +19,8 @@ package com.android.systemui.tv.pip; import android.app.Activity; import android.os.Bundle; import android.os.Handler; -import android.view.View; +import android.view.View; import com.android.systemui.R; /** @@ -30,25 +30,37 @@ public class PipOverlayActivity extends Activity implements PipManager.Listener private static final String TAG = "PipOverlayActivity"; private static final boolean DEBUG = false; - private static final long SHOW_GUIDE_OVERLAY_VIEW_DURATION_MS = 2000; + private static final long SHOW_GUIDE_OVERLAY_VIEW_DURATION_MS = 4000; private final PipManager mPipManager = PipManager.getInstance(); private final Handler mHandler = new Handler(); + private View mGuideOverlayView; + private final Runnable mHideGuideOverlayRunnable = new Runnable() { + public void run() { + mGuideOverlayView.setVisibility(View.INVISIBLE); + } + }; @Override protected void onCreate(Bundle bundle) { super.onCreate(bundle); setContentView(R.layout.tv_pip_overlay); + mGuideOverlayView = findViewById(R.id.guide_overlay); mPipManager.addListener(this); - final View overlayView = findViewById(R.id.guide_overlay); - // TODO: apply animation - overlayView.setVisibility(View.VISIBLE); - mHandler.postDelayed(new Runnable() { - @Override - public void run() { - overlayView.setVisibility(View.INVISIBLE); - } - }, SHOW_GUIDE_OVERLAY_VIEW_DURATION_MS); + } + + @Override + protected void onStart() { + super.onStart(); + mHandler.removeCallbacks(mHideGuideOverlayRunnable); + mHandler.postDelayed(mHideGuideOverlayRunnable, SHOW_GUIDE_OVERLAY_VIEW_DURATION_MS); + } + + @Override + protected void onStop() { + super.onStop(); + mHandler.removeCallbacks(mHideGuideOverlayRunnable); + finish(); } @Override @@ -56,6 +68,8 @@ public class PipOverlayActivity extends Activity implements PipManager.Listener super.onDestroy(); mHandler.removeCallbacksAndMessages(null); mPipManager.removeListener(this); + mPipManager.resumePipResizing( + PipManager.SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_OVERLAY_ACTIVITY_FINISH); } @Override @@ -72,4 +86,11 @@ public class PipOverlayActivity extends Activity implements PipManager.Listener public void onMoveToFullscreen() { finish(); } + + @Override + public void onPipResizeAboutToStart() { + finish(); + mPipManager.suspendPipResizing( + PipManager.SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_OVERLAY_ACTIVITY_FINISH); + } } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index e25fa1b8f2b6..104217a63104 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -1451,6 +1451,7 @@ public final class ActivityManagerService extends ActivityManagerNative static final int VR_MODE_CHANGE_MSG = 63; static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64; static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65; + static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66; static final int FIRST_ACTIVITY_STACK_MSG = 100; static final int FIRST_BROADCAST_QUEUE_MSG = 200; @@ -1979,6 +1980,20 @@ public final class ActivityManagerService extends ActivityManagerNative } break; } + case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: { + synchronized (ActivityManagerService.this) { + for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) { + try { + // Make a one-way callback to the listener + mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded(); + } catch (RemoteException e){ + // Handled by the RemoteCallbackList + } + } + mTaskStackListeners.finishBroadcast(); + } + break; + } case NOTIFY_CLEARTEXT_NETWORK_MSG: { final int uid = msg.arg1; final byte[] firstPacket = (byte[]) msg.obj; @@ -7161,8 +7176,8 @@ public final class ActivityManagerService extends ActivityManagerNative final Rect bounds = (mStackSupervisor.getStack(PINNED_STACK_ID) == null) ? mDefaultPinnedStackBounds : null; - mStackSupervisor.moveActivityToStackLocked( - r, PINNED_STACK_ID, "enterPictureInPicture", bounds); + mStackSupervisor.moveActivityToPinnedStackLocked( + r, "enterPictureInPicture", bounds); } } finally { Binder.restoreCallingIdentity(origId); @@ -11057,6 +11072,16 @@ public final class ActivityManagerService extends ActivityManagerNative mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget(); } + /** Notifies all listeners when the pinned stack animation ends. */ + @Override + public void notifyPinnedStackAnimationEnded() { + synchronized (this) { + mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG); + mHandler.obtainMessage( + NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget(); + } + } + @Override public void notifyCleartextNetwork(int uid, byte[] firstPacket) { mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget(); diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 0beef53cbb70..26108a362273 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -148,6 +148,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS; import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; +import static com.android.server.am.ActivityManagerService.ANIMATE; import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG; import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE; import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE; @@ -2321,36 +2322,44 @@ public final class ActivityStackSupervisor implements DisplayListener { return false; } - moveActivityToStackLocked(r, PINNED_STACK_ID, "moveTopActivityToPinnedStack", null); - mWindowManager.animateResizePinnedStack(bounds); + moveActivityToPinnedStackLocked(r, "moveTopActivityToPinnedStack", bounds); return true; } - void moveActivityToStackLocked(ActivityRecord r, int stackId, String reason, Rect bounds) { - final TaskRecord task = r.task; - if (task.mActivities.size() == 1) { - // There is only one activity in the task. So, we can just move the task over to the - // stack without re-parenting the activity in a different task. - moveTaskToStackLocked( - task.taskId, stackId, ON_TOP, FORCE_FOCUS, reason, true /* animate */); - } else { - final ActivityStack stack = getStack(stackId, CREATE_IF_NEEDED, ON_TOP); - stack.moveActivityToStack(r); - } - - if (bounds != null) { - resizeStackLocked(stackId, bounds, null /* tempTaskBounds */, - null /* tempTaskInsetBounds */, !PRESERVE_WINDOWS, true); + void moveActivityToPinnedStackLocked(ActivityRecord r, String reason, Rect bounds) { + mWindowManager.deferSurfaceLayout(); + try { + final TaskRecord task = r.task; + + // Need to make sure the pinned stack exist so we can resize it below... + final ActivityStack stack = getStack(PINNED_STACK_ID, CREATE_IF_NEEDED, ON_TOP); + + // Resize the pinned stack to match the current size of the task the activity we are + // going to be moving is currently contained in. We do this to have the right starting + // animation bounds for the pinned stack to the desired bounds the caller wants. + resizeStackLocked(PINNED_STACK_ID, task.mBounds, null /* tempTaskBounds */, + null /* tempTaskInsetBounds */, !PRESERVE_WINDOWS, + true /* allowResizeInDockedMode */); + + if (task.mActivities.size() == 1) { + // There is only one activity in the task. So, we can just move the task over to + // the stack without re-parenting the activity in a different task. + moveTaskToStackLocked( + task.taskId, PINNED_STACK_ID, ON_TOP, FORCE_FOCUS, reason, !ANIMATE); + } else { + stack.moveActivityToStack(r); + } + } finally { + mWindowManager.continueSurfaceLayout(); } - // The task might have already been running and its visibility needs to be synchronized with - // the visibility of the stack / windows. + // The task might have already been running and its visibility needs to be synchronized + // with the visibility of the stack / windows. ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); resumeFocusedStackTopActivityLocked(); - if (stackId == PINNED_STACK_ID) { - mService.notifyActivityPinnedLocked(); - } + mWindowManager.animateResizePinnedStack(bounds); + mService.notifyActivityPinnedLocked(); } void positionTaskInStackLocked(int taskId, int stackId, int position) { diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java index b360b897d1ee..28be456628ae 100644 --- a/services/core/java/com/android/server/am/ActivityStarter.java +++ b/services/core/java/com/android/server/am/ActivityStarter.java @@ -1001,7 +1001,7 @@ class ActivityStarter { // If the activity is not focusable, we can't resume it, but still would like to // make sure it becomes visible as it starts (this will also trigger entry // animation). An example of this are PIP activities. - mTargetStack.ensureActivitiesVisibleLocked(mStartActivity, 0, !PRESERVE_WINDOWS); + mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); } } else { mTargetStack.addRecentActivityLocked(mStartActivity); diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index a8b728923265..7244676c8abd 100644 --- a/services/core/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -38,6 +38,7 @@ import java.util.ArrayList; import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT; import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID; +import static android.app.ActivityManager.StackId.PINNED_STACK_ID; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.view.WindowManager.DOCKED_BOTTOM; import static android.view.WindowManager.DOCKED_INVALID; @@ -945,6 +946,13 @@ public class TaskStack implements DimLayer.DimLayerUser, mDragResizing = false; mService.requestTraversal(); } + if (mStackId == PINNED_STACK_ID) { + try { + mService.mActivityManager.notifyPinnedStackAnimationEnded(); + } catch (RemoteException e) { + // I don't believe you... + } + } } @Override |