Merge "Updating Overview to work with PiP" into oc-dev
am: 0553cbcf36
Change-Id: I57d2f76567c0a92d9a282c6c8cdd0732be06873d
This commit is contained in:
@@ -30,7 +30,7 @@ oneway interface ITaskStackListener {
|
||||
void onTaskStackChanged();
|
||||
|
||||
/** Called whenever an Activity is moved to the pinned stack from another stack. */
|
||||
void onActivityPinned(String packageName);
|
||||
void onActivityPinned(String packageName, int taskId);
|
||||
|
||||
/** Called whenever an Activity is moved from the pinned stack to another stack. */
|
||||
void onActivityUnpinned();
|
||||
|
||||
@@ -31,7 +31,7 @@ public abstract class TaskStackListener extends ITaskStackListener.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityPinned(String packageName) throws RemoteException {
|
||||
public void onActivityPinned(String packageName, int taskId) throws RemoteException {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,9 +16,11 @@
|
||||
|
||||
package com.android.systemui.pip.phone;
|
||||
|
||||
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityManager.StackInfo;
|
||||
import android.app.IActivityManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
@@ -33,6 +35,8 @@ import android.view.IWindowManager;
|
||||
import android.view.WindowManagerGlobal;
|
||||
|
||||
import com.android.systemui.pip.BasePipManager;
|
||||
import com.android.systemui.recents.events.EventBus;
|
||||
import com.android.systemui.recents.events.component.ExpandPipEvent;
|
||||
import com.android.systemui.recents.misc.SystemServicesProxy;
|
||||
import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
|
||||
import com.android.systemui.statusbar.CommandQueue;
|
||||
@@ -65,7 +69,7 @@ public class PipManager implements BasePipManager {
|
||||
*/
|
||||
TaskStackListener mTaskStackListener = new TaskStackListener() {
|
||||
@Override
|
||||
public void onActivityPinned(String packageName) {
|
||||
public void onActivityPinned(String packageName, int taskId) {
|
||||
if (!checkCurrentUserId(false /* debug */)) {
|
||||
return;
|
||||
}
|
||||
@@ -186,6 +190,7 @@ public class PipManager implements BasePipManager {
|
||||
mInputConsumerController);
|
||||
mNotificationController = new PipNotificationController(context, mActivityManager,
|
||||
mTouchHandler.getMotionHelper());
|
||||
EventBus.getDefault().register(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -195,6 +200,26 @@ public class PipManager implements BasePipManager {
|
||||
mTouchHandler.onConfigurationChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Expands the PIP.
|
||||
*/
|
||||
public final void onBusEvent(ExpandPipEvent event) {
|
||||
if (event.clearThumbnailWindows) {
|
||||
try {
|
||||
StackInfo stackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
|
||||
if (stackInfo != null && stackInfo.taskIds != null) {
|
||||
SystemServicesProxy ssp = SystemServicesProxy.getInstance(mContext);
|
||||
for (int taskId : stackInfo.taskIds) {
|
||||
ssp.cancelThumbnailTransition(taskId);
|
||||
}
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
mTouchHandler.getMotionHelper().expandPip(false /* skipAnimation */);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sent from KEYCODE_WINDOW handler in PhoneWindowManager, to request the menu to be shown.
|
||||
*/
|
||||
|
||||
@@ -63,6 +63,8 @@ import android.widget.LinearLayout;
|
||||
|
||||
import com.android.systemui.Interpolators;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.recents.events.EventBus;
|
||||
import com.android.systemui.recents.events.component.HidePipMenuEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -231,6 +233,7 @@ public class PipMenuActivity extends Activity {
|
||||
super.onStop();
|
||||
|
||||
cancelDelayedFinish();
|
||||
EventBus.getDefault().unregister(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -290,6 +293,19 @@ public class PipMenuActivity extends Activity {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
public final void onBusEvent(HidePipMenuEvent event) {
|
||||
if (mMenuState != MENU_STATE_NONE) {
|
||||
// If the menu is visible in either the closed or full state, then hide the menu and
|
||||
// trigger the animation trigger afterwards
|
||||
event.getAnimationTrigger().increment();
|
||||
hideMenu(() -> {
|
||||
mHandler.post(() -> {
|
||||
event.getAnimationTrigger().decrement();
|
||||
});
|
||||
}, true /* notifyMenuVisibility */);
|
||||
}
|
||||
}
|
||||
|
||||
private void showMenu(int menuState, Rect stackBounds, Rect movementBounds,
|
||||
boolean allowMenuTimeout) {
|
||||
mAllowMenuTimeout = allowMenuTimeout;
|
||||
@@ -373,11 +389,16 @@ public class PipMenuActivity extends Activity {
|
||||
private void updateFromIntent(Intent intent) {
|
||||
mToControllerMessenger = intent.getParcelableExtra(EXTRA_CONTROLLER_MESSENGER);
|
||||
notifyActivityCallback(mMessenger);
|
||||
|
||||
// Register for HidePipMenuEvents once we notify the controller of this activity
|
||||
EventBus.getDefault().register(this);
|
||||
|
||||
ParceledListSlice actions = intent.getParcelableExtra(EXTRA_ACTIONS);
|
||||
if (actions != null) {
|
||||
mActions.clear();
|
||||
mActions.addAll(actions.getList());
|
||||
}
|
||||
|
||||
final int menuState = intent.getIntExtra(EXTRA_MENU_STATE, MENU_STATE_NONE);
|
||||
if (menuState != MENU_STATE_NONE) {
|
||||
Rect stackBounds = intent.getParcelableExtra(EXTRA_STACK_BOUNDS);
|
||||
|
||||
@@ -36,6 +36,9 @@ import android.util.Log;
|
||||
import android.view.IWindowManager;
|
||||
|
||||
import com.android.systemui.pip.phone.PipMediaController.ActionListener;
|
||||
import com.android.systemui.recents.events.EventBus;
|
||||
import com.android.systemui.recents.events.component.HidePipMenuEvent;
|
||||
import com.android.systemui.recents.misc.ReferenceCountedTrigger;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
@@ -119,6 +122,7 @@ public class PipMenuActivityController {
|
||||
// The dismiss fraction update is sent frequently, so use a temporary bundle for the message
|
||||
private Bundle mTmpDismissFractionData = new Bundle();
|
||||
|
||||
private ReferenceCountedTrigger mOnAttachDecrementTrigger;
|
||||
private boolean mStartActivityRequested;
|
||||
private Messenger mToActivityMessenger;
|
||||
private Messenger mMessenger = new Messenger(new Handler() {
|
||||
@@ -157,6 +161,10 @@ public class PipMenuActivityController {
|
||||
case MESSAGE_UPDATE_ACTIVITY_CALLBACK: {
|
||||
mToActivityMessenger = msg.replyTo;
|
||||
mStartActivityRequested = false;
|
||||
if (mOnAttachDecrementTrigger != null) {
|
||||
mOnAttachDecrementTrigger.decrement();
|
||||
mOnAttachDecrementTrigger = null;
|
||||
}
|
||||
// Mark the menu as invisible once the activity finishes as well
|
||||
if (mToActivityMessenger == null) {
|
||||
onMenuStateChanged(MENU_STATE_NONE, true /* resize */);
|
||||
@@ -181,6 +189,8 @@ public class PipMenuActivityController {
|
||||
mActivityManager = activityManager;
|
||||
mMediaController = mediaController;
|
||||
mInputConsumerController = inputConsumerController;
|
||||
|
||||
EventBus.getDefault().register(this);
|
||||
}
|
||||
|
||||
public void onActivityPinned() {
|
||||
@@ -435,6 +445,15 @@ public class PipMenuActivityController {
|
||||
mMenuState = menuState;
|
||||
}
|
||||
|
||||
public final void onBusEvent(HidePipMenuEvent event) {
|
||||
if (mStartActivityRequested) {
|
||||
// If the menu has been start-requested, but not actually started, then we defer the
|
||||
// trigger callback until the menu has started and called back to the controller
|
||||
mOnAttachDecrementTrigger = event.getAnimationTrigger();
|
||||
mOnAttachDecrementTrigger.increment();
|
||||
}
|
||||
}
|
||||
|
||||
public void dump(PrintWriter pw, String prefix) {
|
||||
final String innerPrefix = prefix + " ";
|
||||
pw.println(prefix + TAG);
|
||||
|
||||
@@ -612,7 +612,7 @@ public class PipManager implements BasePipManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityPinned(String packageName) {
|
||||
public void onActivityPinned(String packageName, int taskId) {
|
||||
if (DEBUG) Log.d(TAG, "onActivityPinned()");
|
||||
if (!checkCurrentUserId(DEBUG)) {
|
||||
return;
|
||||
|
||||
@@ -62,6 +62,7 @@ import com.android.systemui.recents.events.activity.LaunchTaskFailedEvent;
|
||||
import com.android.systemui.recents.events.activity.LaunchTaskSucceededEvent;
|
||||
import com.android.systemui.recents.events.activity.MultiWindowStateChangedEvent;
|
||||
import com.android.systemui.recents.events.activity.ToggleRecentsEvent;
|
||||
import com.android.systemui.recents.events.component.ActivityUnpinnedEvent;
|
||||
import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
|
||||
import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
|
||||
import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent;
|
||||
@@ -205,6 +206,10 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
|
||||
}
|
||||
Settings.Secure.putLongForUser(RecentsActivity.this.getContentResolver(),
|
||||
Secure.OVERVIEW_LAST_STACK_ACTIVE_TIME, currentTime, currentUser);
|
||||
|
||||
// Clear the last PiP task time, it's an edge case and we'd rather it
|
||||
// not relaunch the PiP task if the user double taps
|
||||
RecentsImpl.clearLastPipTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -395,6 +400,7 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
|
||||
* Reloads the stack views upon launching Recents.
|
||||
*/
|
||||
private void reloadStackView() {
|
||||
|
||||
// If the Recents component has preloaded a load plan, then use that to prevent
|
||||
// reconstructing the task stack
|
||||
RecentsTaskLoader loader = Recents.getTaskLoader();
|
||||
@@ -501,28 +507,7 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
|
||||
public void onMultiWindowModeChanged(boolean isInMultiWindowMode) {
|
||||
super.onMultiWindowModeChanged(isInMultiWindowMode);
|
||||
|
||||
// Reload the task stack completely
|
||||
RecentsConfiguration config = Recents.getConfiguration();
|
||||
RecentsActivityLaunchState launchState = config.getLaunchState();
|
||||
RecentsTaskLoader loader = Recents.getTaskLoader();
|
||||
RecentsTaskLoadPlan loadPlan = loader.createLoadPlan(this);
|
||||
loader.preloadTasks(loadPlan, -1 /* runningTaskId */,
|
||||
false /* includeFrontMostExcludedTask */);
|
||||
|
||||
RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
|
||||
loadOpts.numVisibleTasks = launchState.launchedNumVisibleTasks;
|
||||
loadOpts.numVisibleTaskThumbnails = launchState.launchedNumVisibleThumbnails;
|
||||
loader.loadTasks(this, loadPlan, loadOpts);
|
||||
|
||||
TaskStack stack = loadPlan.getTaskStack();
|
||||
int numStackTasks = stack.getStackTaskCount();
|
||||
boolean showDeferredAnimation = numStackTasks > 0;
|
||||
|
||||
EventBus.getDefault().send(new ConfigurationChangedEvent(true /* fromMultiWindow */,
|
||||
false /* fromDeviceOrientationChange */, false /* fromDisplayDensityChange */,
|
||||
numStackTasks > 0));
|
||||
EventBus.getDefault().send(new MultiWindowStateChangedEvent(isInMultiWindowMode,
|
||||
showDeferredAnimation, stack));
|
||||
reloadTaskStack(isInMultiWindowMode, true /* sendConfigChangedEvent */);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -821,6 +806,41 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
|
||||
mRecentsView.invalidate();
|
||||
}
|
||||
|
||||
public final void onBusEvent(final ActivityUnpinnedEvent event) {
|
||||
if (mIsVisible) {
|
||||
// Skip the configuration change event as the PiP activity does not actually affect the
|
||||
// config of recents
|
||||
reloadTaskStack(isInMultiWindowMode(), false /* sendConfigChangedEvent */);
|
||||
}
|
||||
}
|
||||
|
||||
private void reloadTaskStack(boolean isInMultiWindowMode, boolean sendConfigChangedEvent) {
|
||||
// Reload the task stack completely
|
||||
RecentsConfiguration config = Recents.getConfiguration();
|
||||
RecentsActivityLaunchState launchState = config.getLaunchState();
|
||||
RecentsTaskLoader loader = Recents.getTaskLoader();
|
||||
RecentsTaskLoadPlan loadPlan = loader.createLoadPlan(this);
|
||||
loader.preloadTasks(loadPlan, -1 /* runningTaskId */,
|
||||
false /* includeFrontMostExcludedTask */);
|
||||
|
||||
RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
|
||||
loadOpts.numVisibleTasks = launchState.launchedNumVisibleTasks;
|
||||
loadOpts.numVisibleTaskThumbnails = launchState.launchedNumVisibleThumbnails;
|
||||
loader.loadTasks(this, loadPlan, loadOpts);
|
||||
|
||||
TaskStack stack = loadPlan.getTaskStack();
|
||||
int numStackTasks = stack.getStackTaskCount();
|
||||
boolean showDeferredAnimation = numStackTasks > 0;
|
||||
|
||||
if (sendConfigChangedEvent) {
|
||||
EventBus.getDefault().send(new ConfigurationChangedEvent(true /* fromMultiWindow */,
|
||||
false /* fromDeviceOrientationChange */, false /* fromDisplayDensityChange */,
|
||||
numStackTasks > 0));
|
||||
}
|
||||
EventBus.getDefault().send(new MultiWindowStateChangedEvent(isInMultiWindowMode,
|
||||
showDeferredAnimation, stack));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreDraw() {
|
||||
mRecentsView.getViewTreeObserver().removeOnPreDrawListener(this);
|
||||
|
||||
@@ -29,6 +29,10 @@ public class RecentsActivityLaunchState {
|
||||
|
||||
public boolean launchedWithAltTab;
|
||||
public boolean launchedFromApp;
|
||||
// Set if the activity that we launched from entered PiP during the transition into Recents
|
||||
public boolean launchedFromPipApp;
|
||||
// Set if the next activity that quick-switch will launch is the PiP activity
|
||||
public boolean launchedWithNextPipApp;
|
||||
public boolean launchedFromBlacklistedApp;
|
||||
public boolean launchedFromHome;
|
||||
public boolean launchedViaDragGesture;
|
||||
@@ -41,6 +45,8 @@ public class RecentsActivityLaunchState {
|
||||
launchedFromHome = false;
|
||||
launchedFromApp = false;
|
||||
launchedFromBlacklistedApp = false;
|
||||
launchedFromPipApp = false;
|
||||
launchedWithNextPipApp = false;
|
||||
launchedToTaskId = -1;
|
||||
launchedWithAltTab = false;
|
||||
launchedViaDragGesture = false;
|
||||
|
||||
@@ -57,6 +57,9 @@ import com.android.systemui.recents.events.activity.LaunchMostRecentTaskRequestE
|
||||
import com.android.systemui.recents.events.activity.LaunchNextTaskRequestEvent;
|
||||
import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
|
||||
import com.android.systemui.recents.events.activity.ToggleRecentsEvent;
|
||||
import com.android.systemui.recents.events.component.ActivityPinnedEvent;
|
||||
import com.android.systemui.recents.events.component.ActivityUnpinnedEvent;
|
||||
import com.android.systemui.recents.events.component.HidePipMenuEvent;
|
||||
import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
|
||||
import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
|
||||
import com.android.systemui.recents.events.ui.DraggingInRecentsEndedEvent;
|
||||
@@ -127,6 +130,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
|
||||
// previous one.
|
||||
VisibilityReport visibilityReport;
|
||||
synchronized (mDummyStackView) {
|
||||
mDummyStackView.getStack().removeAllTasks(false /* notifyStackChanges */);
|
||||
mDummyStackView.setTasks(plan.getTaskStack(), false /* allowNotify */);
|
||||
updateDummyStackViewLayout(plan.getTaskStack(),
|
||||
getWindowRect(null /* windowRectOverride */));
|
||||
@@ -150,6 +154,23 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityPinned(String packageName, int taskId) {
|
||||
// This time needs to be fetched the same way the last active time is fetched in
|
||||
// {@link TaskRecord#touchActiveTime}
|
||||
Recents.getConfiguration().getLaunchState().launchedFromPipApp = true;
|
||||
Recents.getConfiguration().getLaunchState().launchedWithNextPipApp = false;
|
||||
EventBus.getDefault().send(new ActivityPinnedEvent(taskId));
|
||||
consumeInstanceLoadPlan();
|
||||
sLastPipTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityUnpinned() {
|
||||
EventBus.getDefault().send(new ActivityUnpinnedEvent());
|
||||
sLastPipTime = -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) {
|
||||
EventBus.getDefault().send(new TaskSnapshotChangedEvent(taskId, snapshot));
|
||||
@@ -157,6 +178,8 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
|
||||
}
|
||||
|
||||
protected static RecentsTaskLoadPlan sInstanceLoadPlan;
|
||||
// Stores the last pinned task time
|
||||
protected static long sLastPipTime = -1;
|
||||
|
||||
protected Context mContext;
|
||||
protected Handler mHandler;
|
||||
@@ -594,6 +617,20 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
|
||||
return plan;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the time at which a task last entered picture-in-picture.
|
||||
*/
|
||||
public static long getLastPipTime() {
|
||||
return sLastPipTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the time at which a task last entered picture-in-picture.
|
||||
*/
|
||||
public static void clearLastPipTime() {
|
||||
sLastPipTime = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads all the resources for the current configuration.
|
||||
*/
|
||||
@@ -676,6 +713,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
|
||||
updateDummyStackViewLayout(stack, windowRect);
|
||||
if (stack != null) {
|
||||
TaskStackLayoutAlgorithm stackLayout = mDummyStackView.getStackAlgorithm();
|
||||
mDummyStackView.getStack().removeAllTasks(false /* notifyStackChanges */);
|
||||
mDummyStackView.setTasks(stack, false /* allowNotifyStackChanges */);
|
||||
// Get the width of a task view so that we know how wide to draw the header bar.
|
||||
if (useGridLayout) {
|
||||
@@ -921,6 +959,9 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
|
||||
launchState.launchedFromHome = !useThumbnailTransition && !mLaunchedWhileDocking;
|
||||
launchState.launchedFromApp = useThumbnailTransition || mLaunchedWhileDocking;
|
||||
launchState.launchedFromBlacklistedApp = launchState.launchedFromApp && isBlacklisted;
|
||||
launchState.launchedFromPipApp = false;
|
||||
launchState.launchedWithNextPipApp =
|
||||
stack.isNextLaunchTargetPip(RecentsImpl.getLastPipTime());
|
||||
launchState.launchedViaDockGesture = mLaunchedWhileDocking;
|
||||
launchState.launchedViaDragGesture = mDraggingInRecents;
|
||||
launchState.launchedToTaskId = runningTaskId;
|
||||
@@ -988,12 +1029,16 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
|
||||
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
|
||||
| Intent.FLAG_ACTIVITY_TASK_ON_HOME);
|
||||
|
||||
if (opts != null) {
|
||||
mContext.startActivityAsUser(intent, opts.toBundle(), UserHandle.CURRENT);
|
||||
} else {
|
||||
mContext.startActivityAsUser(intent, UserHandle.CURRENT);
|
||||
}
|
||||
EventBus.getDefault().send(new RecentsActivityStartingEvent());
|
||||
HidePipMenuEvent hideMenuEvent = new HidePipMenuEvent();
|
||||
hideMenuEvent.addPostAnimationCallback(() -> {
|
||||
if (opts != null) {
|
||||
mContext.startActivityAsUser(intent, opts.toBundle(), UserHandle.CURRENT);
|
||||
} else {
|
||||
mContext.startActivityAsUser(intent, UserHandle.CURRENT);
|
||||
}
|
||||
EventBus.getDefault().send(new RecentsActivityStartingEvent());
|
||||
});
|
||||
EventBus.getDefault().send(hideMenuEvent);
|
||||
}
|
||||
|
||||
/**** OnAnimationFinishedListener Implementation ****/
|
||||
|
||||
@@ -810,6 +810,11 @@ public class EventBus extends BroadcastReceiver {
|
||||
private void queueEvent(final Event event) {
|
||||
ArrayList<EventHandler> eventHandlers = mEventTypeMap.get(event.getClass());
|
||||
if (eventHandlers == null) {
|
||||
// This is just an optimization to return early if there are no handlers. However, we
|
||||
// should still ensure that we call pre/post dispatch callbacks so that AnimatedEvents
|
||||
// are still cleaned up correctly if a listener has not been registered to handle them
|
||||
event.onPreDispatch();
|
||||
event.onPostDispatch();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License
|
||||
*/
|
||||
|
||||
package com.android.systemui.recents.events.activity;
|
||||
|
||||
import com.android.systemui.recents.events.EventBus;
|
||||
|
||||
/**
|
||||
* Sent when the stack should be hidden and the empty view shown.
|
||||
*/
|
||||
public class ShowEmptyViewEvent extends EventBus.Event {
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.recents.events.component;
|
||||
|
||||
import com.android.systemui.recents.events.EventBus;
|
||||
|
||||
/**
|
||||
* This is sent when an activity is pinned.
|
||||
*/
|
||||
public class ActivityPinnedEvent extends EventBus.Event {
|
||||
|
||||
public final int taskId;
|
||||
|
||||
public ActivityPinnedEvent(int taskId) {
|
||||
this.taskId = taskId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.recents.events.component;
|
||||
|
||||
import com.android.systemui.recents.events.EventBus;
|
||||
|
||||
/**
|
||||
* This is sent when an activity is unpinned.
|
||||
*/
|
||||
public class ActivityUnpinnedEvent extends EventBus.Event {
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.recents.events.component;
|
||||
|
||||
import com.android.systemui.recents.events.EventBus;
|
||||
|
||||
/**
|
||||
* This is sent when the PiP should be expanded due to being relaunched.
|
||||
*/
|
||||
public class ExpandPipEvent extends EventBus.Event {
|
||||
public final boolean clearThumbnailWindows = true;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.recents.events.component;
|
||||
|
||||
import com.android.systemui.recents.events.EventBus;
|
||||
|
||||
/**
|
||||
* This is sent when the PiP menu should be hidden.
|
||||
*/
|
||||
public class HidePipMenuEvent extends EventBus.AnimatedEvent {
|
||||
// Simple event
|
||||
}
|
||||
@@ -163,7 +163,7 @@ public class SystemServicesProxy {
|
||||
public void onTaskStackChangedBackground() { }
|
||||
public void onTaskStackChanged() { }
|
||||
public void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) { }
|
||||
public void onActivityPinned(String packageName) { }
|
||||
public void onActivityPinned(String packageName, int taskId) { }
|
||||
public void onActivityUnpinned() { }
|
||||
public void onPinnedActivityRestartAttempt(boolean clearedTask) { }
|
||||
public void onPinnedStackAnimationStarted() { }
|
||||
@@ -218,9 +218,9 @@ public class SystemServicesProxy {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityPinned(String packageName) throws RemoteException {
|
||||
public void onActivityPinned(String packageName, int taskId) throws RemoteException {
|
||||
mHandler.removeMessages(H.ON_ACTIVITY_PINNED);
|
||||
mHandler.obtainMessage(H.ON_ACTIVITY_PINNED, packageName).sendToTarget();
|
||||
mHandler.obtainMessage(H.ON_ACTIVITY_PINNED, taskId, 0, packageName).sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -449,9 +449,18 @@ public class SystemServicesProxy {
|
||||
* Returns the top running task.
|
||||
*/
|
||||
public ActivityManager.RunningTaskInfo getRunningTask() {
|
||||
List<ActivityManager.RunningTaskInfo> tasks = mAm.getRunningTasks(1);
|
||||
// Note: The set of running tasks from the system is ordered by recency
|
||||
List<ActivityManager.RunningTaskInfo> tasks = mAm.getRunningTasks(10);
|
||||
if (tasks != null && !tasks.isEmpty()) {
|
||||
return tasks.get(0);
|
||||
// Find the first task in a valid stack, we ignore everything from the Recents and PiP
|
||||
// stacks
|
||||
for (int i = 0; i < tasks.size(); i++) {
|
||||
ActivityManager.RunningTaskInfo task = tasks.get(i);
|
||||
int stackId = task.stackId;
|
||||
if (stackId != RECENTS_STACK_ID && stackId != PINNED_STACK_ID) {
|
||||
return task;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -1314,7 +1323,7 @@ public class SystemServicesProxy {
|
||||
}
|
||||
case ON_ACTIVITY_PINNED: {
|
||||
for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
|
||||
mTaskStackListeners.get(i).onActivityPinned((String) msg.obj);
|
||||
mTaskStackListeners.get(i).onActivityPinned((String) msg.obj, msg.arg1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -229,7 +229,8 @@ public class TaskStack {
|
||||
* Notifies when a task has been removed from the stack.
|
||||
*/
|
||||
void onStackTaskRemoved(TaskStack stack, Task removedTask, Task newFrontMostTask,
|
||||
AnimationProps animation, boolean fromDockGesture);
|
||||
AnimationProps animation, boolean fromDockGesture,
|
||||
boolean dismissRecentsIfAllRemoved);
|
||||
|
||||
/**
|
||||
* Notifies when all tasks have been removed from the stack.
|
||||
@@ -631,13 +632,22 @@ public class TaskStack {
|
||||
* how they should update themselves.
|
||||
*/
|
||||
public void removeTask(Task t, AnimationProps animation, boolean fromDockGesture) {
|
||||
removeTask(t, animation, fromDockGesture, true /* dismissRecentsIfAllRemoved */);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a task from the stack, with an additional {@param animation} hint to the callbacks on
|
||||
* how they should update themselves.
|
||||
*/
|
||||
public void removeTask(Task t, AnimationProps animation, boolean fromDockGesture,
|
||||
boolean dismissRecentsIfAllRemoved) {
|
||||
if (mStackTaskList.contains(t)) {
|
||||
removeTaskImpl(mStackTaskList, t);
|
||||
Task newFrontMostTask = getStackFrontMostTask(false /* includeFreeform */);
|
||||
if (mCb != null) {
|
||||
// Notify that a task has been removed
|
||||
mCb.onStackTaskRemoved(this, t, newFrontMostTask, animation,
|
||||
fromDockGesture);
|
||||
fromDockGesture, dismissRecentsIfAllRemoved);
|
||||
}
|
||||
}
|
||||
mRawTaskList.remove(t);
|
||||
@@ -646,19 +656,27 @@ public class TaskStack {
|
||||
/**
|
||||
* Removes all tasks from the stack.
|
||||
*/
|
||||
public void removeAllTasks() {
|
||||
public void removeAllTasks(boolean notifyStackChanges) {
|
||||
ArrayList<Task> tasks = mStackTaskList.getTasks();
|
||||
for (int i = tasks.size() - 1; i >= 0; i--) {
|
||||
Task t = tasks.get(i);
|
||||
removeTaskImpl(mStackTaskList, t);
|
||||
mRawTaskList.remove(t);
|
||||
}
|
||||
if (mCb != null) {
|
||||
if (mCb != null && notifyStackChanges) {
|
||||
// Notify that all tasks have been removed
|
||||
mCb.onStackTasksRemoved(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see #setTasks(Context, List, boolean, boolean)
|
||||
*/
|
||||
public void setTasks(Context context, TaskStack stack, boolean notifyStackChanges) {
|
||||
setTasks(context, stack.mRawTaskList, notifyStackChanges);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a few tasks in one go, without calling any callbacks.
|
||||
*
|
||||
@@ -723,7 +741,8 @@ public class TaskStack {
|
||||
Task newFrontMostTask = getStackFrontMostTask(false);
|
||||
for (int i = 0; i < removedTaskCount; i++) {
|
||||
mCb.onStackTaskRemoved(this, removedTasks.get(i), newFrontMostTask,
|
||||
AnimationProps.IMMEDIATE, false /* fromDockGesture */);
|
||||
AnimationProps.IMMEDIATE, false /* fromDockGesture */,
|
||||
true /* dismissRecentsIfAllRemoved */);
|
||||
}
|
||||
|
||||
// Only callback for the newly added tasks after this stack has been updated
|
||||
@@ -853,22 +872,47 @@ public class TaskStack {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the next launch target should actually be the PiP task.
|
||||
*/
|
||||
public boolean isNextLaunchTargetPip(long lastPipTime) {
|
||||
Task launchTarget = getLaunchTarget();
|
||||
Task nextLaunchTarget = getNextLaunchTargetRaw();
|
||||
if (nextLaunchTarget != null && lastPipTime > 0) {
|
||||
// If the PiP time is more recent than the next launch target, then launch the PiP task
|
||||
return lastPipTime > nextLaunchTarget.key.lastActiveTime;
|
||||
} else if (launchTarget != null && lastPipTime > 0 && getTaskCount() == 1) {
|
||||
// Otherwise, if there is no next launch target, but there is a PiP, then launch
|
||||
// the PiP task
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the task in stack tasks which should be launched next if Recents are toggled
|
||||
* again, or null if there is no task to be launched.
|
||||
* again, or null if there is no task to be launched. Callers should check
|
||||
* {@link #isNextLaunchTargetPip(long)} before fetching the next raw launch target from the
|
||||
* stack.
|
||||
*/
|
||||
public Task getNextLaunchTarget() {
|
||||
Task nextLaunchTarget = getNextLaunchTargetRaw();
|
||||
if (nextLaunchTarget != null) {
|
||||
return nextLaunchTarget;
|
||||
}
|
||||
return getStackTasks().get(getTaskCount() - 1);
|
||||
}
|
||||
|
||||
private Task getNextLaunchTargetRaw() {
|
||||
int taskCount = getTaskCount();
|
||||
if (taskCount == 0) {
|
||||
return null;
|
||||
}
|
||||
int launchTaskIndex = indexOfStackTask(getLaunchTarget());
|
||||
if (launchTaskIndex != -1) {
|
||||
launchTaskIndex = Math.max(0, launchTaskIndex - 1);
|
||||
} else {
|
||||
launchTaskIndex = getTaskCount() - 1;
|
||||
if (launchTaskIndex != -1 && launchTaskIndex > 0) {
|
||||
return getStackTasks().get(launchTaskIndex - 1);
|
||||
}
|
||||
return getStackTasks().get(launchTaskIndex);
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Returns the index of this task in this current task stack */
|
||||
|
||||
@@ -55,7 +55,9 @@ import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationC
|
||||
import com.android.systemui.recents.events.activity.HideStackActionButtonEvent;
|
||||
import com.android.systemui.recents.events.activity.LaunchTaskEvent;
|
||||
import com.android.systemui.recents.events.activity.MultiWindowStateChangedEvent;
|
||||
import com.android.systemui.recents.events.activity.ShowEmptyViewEvent;
|
||||
import com.android.systemui.recents.events.activity.ShowStackActionButtonEvent;
|
||||
import com.android.systemui.recents.events.component.ExpandPipEvent;
|
||||
import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent;
|
||||
import com.android.systemui.recents.events.ui.DismissAllTaskViewsEvent;
|
||||
import com.android.systemui.recents.events.ui.DraggingInRecentsEndedEvent;
|
||||
@@ -250,6 +252,12 @@ public class RecentsView extends FrameLayout {
|
||||
|
||||
/** Launches the task that recents was launched from if possible */
|
||||
public boolean launchPreviousTask() {
|
||||
if (Recents.getConfiguration().getLaunchState().launchedFromPipApp) {
|
||||
// If the app auto-entered PiP on the way to Recents, then just re-expand it
|
||||
EventBus.getDefault().send(new ExpandPipEvent());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mTaskStackView != null) {
|
||||
Task task = getStack().getLaunchTarget();
|
||||
if (task != null) {
|
||||
@@ -635,6 +643,10 @@ public class RecentsView extends FrameLayout {
|
||||
updateStack(event.stack, false /* setStackViewTasks */);
|
||||
}
|
||||
|
||||
public final void onBusEvent(ShowEmptyViewEvent event) {
|
||||
showEmptyView(R.string.recents_empty_message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the stack action button.
|
||||
*/
|
||||
|
||||
@@ -562,7 +562,8 @@ public class TaskStackLayoutAlgorithm {
|
||||
mMinScrollP = 0;
|
||||
mMaxScrollP = Math.max(mMinScrollP, (mNumStackTasks - 1) -
|
||||
Math.max(0, mFocusedRange.getAbsoluteX(maxBottomNormX)));
|
||||
if (launchState.launchedFromHome) {
|
||||
if (launchState.launchedFromHome || launchState.launchedFromPipApp
|
||||
|| launchState.launchedWithNextPipApp) {
|
||||
mInitialScrollP = Utilities.clamp(launchTaskIndex, mMinScrollP, mMaxScrollP);
|
||||
} else {
|
||||
mInitialScrollP = Utilities.clamp(launchTaskIndex - 1, mMinScrollP, mMaxScrollP);
|
||||
@@ -581,8 +582,8 @@ public class TaskStackLayoutAlgorithm {
|
||||
mMinScrollP = 0;
|
||||
mMaxScrollP = Math.max(mMinScrollP, (mNumStackTasks - 1) -
|
||||
Math.max(0, mUnfocusedRange.getAbsoluteX(maxBottomNormX)));
|
||||
boolean scrollToFront = launchState.launchedFromHome ||
|
||||
launchState.launchedViaDockGesture;
|
||||
boolean scrollToFront = launchState.launchedFromHome || launchState.launchedFromPipApp
|
||||
|| launchState.launchedWithNextPipApp || launchState.launchedViaDockGesture;
|
||||
if (launchState.launchedFromBlacklistedApp) {
|
||||
mInitialScrollP = mMaxScrollP;
|
||||
} else if (launchState.launchedWithAltTab) {
|
||||
@@ -608,6 +609,8 @@ public class TaskStackLayoutAlgorithm {
|
||||
mTaskIndexOverrideMap.clear();
|
||||
|
||||
boolean scrollToFront = launchState.launchedFromHome ||
|
||||
launchState.launchedFromPipApp ||
|
||||
launchState.launchedWithNextPipApp ||
|
||||
launchState.launchedFromBlacklistedApp ||
|
||||
launchState.launchedViaDockGesture;
|
||||
if (getInitialFocusState() == STATE_UNFOCUSED && mNumStackTasks > 1) {
|
||||
|
||||
@@ -57,6 +57,7 @@ import com.android.systemui.recents.RecentsActivity;
|
||||
import com.android.systemui.recents.RecentsActivityLaunchState;
|
||||
import com.android.systemui.recents.RecentsConfiguration;
|
||||
import com.android.systemui.recents.RecentsDebugFlags;
|
||||
import com.android.systemui.recents.RecentsImpl;
|
||||
import com.android.systemui.recents.events.EventBus;
|
||||
import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
|
||||
import com.android.systemui.recents.events.activity.ConfigurationChangedEvent;
|
||||
@@ -72,7 +73,11 @@ import com.android.systemui.recents.events.activity.LaunchTaskEvent;
|
||||
import com.android.systemui.recents.events.activity.LaunchTaskStartedEvent;
|
||||
import com.android.systemui.recents.events.activity.MultiWindowStateChangedEvent;
|
||||
import com.android.systemui.recents.events.activity.PackagesChangedEvent;
|
||||
import com.android.systemui.recents.events.activity.ShowEmptyViewEvent;
|
||||
import com.android.systemui.recents.events.activity.ShowStackActionButtonEvent;
|
||||
import com.android.systemui.recents.events.component.ActivityPinnedEvent;
|
||||
import com.android.systemui.recents.events.component.ExpandPipEvent;
|
||||
import com.android.systemui.recents.events.component.HidePipMenuEvent;
|
||||
import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
|
||||
import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent;
|
||||
import com.android.systemui.recents.events.ui.DeleteTaskDataEvent;
|
||||
@@ -379,8 +384,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
|
||||
// Only notify if we are already initialized, otherwise, everything will pick up all the
|
||||
// new and old tasks when we next layout
|
||||
mStack.setTasks(getContext(), stack.computeAllTasksList(),
|
||||
allowNotifyStackChanges && isInitialized);
|
||||
mStack.setTasks(getContext(), stack, allowNotifyStackChanges && isInitialized);
|
||||
}
|
||||
|
||||
/** Returns the task stack. */
|
||||
@@ -1496,7 +1500,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
*/
|
||||
@Override
|
||||
public void onStackTaskRemoved(TaskStack stack, Task removedTask, Task newFrontMostTask,
|
||||
AnimationProps animation, boolean fromDockGesture) {
|
||||
AnimationProps animation, boolean fromDockGesture, boolean dismissRecentsIfAllRemoved) {
|
||||
if (mFocusedTask == removedTask) {
|
||||
resetFocusedTask(removedTask);
|
||||
}
|
||||
@@ -1527,9 +1531,13 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
|
||||
// If there are no remaining tasks, then just close recents
|
||||
if (mStack.getTaskCount() == 0) {
|
||||
EventBus.getDefault().send(new AllTaskViewsDismissedEvent(fromDockGesture
|
||||
? R.string.recents_empty_message
|
||||
: R.string.recents_empty_message_dismissed_all));
|
||||
if (dismissRecentsIfAllRemoved) {
|
||||
EventBus.getDefault().send(new AllTaskViewsDismissedEvent(fromDockGesture
|
||||
? R.string.recents_empty_message
|
||||
: R.string.recents_empty_message_dismissed_all));
|
||||
} else {
|
||||
EventBus.getDefault().send(new ShowEmptyViewEvent());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1802,14 +1810,36 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
return;
|
||||
}
|
||||
|
||||
final Task launchTask = mStack.getNextLaunchTarget();
|
||||
if (launchTask != null) {
|
||||
launchTask(launchTask);
|
||||
MetricsLogger.action(getContext(), MetricsEvent.OVERVIEW_LAUNCH_PREVIOUS_TASK,
|
||||
launchTask.key.getComponent().toString());
|
||||
} else if (mStack.getTaskCount() == 0) {
|
||||
// If there are no tasks, then just hide recents back to home.
|
||||
EventBus.getDefault().send(new HideRecentsEvent(false, true));
|
||||
if (mStack.getTaskCount() == 0) {
|
||||
if (RecentsImpl.getLastPipTime() != -1) {
|
||||
EventBus.getDefault().send(new ExpandPipEvent());
|
||||
MetricsLogger.action(getContext(), MetricsEvent.OVERVIEW_LAUNCH_PREVIOUS_TASK,
|
||||
"pip");
|
||||
} else {
|
||||
// If there are no tasks, then just hide recents back to home.
|
||||
EventBus.getDefault().send(new HideRecentsEvent(false, true));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Recents.getConfiguration().getLaunchState().launchedFromPipApp
|
||||
&& mStack.isNextLaunchTargetPip(RecentsImpl.getLastPipTime())) {
|
||||
// If the launch task is in the pinned stack, then expand the PiP now
|
||||
EventBus.getDefault().send(new ExpandPipEvent());
|
||||
MetricsLogger.action(getContext(), MetricsEvent.OVERVIEW_LAUNCH_PREVIOUS_TASK, "pip");
|
||||
} else {
|
||||
final Task launchTask = mStack.getNextLaunchTarget();
|
||||
if (launchTask != null) {
|
||||
// Defer launching the task until the PiP menu has been dismissed (if it is
|
||||
// showing at all)
|
||||
HidePipMenuEvent hideMenuEvent = new HidePipMenuEvent();
|
||||
hideMenuEvent.addPostAnimationCallback(() -> {
|
||||
launchTask(launchTask);
|
||||
});
|
||||
EventBus.getDefault().send(hideMenuEvent);
|
||||
MetricsLogger.action(getContext(), MetricsEvent.OVERVIEW_LAUNCH_PREVIOUS_TASK,
|
||||
launchTask.key.getComponent().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1871,7 +1901,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
R.string.accessibility_recents_all_items_dismissed));
|
||||
|
||||
// Remove all tasks and delete the task data for all tasks
|
||||
mStack.removeAllTasks();
|
||||
mStack.removeAllTasks(true /* notifyStackChanges */);
|
||||
for (int i = tasks.size() - 1; i >= 0; i--) {
|
||||
EventBus.getDefault().send(new DeleteTaskDataEvent(tasks.get(i)));
|
||||
}
|
||||
@@ -2217,11 +2247,23 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
}
|
||||
}
|
||||
|
||||
public final void onBusEvent(ActivityPinnedEvent event) {
|
||||
// If an activity enters PiP while Recents is open, remove the stack task associated with
|
||||
// the new PiP task
|
||||
Task removeTask = mStack.findTaskWithId(event.taskId);
|
||||
if (removeTask != null) {
|
||||
// In this case, we remove the task, but if the last task is removed, don't dismiss
|
||||
// Recents to home
|
||||
mStack.removeTask(removeTask, AnimationProps.IMMEDIATE, false /* fromDockGesture */,
|
||||
false /* dismissRecentsIfAllRemoved */);
|
||||
}
|
||||
updateLayoutAlgorithm(false /* boundScroll */);
|
||||
updateToInitialState();
|
||||
}
|
||||
|
||||
public void reloadOnConfigurationChange() {
|
||||
mStableLayoutAlgorithm.reloadOnConfigurationChange(getContext());
|
||||
mLayoutAlgorithm.reloadOnConfigurationChange(getContext());
|
||||
|
||||
boolean hasDockedTask = Recents.getSystemServices().hasDockedTask();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2998,7 +2998,8 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
|
||||
|
||||
stack.animateResizePinnedStack(sourceHintBounds, destBounds, -1 /* animationDuration */,
|
||||
true /* schedulePipModeChangedOnAnimationEnd */);
|
||||
mService.mTaskChangeNotificationController.notifyActivityPinned(r.packageName);
|
||||
mService.mTaskChangeNotificationController.notifyActivityPinned(r.packageName,
|
||||
r.getTask().taskId);
|
||||
}
|
||||
|
||||
/** Move activity with its stack to front and make the stack focused. */
|
||||
|
||||
@@ -96,7 +96,7 @@ class TaskChangeNotificationController {
|
||||
};
|
||||
|
||||
private final TaskStackConsumer mNotifyActivityPinned = (l, m) -> {
|
||||
l.onActivityPinned((String) m.obj);
|
||||
l.onActivityPinned((String) m.obj, m.arg1);
|
||||
};
|
||||
|
||||
private final TaskStackConsumer mNotifyActivityUnpinned = (l, m) -> {
|
||||
@@ -279,10 +279,10 @@ class TaskChangeNotificationController {
|
||||
}
|
||||
|
||||
/** Notifies all listeners when an Activity is pinned. */
|
||||
void notifyActivityPinned(String packageName) {
|
||||
void notifyActivityPinned(String packageName, int taskId) {
|
||||
mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
|
||||
final Message msg = mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG,
|
||||
packageName);
|
||||
taskId, 0, packageName);
|
||||
forAllLocalListeners(mNotifyActivityPinned, msg);
|
||||
msg.sendToTarget();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user