Ensure RecentsActivity is resizeable.

- Removing old code related to multi-stack layouts.

Change-Id: Ib9b820d2a65ff15e9cd8e5255e3e858b611e5aa9
This commit is contained in:
Winson
2015-09-16 16:49:55 -07:00
parent a6d602dff5
commit 147ecaf3ba
15 changed files with 183 additions and 418 deletions

View File

@@ -205,6 +205,7 @@
android:stateNotNeeded="true"
android:resumeWhilePausing="true"
android:screenOrientation="behind"
android:resizeableActivity="true"
android:theme="@style/config_recents_activity_theme">
<intent-filter>
<action android:name="com.android.systemui.recents.TOGGLE_RECENTS" />

View File

@@ -45,8 +45,6 @@ public class Constants {
public static final boolean EnableSearchLayout = true;
// Enables the thumbnail alpha on the front-most task
public static final boolean EnableThumbnailAlphaOnFrontmost = false;
// Enables all system stacks to show up in the same recents stack
public static final boolean EnableMultiStackToSingleStack = true;
// This disables the bitmap and icon caches
public static final boolean DisableBackgroundCache = false;
// Enables the simulated task affiliations

View File

@@ -116,7 +116,7 @@ public class Recents extends SystemUI
/** Preloads the next task */
public void run() {
// Temporarily skip this if multi stack is enabled
if (mConfig.multiStackEnabled) return;
if (mConfig.multiWindowEnabled) return;
RecentsConfiguration config = RecentsConfiguration.getInstance();
if (config.svelteLevel == RecentsConfiguration.SVELTE_NONE) {
@@ -176,7 +176,6 @@ public class Recents extends SystemUI
// Task launching
RecentsConfiguration mConfig;
Rect mWindowRect = new Rect();
Rect mTaskStackBounds = new Rect();
Rect mSystemInsets = new Rect();
TaskViewTransform mTmpTransform = new TaskViewTransform();
@@ -372,9 +371,9 @@ public class Recents extends SystemUI
if (topTask != null && !mSystemServicesProxy.isRecentsTopMost(topTask, topTaskHome)) {
sInstanceLoadPlan.preloadRawTasks(topTaskHome.value);
loader.preloadTasks(sInstanceLoadPlan, topTaskHome.value);
TaskStack top = sInstanceLoadPlan.getAllTaskStacks().get(0);
if (top.getTaskCount() > 0) {
preCacheThumbnailTransitionBitmapAsync(topTask, top, mDummyStackView,
TaskStack stack = sInstanceLoadPlan.getTaskStack();
if (stack.getTaskCount() > 0) {
preCacheThumbnailTransitionBitmapAsync(topTask, stack, mDummyStackView,
topTaskHome.value);
}
}
@@ -388,16 +387,10 @@ public class Recents extends SystemUI
void showRelativeAffiliatedTask(boolean showNextTask) {
// Return early if there is no focused stack
int focusedStackId = mSystemServicesProxy.getFocusedStack();
TaskStack focusedStack = null;
RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext);
loader.preloadTasks(plan, true /* isTopTaskHome */);
if (mConfig.multiStackEnabled) {
if (focusedStackId < 0) return;
focusedStack = plan.getTaskStack(focusedStackId);
} else {
focusedStack = plan.getAllTaskStacks().get(0);
}
TaskStack focusedStack = plan.getTaskStack();
// Return early if there are no tasks in the focused stack
if (focusedStack == null || focusedStack.getTaskCount() == 0) return;
@@ -502,7 +495,8 @@ public class Recents extends SystemUI
/** Prepares the header bar layout. */
void reloadHeaderBarLayout() {
Resources res = mContext.getResources();
mWindowRect = mSystemServicesProxy.getWindowRect();
Rect windowRect = mSystemServicesProxy.getWindowRect();
mStatusBarHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
mNavBarHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_height);
mNavBarWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_width);
@@ -513,10 +507,10 @@ public class Recents extends SystemUI
// have the right thumbnail bounds to animate to.
// Note: We have to reload the widget id before we get the task stack bounds below
if (mSystemServicesProxy.getOrBindSearchAppWidget(mContext, mAppWidgetHost) != null) {
mConfig.getSearchBarBounds(mWindowRect.width(), mWindowRect.height(),
mConfig.getSearchBarBounds(windowRect,
mStatusBarHeight, searchBarBounds);
}
mConfig.getAvailableTaskStackBounds(mWindowRect.width(), mWindowRect.height(),
mConfig.getAvailableTaskStackBounds(windowRect,
mStatusBarHeight, (mConfig.hasTransposedNavBar ? mNavBarWidth : 0), searchBarBounds,
mTaskStackBounds);
if (mConfig.isLandscape && mConfig.hasTransposedNavBar) {
@@ -531,7 +525,7 @@ public class Recents extends SystemUI
TaskStackViewLayoutAlgorithm algo = mDummyStackView.getStackAlgorithm();
Rect taskStackBounds = new Rect(mTaskStackBounds);
taskStackBounds.bottom -= mSystemInsets.bottom;
algo.computeRects(mWindowRect.width(), mWindowRect.height(), taskStackBounds);
algo.computeRects(windowRect.width(), windowRect.height(), taskStackBounds);
Rect taskViewSize = algo.getUntransformedTaskViewSize();
int taskBarHeight = res.getDimensionPixelSize(R.dimen.recents_task_bar_height);
synchronized (mHeaderBarLock) {
@@ -540,6 +534,7 @@ public class Recents extends SystemUI
mHeaderBar.measure(
View.MeasureSpec.makeMeasureSpec(taskViewSize.width(), View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(taskBarHeight, View.MeasureSpec.EXACTLY));
// TODO: may not be needed
mHeaderBar.layout(0, 0, taskViewSize.width(), taskBarHeight);
}
}
@@ -749,10 +744,9 @@ public class Recents extends SystemUI
// Temporarily skip the transition (use a dummy fade) if multi stack is enabled.
// For multi-stack we need to figure out where each of the tasks are going.
if (mConfig.multiStackEnabled) {
if (mConfig.multiWindowEnabled) {
loader.preloadTasks(sInstanceLoadPlan, true);
ArrayList<TaskStack> stacks = sInstanceLoadPlan.getAllTaskStacks();
TaskStack stack = stacks.get(0);
TaskStack stack = sInstanceLoadPlan.getTaskStack();
mDummyStackView.updateMinMaxScrollForStack(stack, mTriggeredFromAltTab, true);
TaskStackViewLayoutAlgorithm.VisibilityReport stackVr =
mDummyStackView.computeStackVisibilityReport();
@@ -765,8 +759,7 @@ public class Recents extends SystemUI
if (!sInstanceLoadPlan.hasTasks()) {
loader.preloadTasks(sInstanceLoadPlan, isTopTaskHome);
}
ArrayList<TaskStack> stacks = sInstanceLoadPlan.getAllTaskStacks();
TaskStack stack = stacks.get(0);
TaskStack stack = sInstanceLoadPlan.getTaskStack();
// Prepare the dummy stack for the transition
mDummyStackView.updateMinMaxScrollForStack(stack, mTriggeredFromAltTab, isTopTaskHome);

View File

@@ -25,6 +25,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.SystemClock;
import android.os.UserHandle;
@@ -205,10 +206,10 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
loadOpts.numVisibleTaskThumbnails = mConfig.launchedNumVisibleThumbnails;
loader.loadTasks(this, plan, loadOpts);
ArrayList<TaskStack> stacks = plan.getAllTaskStacks();
TaskStack stack = plan.getTaskStack();
mConfig.launchedWithNoRecentTasks = !plan.hasTasks();
if (!mConfig.launchedWithNoRecentTasks) {
mRecentsView.setTaskStacks(stacks);
mRecentsView.setTaskStack(stack);
}
// Create the home intent runnable
@@ -224,20 +225,16 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
R.anim.recents_to_launcher_exit));
// Mark the task that is the launch target
int taskStackCount = stacks.size();
int launchTaskIndexInStack = 0;
if (mConfig.launchedToTaskId != -1) {
for (int i = 0; i < taskStackCount; i++) {
TaskStack stack = stacks.get(i);
ArrayList<Task> tasks = stack.getTasks();
int taskCount = tasks.size();
for (int j = 0; j < taskCount; j++) {
Task t = tasks.get(j);
if (t.key.id == mConfig.launchedToTaskId) {
t.isLaunchTarget = true;
launchTaskIndexInStack = tasks.size() - j - 1;
break;
}
ArrayList<Task> tasks = stack.getTasks();
int taskCount = tasks.size();
for (int j = 0; j < taskCount; j++) {
Task t = tasks.get(j);
if (t.key.id == mConfig.launchedToTaskId) {
t.isLaunchTarget = true;
launchTaskIndexInStack = tasks.size() - j - 1;
break;
}
}
}
@@ -278,11 +275,7 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
MetricsLogger.count(this, "overview_source_home", 1);
}
// Keep track of the total stack task count
int taskCount = 0;
for (int i = 0; i < stacks.size(); i++) {
TaskStack stack = stacks.get(i);
taskCount += stack.getTaskCount();
}
int taskCount = stack.getTaskCount();
MetricsLogger.histogram(this, "overview_task_count", taskCount);
}

View File

@@ -134,7 +134,7 @@ public class RecentsConfiguration {
public boolean fakeShadows;
/** Dev options and global settings */
public boolean multiStackEnabled;
public boolean multiWindowEnabled;
public boolean lockToAppEnabled;
public boolean developerOptionsEnabled;
public boolean debugModeEnabled;
@@ -283,7 +283,7 @@ public class RecentsConfiguration {
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED) != 0;
lockToAppEnabled = ssp.getSystemSetting(context,
Settings.System.LOCK_TO_APP_ENABLED) != 0;
multiStackEnabled = "true".equals(ssp.getSystemProperty("persist.sys.debug.multi_window"));
multiWindowEnabled = "true".equals(ssp.getSystemProperty("persist.sys.debug.multi_window"));
}
/** Called when the configuration has changed, and we want to reset any configuration specific
@@ -320,14 +320,16 @@ public class RecentsConfiguration {
* Returns the task stack bounds in the current orientation. These bounds do not account for
* the system insets.
*/
public void getAvailableTaskStackBounds(int windowWidth, int windowHeight, int topInset,
public void getAvailableTaskStackBounds(Rect windowBounds, int topInset,
int rightInset, Rect searchBarBounds, Rect taskStackBounds) {
if (isLandscape && hasTransposedSearchBar) {
// In landscape, the search bar appears on the left, but we overlay it on top
taskStackBounds.set(0, topInset, windowWidth - rightInset, windowHeight);
taskStackBounds.set(windowBounds.left, windowBounds.top + topInset,
windowBounds.right - rightInset, windowBounds.bottom);
} else {
// In portrait, the search bar appears on the top (which already has the inset)
taskStackBounds.set(0, searchBarBounds.bottom, windowWidth, windowHeight);
taskStackBounds.set(windowBounds.left, searchBarBounds.bottom,
windowBounds.right, windowBounds.bottom);
}
}
@@ -335,16 +337,17 @@ public class RecentsConfiguration {
* Returns the search bar bounds in the current orientation. These bounds do not account for
* the system insets.
*/
public void getSearchBarBounds(int windowWidth, int windowHeight, int topInset,
Rect searchBarSpaceBounds) {
public void getSearchBarBounds(Rect windowBounds, int topInset, Rect searchBarSpaceBounds) {
// Return empty rects if search is not enabled
int searchBarSize = searchBarSpaceHeightPx;
if (isLandscape && hasTransposedSearchBar) {
// In landscape, the search bar appears on the left
searchBarSpaceBounds.set(0, topInset, searchBarSize, windowHeight);
searchBarSpaceBounds.set(windowBounds.left, windowBounds.top + topInset,
windowBounds.left + searchBarSize, windowBounds.bottom);
} else {
// In portrait, the search bar appears on the top
searchBarSpaceBounds.set(0, topInset, windowWidth, topInset + searchBarSize);
searchBarSpaceBounds.set(windowBounds.left, windowBounds.top + topInset,
windowBounds.right, windowBounds.top + topInset + searchBarSize);
}
}
}

View File

@@ -24,7 +24,6 @@ import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
@@ -32,11 +31,8 @@ import com.android.systemui.R;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.model.RecentsTaskLoader;
import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.RecentsActivity;
import com.android.systemui.recents.views.RecentsView;
import java.util.ArrayList;
/**
* A helper for the dialogs that show when task debugging is on.
*/
@@ -216,7 +212,7 @@ public class RecentsResizeTaskDialog extends DialogFragment {
// In debug mode, we force all task to be resizeable regardless of the
// current app configuration.
if (RecentsConfiguration.getInstance().multiStackEnabled) {
if (RecentsConfiguration.getInstance().multiWindowEnabled) {
for (int i = additionalTasks; i >= 0; --i) {
if (mTasks[i] != null) {
mSsp.setTaskResizeable(mTasks[i].key.id);

View File

@@ -641,12 +641,19 @@ public class SystemServicesProxy {
*/
public Rect getWindowRect() {
Rect windowRect = new Rect();
if (mWm == null) return windowRect;
if (mIam == null) return windowRect;
Point p = new Point();
mWm.getDefaultDisplay().getRealSize(p);
windowRect.set(0, 0, p.x, p.y);
return windowRect;
try {
// Use the home stack bounds
ActivityManager.StackInfo stackInfo = mIam.getStackInfo(ActivityManager.HOME_STACK_ID);
if (stackInfo != null) {
windowRect.set(stackInfo.bounds);
}
} catch (RemoteException e) {
e.printStackTrace();
} finally {
return windowRect;
}
}
/** Starts an activity from recents. */

View File

@@ -20,12 +20,10 @@ import android.app.ActivityManager;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.UserHandle;
import android.util.Log;
import android.util.SparseArray;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.misc.SystemServicesProxy;
@@ -63,7 +61,7 @@ public class RecentsTaskLoadPlan {
SystemServicesProxy mSystemServicesProxy;
List<ActivityManager.RecentTaskInfo> mRawTasks;
SparseArray<TaskStack> mStacks = new SparseArray<>();
TaskStack mStack;
HashMap<Task.ComponentNameKey, ActivityInfoHandle> mActivityInfoCache =
new HashMap<Task.ComponentNameKey, ActivityInfoHandle>();
@@ -96,11 +94,8 @@ public class RecentsTaskLoadPlan {
// This activity info cache will be used for both preloadPlan() and executePlan()
mActivityInfoCache.clear();
// TODO (multi-display): Currently assume the primary display
Rect displayBounds = mSystemServicesProxy.getWindowRect();
Resources res = mContext.getResources();
SparseArray<ArrayList<Task>> stacksTasks = new SparseArray<>();
ArrayList<Task> stackTasks = new ArrayList<>();
if (mRawTasks == null) {
preloadRawTasks(isTopTaskHome);
}
@@ -152,37 +147,13 @@ public class RecentsTaskLoadPlan {
task.thumbnail = loader.getAndUpdateThumbnail(taskKey, mSystemServicesProxy, false);
if (DEBUG) Log.d(TAG, "\tthumbnail: " + taskKey + ", " + task.thumbnail);
if (!mConfig.multiStackEnabled ||
Constants.DebugFlags.App.EnableMultiStackToSingleStack) {
int firstStackId = 0;
ArrayList<Task> stackTasks = stacksTasks.get(firstStackId);
if (stackTasks == null) {
stackTasks = new ArrayList<>();
stacksTasks.put(firstStackId, stackTasks);
}
stackTasks.add(task);
} else {
ArrayList<Task> stackTasks = stacksTasks.get(t.stackId);
if (stackTasks == null) {
stackTasks = new ArrayList<>();
stacksTasks.put(t.stackId, stackTasks);
}
stackTasks.add(task);
}
stackTasks.add(task);
}
// Initialize the stacks
mStacks.clear();
int stackCount = stacksTasks.size();
for (int i = 0; i < stackCount; i++) {
int stackId = stacksTasks.keyAt(i);
ArrayList<Task> stackTasks = stacksTasks.valueAt(i);
TaskStack stack = new TaskStack(stackId);
stack.setBounds(displayBounds, displayBounds);
stack.setTasks(stackTasks);
stack.createAffiliatedGroupings(mConfig);
mStacks.put(stackId, stack);
}
mStack = new TaskStack();
mStack.setTasks(stackTasks);
mStack.createAffiliatedGroupings(mConfig);
}
/**
@@ -197,92 +168,70 @@ public class RecentsTaskLoadPlan {
Resources res = mContext.getResources();
// Iterate through each of the tasks and load them according to the load conditions.
int stackCount = mStacks.size();
for (int j = 0; j < stackCount; j++) {
ArrayList<Task> tasks = mStacks.valueAt(j).getTasks();
int taskCount = tasks.size();
for (int i = 0; i < taskCount; i++) {
ActivityManager.RecentTaskInfo t = mRawTasks.get(i);
Task task = tasks.get(i);
Task.TaskKey taskKey = task.key;
ArrayList<Task> tasks = mStack.getTasks();
int taskCount = tasks.size();
for (int i = 0; i < taskCount; i++) {
ActivityManager.RecentTaskInfo t = mRawTasks.get(i);
Task task = tasks.get(i);
Task.TaskKey taskKey = task.key;
// Get an existing activity info handle if possible
Task.ComponentNameKey cnKey = taskKey.getComponentNameKey();
ActivityInfoHandle infoHandle;
boolean hadCachedActivityInfo = false;
if (mActivityInfoCache.containsKey(cnKey)) {
infoHandle = mActivityInfoCache.get(cnKey);
hadCachedActivityInfo = true;
} else {
infoHandle = new ActivityInfoHandle();
// Get an existing activity info handle if possible
Task.ComponentNameKey cnKey = taskKey.getComponentNameKey();
ActivityInfoHandle infoHandle;
boolean hadCachedActivityInfo = false;
if (mActivityInfoCache.containsKey(cnKey)) {
infoHandle = mActivityInfoCache.get(cnKey);
hadCachedActivityInfo = true;
} else {
infoHandle = new ActivityInfoHandle();
}
boolean isRunningTask = (task.key.id == opts.runningTaskId);
boolean isVisibleTask = i >= (taskCount - opts.numVisibleTasks);
boolean isVisibleThumbnail = i >= (taskCount - opts.numVisibleTaskThumbnails);
// If requested, skip the running task
if (opts.onlyLoadPausedActivities && isRunningTask) {
continue;
}
if (opts.loadIcons && (isRunningTask || isVisibleTask)) {
if (task.activityIcon == null) {
if (DEBUG) Log.d(TAG, "\tLoading icon: " + taskKey);
task.activityIcon = loader.getAndUpdateActivityIcon(taskKey,
t.taskDescription, mSystemServicesProxy, res, infoHandle, true);
}
boolean isRunningTask = (task.key.id == opts.runningTaskId);
boolean isVisibleTask = i >= (taskCount - opts.numVisibleTasks);
boolean isVisibleThumbnail = i >= (taskCount - opts.numVisibleTaskThumbnails);
// If requested, skip the running task
if (opts.onlyLoadPausedActivities && isRunningTask) {
continue;
}
if (opts.loadIcons && (isRunningTask || isVisibleTask)) {
if (task.activityIcon == null) {
if (DEBUG) Log.d(TAG, "\tLoading icon: " + taskKey);
task.activityIcon = loader.getAndUpdateActivityIcon(taskKey,
t.taskDescription, mSystemServicesProxy, res, infoHandle, true);
}
}
if (opts.loadThumbnails && (isRunningTask || isVisibleThumbnail)) {
if (task.thumbnail == null || isRunningTask) {
if (DEBUG) Log.d(TAG, "\tLoading thumbnail: " + taskKey);
if (mConfig.svelteLevel <= RecentsConfiguration.SVELTE_LIMIT_CACHE) {
task.thumbnail = loader.getAndUpdateThumbnail(taskKey,
mSystemServicesProxy, true);
} else if (mConfig.svelteLevel == RecentsConfiguration.SVELTE_DISABLE_CACHE) {
loadQueue.addTask(task);
}
}
if (opts.loadThumbnails && (isRunningTask || isVisibleThumbnail)) {
if (task.thumbnail == null || isRunningTask) {
if (DEBUG) Log.d(TAG, "\tLoading thumbnail: " + taskKey);
if (mConfig.svelteLevel <= RecentsConfiguration.SVELTE_LIMIT_CACHE) {
task.thumbnail = loader.getAndUpdateThumbnail(taskKey,
mSystemServicesProxy, true);
} else if (mConfig.svelteLevel == RecentsConfiguration.SVELTE_DISABLE_CACHE) {
loadQueue.addTask(task);
}
}
}
// Update the activity info cache
if (!hadCachedActivityInfo && infoHandle.info != null) {
mActivityInfoCache.put(cnKey, infoHandle);
}
// Update the activity info cache
if (!hadCachedActivityInfo && infoHandle.info != null) {
mActivityInfoCache.put(cnKey, infoHandle);
}
}
}
/**
* Returns all TaskStacks from the preloaded list of recent tasks.
* Returns the TaskStack from the preloaded list of recent tasks.
*/
public ArrayList<TaskStack> getAllTaskStacks() {
ArrayList<TaskStack> stacks = new ArrayList<TaskStack>();
int stackCount = mStacks.size();
for (int i = 0; i < stackCount; i++) {
stacks.add(mStacks.valueAt(i));
}
// Ensure that we have at least one stack
if (stacks.isEmpty()) {
stacks.add(new TaskStack());
}
return stacks;
}
/**
* Returns a specific TaskStack from the preloaded list of recent tasks.
*/
public TaskStack getTaskStack(int stackId) {
return mStacks.get(stackId);
public TaskStack getTaskStack() {
return mStack;
}
/** Returns whether there are any tasks in any stacks. */
public boolean hasTasks() {
int stackCount = mStacks.size();
for (int i = 0; i < stackCount; i++) {
if (mStacks.valueAt(i).getTaskCount() > 0) {
return true;
}
if (mStack != null) {
return mStack.getTaskCount() > 0;
}
return false;
}

View File

@@ -177,35 +177,17 @@ public class TaskStack {
// The task offset to apply to a task id as a group affiliation
static final int IndividualTaskIdOffset = 1 << 16;
public final int id;
public final Rect stackBounds = new Rect();
public final Rect displayBounds = new Rect();
FilteredTaskList mTaskList = new FilteredTaskList();
TaskStackCallbacks mCb;
ArrayList<TaskGrouping> mGroups = new ArrayList<TaskGrouping>();
HashMap<Integer, TaskGrouping> mAffinitiesGroups = new HashMap<Integer, TaskGrouping>();
public TaskStack() {
this(0);
}
public TaskStack(int stackId) {
id = stackId;
}
/** Sets the callbacks for this task stack. */
public void setCallbacks(TaskStackCallbacks cb) {
mCb = cb;
}
/** Sets the bounds of this stack. */
public void setBounds(Rect stackBounds, Rect displayBounds) {
this.stackBounds.set(stackBounds);
this.displayBounds.set(displayBounds);
}
/** Resets this TaskStack. */
public void reset() {
mCb = null;

View File

@@ -79,10 +79,9 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
RecentsConfiguration mConfig;
LayoutInflater mInflater;
DebugOverlayView mDebugOverlay;
RecentsViewLayoutAlgorithm mLayoutAlgorithm;
ArrayList<TaskStack> mStacks;
List<TaskStackView> mTaskStackViews = new ArrayList<>();
TaskStackView mTaskStackView;
RecentsAppWidgetHostView mSearchBar;
RecentsViewCallbacks mCb;
@@ -102,7 +101,6 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
super(context, attrs, defStyleAttr, defStyleRes);
mConfig = RecentsConfiguration.getInstance();
mInflater = LayoutInflater.from(context);
mLayoutAlgorithm = new RecentsViewLayoutAlgorithm(mConfig);
}
/** Sets the callbacks */
@@ -116,61 +114,41 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
}
/** Set/get the bsp root node */
public void setTaskStacks(ArrayList<TaskStack> stacks) {
int numStacks = stacks.size();
// Remove all/extra stack views
int numTaskStacksToKeep = 0; // Keep no tasks if we are recreating the layout
public void setTaskStack(TaskStack stack) {
if (mConfig.launchedReuseTaskStackViews) {
numTaskStacksToKeep = Math.min(mTaskStackViews.size(), numStacks);
}
for (int i = mTaskStackViews.size() - 1; i >= numTaskStacksToKeep; i--) {
removeView(mTaskStackViews.remove(i));
}
// Update the stack views that we are keeping
for (int i = 0; i < numTaskStacksToKeep; i++) {
TaskStackView tsv = mTaskStackViews.get(i);
// If onRecentsHidden is not triggered, we need to the stack view again here
tsv.reset();
tsv.setStack(stacks.get(i));
}
// Add remaining/recreate stack views
mStacks = stacks;
for (int i = mTaskStackViews.size(); i < numStacks; i++) {
TaskStack stack = stacks.get(i);
TaskStackView stackView = new TaskStackView(getContext(), stack);
stackView.setCallbacks(this);
addView(stackView);
mTaskStackViews.add(stackView);
if (mTaskStackView != null) {
// If onRecentsHidden is not triggered, we need to the stack view again here
mTaskStackView.reset();
mTaskStackView.setStack(stack);
} else {
mTaskStackView = new TaskStackView(getContext(), stack);
mTaskStackView.setCallbacks(this);
addView(mTaskStackView);
}
} else {
if (mTaskStackView != null) {
removeView(mTaskStackView);
}
mTaskStackView = new TaskStackView(getContext(), stack);
mTaskStackView.setCallbacks(this);
addView(mTaskStackView);
}
// Enable debug mode drawing on all the stacks if necessary
if (mConfig.debugModeEnabled) {
for (int i = mTaskStackViews.size() - 1; i >= 0; i--) {
TaskStackView stackView = mTaskStackViews.get(i);
stackView.setDebugOverlay(mDebugOverlay);
}
mTaskStackView.setDebugOverlay(mDebugOverlay);
}
// Trigger a new layout
requestLayout();
}
/** Gets the list of task views */
List<TaskStackView> getTaskStackViews() {
return mTaskStackViews;
}
/** Gets the next task in the stack - or if the last - the top task */
public Task getNextTaskOrTopTask(Task taskToSearch) {
Task returnTask = null;
boolean found = false;
List<TaskStackView> stackViews = getTaskStackViews();
int stackCount = stackViews.size();
for (int i = stackCount - 1; i >= 0; --i) {
TaskStack stack = stackViews.get(i).getStack();
if (mTaskStackView != null) {
TaskStack stack = mTaskStackView.getStack();
ArrayList<Task> taskList = stack.getTasks();
// Iterate the stack views and try and find the focused task
for (int j = taskList.size() - 1; j >= 0; --j) {
@@ -190,20 +168,16 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
/** Launches the focused task from the first stack if possible */
public boolean launchFocusedTask() {
// Get the first stack view
List<TaskStackView> stackViews = getTaskStackViews();
int stackCount = stackViews.size();
for (int i = 0; i < stackCount; i++) {
TaskStackView stackView = stackViews.get(i);
TaskStack stack = stackView.getStack();
if (mTaskStackView != null) {
TaskStack stack = mTaskStackView.getStack();
// Iterate the stack views and try and find the focused task
List<TaskView> taskViews = stackView.getTaskViews();
List<TaskView> taskViews = mTaskStackView.getTaskViews();
int taskViewCount = taskViews.size();
for (int j = 0; j < taskViewCount; j++) {
TaskView tv = taskViews.get(j);
Task task = tv.getTask();
if (tv.isFocusedTask()) {
onTaskViewClicked(stackView, tv, stack, task, false, false, null);
onTaskViewClicked(mTaskStackView, tv, stack, task, false, false, null);
return true;
}
}
@@ -213,19 +187,15 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
/** Launches a given task. */
public boolean launchTask(Task task, Rect taskBounds) {
// Get the first stack view
List<TaskStackView> stackViews = getTaskStackViews();
int stackCount = stackViews.size();
for (int i = 0; i < stackCount; i++) {
TaskStackView stackView = stackViews.get(i);
TaskStack stack = stackView.getStack();
if (mTaskStackView != null) {
TaskStack stack = mTaskStackView.getStack();
// Iterate the stack views and try and find the given task.
List<TaskView> taskViews = stackView.getTaskViews();
List<TaskView> taskViews = mTaskStackView.getTaskViews();
int taskViewCount = taskViews.size();
for (int j = 0; j < taskViewCount; j++) {
TaskView tv = taskViews.get(j);
if (tv.getTask() == task) {
onTaskViewClicked(stackView, tv, stack, task, false, true, taskBounds);
onTaskViewClicked(mTaskStackView, tv, stack, task, false, true, taskBounds);
return true;
}
}
@@ -235,12 +205,8 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
/** Launches the task that Recents was launched from, if possible */
public boolean launchPreviousTask() {
// Get the first stack view
List<TaskStackView> stackViews = getTaskStackViews();
int stackCount = stackViews.size();
for (int i = 0; i < stackCount; i++) {
TaskStackView stackView = stackViews.get(i);
TaskStack stack = stackView.getStack();
if (mTaskStackView != null) {
TaskStack stack = mTaskStackView.getStack();
ArrayList<Task> tasks = stack.getTasks();
// Find the launch task in the stack
@@ -249,8 +215,8 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
for (int j = 0; j < taskCount; j++) {
if (tasks.get(j).isLaunchTarget) {
Task task = tasks.get(j);
TaskView tv = stackView.getChildViewForTask(task);
onTaskViewClicked(stackView, tv, stack, task, false, false, null);
TaskView tv = mTaskStackView.getChildViewForTask(task);
onTaskViewClicked(mTaskStackView, tv, stack, task, false, false, null);
return true;
}
}
@@ -264,12 +230,8 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
// We have to increment/decrement the post animation trigger in case there are no children
// to ensure that it runs
ctx.postAnimationTrigger.increment();
List<TaskStackView> stackViews = getTaskStackViews();
int stackCount = stackViews.size();
for (int i = 0; i < stackCount; i++) {
TaskStackView stackView = stackViews.get(i);
stackView.startEnterRecentsAnimation(ctx);
if (mTaskStackView != null) {
mTaskStackView.startEnterRecentsAnimation(ctx);
}
ctx.postAnimationTrigger.decrement();
}
@@ -279,11 +241,8 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
// We have to increment/decrement the post animation trigger in case there are no children
// to ensure that it runs
ctx.postAnimationTrigger.increment();
List<TaskStackView> stackViews = getTaskStackViews();
int stackCount = stackViews.size();
for (int i = 0; i < stackCount; i++) {
TaskStackView stackView = stackViews.get(i);
stackView.startExitToHomeAnimation(ctx);
if (mTaskStackView != null) {
mTaskStackView.startExitToHomeAnimation(ctx);
}
ctx.postAnimationTrigger.decrement();
@@ -329,31 +288,19 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
// Get the search bar bounds and measure the search bar layout
Rect searchBarSpaceBounds = new Rect();
if (mSearchBar != null) {
mConfig.getSearchBarBounds(width, height, mConfig.systemInsets.top, searchBarSpaceBounds);
mConfig.getSearchBarBounds(new Rect(0, 0, width, height), mConfig.systemInsets.top,
searchBarSpaceBounds);
mSearchBar.measure(
MeasureSpec.makeMeasureSpec(searchBarSpaceBounds.width(), MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(searchBarSpaceBounds.height(), MeasureSpec.EXACTLY));
}
Rect taskStackBounds = new Rect();
mConfig.getAvailableTaskStackBounds(width, height, mConfig.systemInsets.top,
mConfig.getAvailableTaskStackBounds(new Rect(0, 0, width, height), mConfig.systemInsets.top,
mConfig.systemInsets.right, searchBarSpaceBounds, taskStackBounds);
// Measure each TaskStackView with the full width and height of the window since the
// transition view is a child of that stack view
List<TaskStackView> stackViews = getTaskStackViews();
List<Rect> stackViewsBounds = mLayoutAlgorithm.computeStackRects(stackViews,
taskStackBounds);
int stackCount = stackViews.size();
for (int i = 0; i < stackCount; i++) {
TaskStackView stackView = stackViews.get(i);
if (stackView.getVisibility() != GONE) {
// We are going to measure the TaskStackView with the whole RecentsView dimensions,
// but the actual stack is going to be inset to the bounds calculated by the layout
// algorithm
stackView.setStackInsetRect(stackViewsBounds.get(i));
stackView.measure(widthMeasureSpec, heightMeasureSpec);
}
if (mTaskStackView != null && mTaskStackView.getVisibility() != GONE) {
mTaskStackView.setTaskStackBounds(taskStackBounds);
mTaskStackView.measure(widthMeasureSpec, heightMeasureSpec);
}
setMeasuredDimension(width, height);
@@ -365,24 +312,17 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
// Get the search bar bounds so that we lay it out
Rect measuredRect = new Rect(0, 0, getMeasuredWidth(), getMeasuredHeight());
Rect searchBarSpaceBounds = new Rect();
if (mSearchBar != null) {
Rect searchBarSpaceBounds = new Rect();
mConfig.getSearchBarBounds(getMeasuredWidth(), getMeasuredHeight(),
mConfig.getSearchBarBounds(measuredRect,
mConfig.systemInsets.top, searchBarSpaceBounds);
mSearchBar.layout(searchBarSpaceBounds.left, searchBarSpaceBounds.top,
searchBarSpaceBounds.right, searchBarSpaceBounds.bottom);
}
// Layout each TaskStackView with the full width and height of the window since the
// transition view is a child of that stack view
List<TaskStackView> stackViews = getTaskStackViews();
int stackCount = stackViews.size();
for (int i = 0; i < stackCount; i++) {
TaskStackView stackView = stackViews.get(i);
if (stackView.getVisibility() != GONE) {
stackView.layout(left, top, left + stackView.getMeasuredWidth(),
top + stackView.getMeasuredHeight());
}
if (mTaskStackView != null && mTaskStackView.getVisibility() != GONE) {
mTaskStackView.layout(left, top, left + getMeasuredWidth(), top + getMeasuredHeight());
}
}
@@ -397,29 +337,24 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
/** Notifies each task view of the user interaction. */
public void onUserInteraction() {
// Get the first stack view
List<TaskStackView> stackViews = getTaskStackViews();
int stackCount = stackViews.size();
for (int i = 0; i < stackCount; i++) {
TaskStackView stackView = stackViews.get(i);
stackView.onUserInteraction();
if (mTaskStackView != null) {
mTaskStackView.onUserInteraction();
}
}
/** Focuses the next task in the first stack view */
public void focusNextTask(boolean forward) {
// Get the first stack view
List<TaskStackView> stackViews = getTaskStackViews();
if (!stackViews.isEmpty()) {
stackViews.get(0).focusNextTask(forward, true);
if (mTaskStackView != null) {
mTaskStackView.focusNextTask(forward, true);
}
}
/** Dismisses the focused task. */
public void dismissFocusedTask() {
// Get the first stack view
List<TaskStackView> stackViews = getTaskStackViews();
if (!stackViews.isEmpty()) {
stackViews.get(0).dismissFocusedTask();
if (mTaskStackView != null) {
mTaskStackView.dismissFocusedTask();
}
}
@@ -442,9 +377,8 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
}
public void disableLayersForOneFrame() {
List<TaskStackView> stackViews = getTaskStackViews();
for (int i = 0; i < stackViews.size(); i++) {
stackViews.get(i).disableLayersForOneFrame();
if (mTaskStackView != null) {
mTaskStackView.disableLayersForOneFrame();
}
}
@@ -655,7 +589,7 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
}
postDrawHeaderThumbnailTransitionRunnable(stackView, tv, offsetX, offsetY, stackScroll,
animStartedListener);
if (mConfig.multiStackEnabled) {
if (mConfig.multiWindowEnabled) {
opts = ActivityOptions.makeCustomAnimation(sourceView.getContext(),
R.anim.recents_from_unknown_enter,
R.anim.recents_from_unknown_exit,
@@ -767,11 +701,8 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
/** Final callback after Recents is finally hidden. */
public void onRecentsHidden() {
// Notify each task stack view
List<TaskStackView> stackViews = getTaskStackViews();
int stackCount = stackViews.size();
for (int i = 0; i < stackCount; i++) {
TaskStackView stackView = stackViews.get(i);
stackView.onRecentsHidden();
if (mTaskStackView != null) {
mTaskStackView.onRecentsHidden();
}
}
@@ -815,11 +746,8 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
@Override
public void onPackagesChanged(RecentsPackageMonitor monitor, String packageName, int userId) {
// Propagate this event down to each task stack view
List<TaskStackView> stackViews = getTaskStackViews();
int stackCount = stackViews.size();
for (int i = 0; i < stackCount; i++) {
TaskStackView stackView = stackViews.get(i);
stackView.onPackagesChanged(monitor, packageName, userId);
if (mTaskStackView != null) {
mTaskStackView.onPackagesChanged(monitor, packageName, userId);
}
}
}

View File

@@ -1,59 +0,0 @@
/*
* Copyright (C) 2014 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.views;
import android.graphics.Rect;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.model.TaskStack;
import java.util.ArrayList;
import java.util.List;
/* The layout logic for the RecentsView. */
public class RecentsViewLayoutAlgorithm {
RecentsConfiguration mConfig;
public RecentsViewLayoutAlgorithm(RecentsConfiguration config) {
mConfig = config;
}
/** Return the relative coordinate given coordinates in another size. */
private int getRelativeCoordinate(int availableOffset, int availableSize, int otherCoord, int otherSize) {
float relPos = (float) otherCoord / otherSize;
return availableOffset + (int) (relPos * availableSize);
}
/**
* Computes and returns the bounds that each of the stack views should take up.
*/
List<Rect> computeStackRects(List<TaskStackView> stackViews, Rect availableBounds) {
ArrayList<Rect> bounds = new ArrayList<Rect>(stackViews.size());
int stackViewsCount = stackViews.size();
for (int i = 0; i < stackViewsCount; i++) {
TaskStack stack = stackViews.get(i).getStack();
Rect sb = stack.stackBounds;
Rect db = stack.displayBounds;
Rect ab = availableBounds;
bounds.add(new Rect(getRelativeCoordinate(ab.left, ab.width(), sb.left, db.width()),
getRelativeCoordinate(ab.top, ab.height(), sb.top, db.height()),
getRelativeCoordinate(ab.left, ab.width(), sb.right, db.width()),
getRelativeCoordinate(ab.top, ab.height(), sb.bottom, db.height())));
}
return bounds;
}
}

View File

@@ -80,7 +80,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
ArrayList<TaskViewTransform> mCurrentTaskTransforms = new ArrayList<TaskViewTransform>();
DozeTrigger mUIDozeTrigger;
DebugOverlayView mDebugOverlay;
Rect mTaskStackBounds = new Rect();
DismissView mDismissAllButton;
boolean mDismissAllButtonAnimating;
int mFocusedTaskIndex = -1;
@@ -93,6 +92,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
boolean mStartEnterAnimationRequestedAfterLayout;
boolean mStartEnterAnimationCompleted;
ViewAnimation.TaskViewEnterContext mStartEnterAnimationContext;
Rect mTaskStackBounds = new Rect();
int[] mTmpVisibleRange = new int[2];
float[] mTmpCoord = new float[2];
Matrix mTmpMatrix = new Matrix();
@@ -477,11 +477,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
mStackViewsClipDirty = false;
}
/** The stack insets to apply to the stack contents */
public void setStackInsetRect(Rect r) {
mTaskStackBounds.set(r);
}
/** Updates the min and max virtual scroll bounds */
void updateMinMaxScroll(boolean boundScrollToNewMinMax, boolean launchedWithAltTab,
boolean launchedFromHome) {
@@ -692,11 +687,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
return mTouchHandler.onGenericMotionEvent(ev);
}
/** Returns the region that touch gestures can be started in. */
Rect getTouchableRegion() {
return mTaskStackBounds;
}
@Override
public void computeScroll() {
mStackScroller.computeScroll();
@@ -736,6 +726,10 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
return mLayoutAlgorithm.computeStackVisibilityReport(mStack.getTasks());
}
public void setTaskStackBounds(Rect taskStackBounds) {
mTaskStackBounds.set(taskStackBounds);
}
/**
* This is called with the full window width and height to allow stack view children to
* perform the full screen transition down.
@@ -746,9 +740,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
int height = MeasureSpec.getSize(heightMeasureSpec);
// Compute our stack/task rects
Rect taskStackBounds = new Rect(mTaskStackBounds);
taskStackBounds.bottom -= mConfig.systemInsets.bottom;
computeRects(width, height, taskStackBounds, mConfig.launchedWithAltTab,
computeRects(width, height, mTaskStackBounds, mConfig.launchedWithAltTab,
mConfig.launchedFromHome);
// If this is the first layout, then scroll to the front of the stack and synchronize the
@@ -875,7 +867,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
}
// Start dozing
if (!mConfig.multiStackEnabled) {
if (!mConfig.multiWindowEnabled) {
mUIDozeTrigger.startDozing();
}
}
@@ -1299,7 +1291,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
RecentsTaskLoader.getInstance().loadTaskData(task);
// If the doze trigger has already fired, then update the state for this task view
if (mConfig.multiStackEnabled || mUIDozeTrigger.hasTriggered()) {
if (mConfig.multiWindowEnabled || mUIDozeTrigger.hasTriggered()) {
tv.setNoUserInteractionState();
}

View File

@@ -128,16 +128,6 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
return false;
}
int action = ev.getAction();
if (mConfig.multiStackEnabled) {
// Check if we are within the bounds of the stack view contents
if ((action & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {
if (!mSv.getTouchableRegion().contains((int) ev.getX(), (int) ev.getY())) {
return false;
}
}
}
// Pass through to swipe helper if we are swiping
mInterceptedBySwipeHelper = mSwipeHelper.onInterceptTouchEvent(ev);
if (mInterceptedBySwipeHelper) {
@@ -146,6 +136,7 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
boolean wasScrolling = mScroller.isScrolling() ||
(mScroller.mScrollAnimator != null && mScroller.mScrollAnimator.isRunning());
int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
// Save the touch down info
@@ -212,16 +203,6 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
return false;
}
int action = ev.getAction();
if (mConfig.multiStackEnabled) {
// Check if we are within the bounds of the stack view contents
if ((action & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {
if (!mSv.getTouchableRegion().contains((int) ev.getX(), (int) ev.getY())) {
return false;
}
}
}
// Pass through to swipe helper if we are swiping
if (mInterceptedBySwipeHelper && mSwipeHelper.onTouchEvent(ev)) {
return true;
@@ -230,6 +211,7 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
// Update the velocity tracker
initVelocityTrackerIfNotExists();
int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
// Save the touch down info
@@ -372,7 +354,7 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
// Shift the tap position toward the center of the task stack and check to see if it would
// have hit a view. The user might have tried to tap on a task and missed slightly.
int shiftedX = x;
if (x > mSv.getTouchableRegion().centerX()) {
if (x > (mSv.getRight() - mSv.getLeft()) / 2) {
shiftedX -= mWindowTouchSlop;
} else {
shiftedX += mWindowTouchSlop;

View File

@@ -682,7 +682,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks,
mHeaderView.mApplicationIcon.setOnClickListener(this);
}
mHeaderView.mDismissButton.setOnClickListener(this);
if (mConfig.multiStackEnabled) {
if (mConfig.multiWindowEnabled) {
mHeaderView.mMoveTaskButton.setOnClickListener(this);
}
mActionButtonView.setOnClickListener(this);
@@ -701,7 +701,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks,
// Unbind any listeners
mHeaderView.mApplicationIcon.setOnClickListener(null);
mHeaderView.mDismissButton.setOnClickListener(null);
if (mConfig.multiStackEnabled) {
if (mConfig.multiWindowEnabled) {
mHeaderView.mMoveTaskButton.setOnClickListener(null);
}
mActionButtonView.setOnClickListener(null);

View File

@@ -215,8 +215,8 @@ public class TaskViewHeader extends FrameLayout {
mLightDismissDrawable : mDarkDismissDrawable);
mDismissButton.setContentDescription(String.format(mDismissContentDescription,
t.contentDescription));
mMoveTaskButton.setVisibility((mConfig.multiStackEnabled) ? View.VISIBLE : View.INVISIBLE);
if (mConfig.multiStackEnabled) {
mMoveTaskButton.setVisibility((mConfig.multiWindowEnabled) ? View.VISIBLE : View.INVISIBLE);
if (mConfig.multiWindowEnabled) {
updateResizeTaskBarIcon(t);
}
}