Delete the separate grid recents activity and related code

Bug: 32101881
Test: Made sure everything builds & boots on sw600dp device and checked recents
Change-Id: I1236a1ec5f5d2f485d9825c39702130bbfc243ca
This commit is contained in:
Manu Cornet
2016-12-16 16:17:33 -08:00
parent 0f0ca8e136
commit 8e17342610
9 changed files with 0 additions and 899 deletions

View File

@@ -287,22 +287,6 @@
</intent-filter>
</activity>
<activity android:name=".recents.grid.RecentsGridActivity"
android:label="@string/accessibility_desc_recent_apps"
android:exported="false"
android:launchMode="singleInstance"
android:excludeFromRecents="true"
android:stateNotNeeded="true"
android:resumeWhilePausing="true"
android:screenOrientation="behind"
android:resizeableActivity="true"
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
android:theme="@style/RecentsTheme.Grid">
<intent-filter>
<action android:name="com.android.systemui.recents.TOGGLE_RECENTS" />
</intent-filter>
</activity>
<activity android:name=".recents.tv.RecentsTvActivity"
android:label="@string/accessibility_desc_recent_apps"
android:exported="false"

View File

@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 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.
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/recents_view"
android:gravity="center"
android:background="#99000000">
<include layout="@layout/recents_stack_action_button" />
</FrameLayout>

View File

@@ -720,18 +720,4 @@
<!-- The size of a PIP menu action icon. -->
<dimen name="pip_menu_action_icon_size">32dp</dimen>
<!-- Values specific to grid-based recents. -->
<!-- Margins around recent tasks. -->
<dimen name="recents_grid_margin_left">15dp</dimen>
<dimen name="recents_grid_margin_top">70dp</dimen>
<dimen name="recents_grid_margin_right">15dp</dimen>
<dimen name="recents_grid_margin_bottom">90dp</dimen>
<!-- Margins around the "Clear all" button. -->
<dimen name="recents_grid_clear_all_margin_left">0dp</dimen>
<dimen name="recents_grid_clear_all_margin_top">30dp</dimen>
<dimen name="recents_grid_clear_all_margin_right">15dp</dimen>
<dimen name="recents_grid_clear_all_margin_bottom">0dp</dimen>
<!-- Padding in between task views. -->
<dimen name="recents_grid_inter_task_padding">15dp</dimen>
</resources>

View File

@@ -44,22 +44,6 @@
<item name="android:layout_marginBottom">0dp</item>
</style>
<!-- Grid-based Recents theme. -->
<style name="RecentsTheme.Grid">
<item name="android:windowBackground">@color/transparent</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowShowWallpaper">true</item>
<item name="android:windowDisablePreview">true</item>
<item name="clearAllStyle">@style/ClearAllButtonLargeMargins</item>
</style>
<style name="ClearAllButtonLargeMargins">
<item name="android:layout_marginStart">@dimen/recents_grid_clear_all_margin_left</item>
<item name="android:layout_marginTop">@dimen/recents_grid_clear_all_margin_top</item>
<item name="android:layout_marginEnd">@dimen/recents_grid_clear_all_margin_right</item>
<item name="android:layout_marginBottom">@dimen/recents_grid_clear_all_margin_bottom</item>
</style>
<!-- Performance optimized Recents theme (no wallpaper) -->
<style name="RecentsTheme.NoWallpaper">
<item name="android:windowBackground">@android:color/black</item>

View File

@@ -57,7 +57,6 @@ import com.android.systemui.recents.events.component.ShowUserToastEvent;
import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.model.RecentsTaskLoader;
import com.android.systemui.recents.grid.RecentsGridImpl;
import com.android.systemui.recents.tv.RecentsTvImpl;
import com.android.systemui.stackdivider.Divider;
@@ -84,7 +83,6 @@ public class Recents extends SystemUI
static {
RECENTS_ACTIVITIES.add(RecentsImpl.RECENTS_ACTIVITY);
RECENTS_ACTIVITIES.add(RecentsTvImpl.RECENTS_TV_ACTIVITY);
RECENTS_ACTIVITIES.add(RecentsGridImpl.RECENTS_MOSAIC_ACTIVITY);
}
// Purely for experimentation

View File

@@ -1,504 +0,0 @@
/*
* Copyright (C) 2016 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.grid;
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.FrameLayout;
import android.widget.TextView;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.R;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsActivity;
import com.android.systemui.recents.RecentsActivityLaunchState;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.RecentsImpl;
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.ConfigurationChangedEvent;
import com.android.systemui.recents.events.activity.HideRecentsEvent;
import com.android.systemui.recents.events.activity.LaunchNextTaskRequestEvent;
import com.android.systemui.recents.events.activity.LaunchTaskEvent;
import com.android.systemui.recents.events.activity.ToggleRecentsEvent;
import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent;
import com.android.systemui.recents.events.ui.DeleteTaskDataEvent;
import com.android.systemui.recents.events.ui.DismissAllTaskViewsEvent;
import com.android.systemui.recents.events.ui.DismissTaskViewEvent;
import com.android.systemui.recents.events.ui.TaskViewDismissedEvent;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.misc.Utilities;
import com.android.systemui.recents.model.RecentsTaskLoadPlan;
import com.android.systemui.recents.model.RecentsTaskLoader;
import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskStack;
import com.android.systemui.recents.views.TaskView;
import java.util.ArrayList;
import java.util.Arrays;
/**
* The main grid recents activity started by the RecentsImpl.
*/
public class RecentsGridActivity extends Activity {
public final static int MAX_VISIBLE_TASKS = 9;
private final static String TAG = "RecentsGridActivity";
private final static int TITLE_BAR_HEIGHT_DP = 64;
private ArrayList<Integer> mMargins = new ArrayList<>();
private TaskStack mTaskStack;
private ArrayList<Task> mTasks = new ArrayList<>();
private ArrayList<TaskView> mTaskViews = new ArrayList<>();
private ArrayList<Rect> mTaskViewRects;
private FrameLayout mRecentsView;
private TextView mEmptyView;
private View mClearAllButton;
private int mLastDisplayOrientation = Configuration.ORIENTATION_UNDEFINED;
private int mLastDisplayDensity;
private Rect mDisplayRect = new Rect();
private LayoutInflater mInflater;
private boolean mTouchExplorationEnabled;
private Point mScreenSize;
private int mTitleBarHeightPx;
private int mStatusBarHeightPx;
private int mNavigationBarHeightPx;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.recents_grid);
SystemServicesProxy ssp = Recents.getSystemServices();
Resources res = getResources();
Integer[] margins = {
res.getDimensionPixelSize(R.dimen.recents_grid_margin_left),
res.getDimensionPixelSize(R.dimen.recents_grid_margin_top),
res.getDimensionPixelSize(R.dimen.recents_grid_margin_right),
res.getDimensionPixelSize(R.dimen.recents_grid_margin_bottom),
};
mMargins.addAll(Arrays.asList(margins));
mInflater = LayoutInflater.from(this);
Configuration appConfiguration = Utilities.getAppConfiguration(this);
mDisplayRect = ssp.getDisplayRect();
mLastDisplayOrientation = appConfiguration.orientation;
mLastDisplayDensity = appConfiguration.densityDpi;
mTouchExplorationEnabled = ssp.isTouchExplorationEnabled();
mScreenSize = new Point();
getWindowManager().getDefaultDisplay().getRealSize(mScreenSize);
DisplayMetrics metrics = res.getDisplayMetrics();
mTitleBarHeightPx = (int) (TITLE_BAR_HEIGHT_DP *
((float) metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT));
mStatusBarHeightPx = res.getDimensionPixelSize(R.dimen.status_bar_height);
mNavigationBarHeightPx = res.getDimensionPixelSize(R.dimen.navigation_bar_height);
mRecentsView = (FrameLayout) findViewById(R.id.recents_view);
mRecentsView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
getWindow().getAttributes().privateFlags |=
WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;
mEmptyView = (TextView) mInflater.inflate(R.layout.recents_empty, mRecentsView, false);
mClearAllButton = findViewById(R.id.button);
FrameLayout.LayoutParams emptyViewLayoutParams = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT);
emptyViewLayoutParams.gravity = Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL;
mEmptyView.setLayoutParams(emptyViewLayoutParams);
mRecentsView.addView(mEmptyView);
mClearAllButton.setVisibility(View.VISIBLE);
FrameLayout.LayoutParams lp =
(FrameLayout.LayoutParams) mClearAllButton.getLayoutParams();
lp.gravity = Gravity.END;
mClearAllButton.setOnClickListener(v -> {
EventBus.getDefault().send(new DismissAllTaskViewsEvent());
});
mRecentsView.setOnClickListener(v -> {
EventBus.getDefault().send(new HideRecentsEvent(
false /* triggeredFromAltTab */, false /* triggeredFromHomeKey */));
});
EventBus.getDefault().register(this, RecentsActivity.EVENT_BUS_PRIORITY);
}
private TaskView createView() {
return (TaskView) mInflater.inflate(R.layout.recents_task_view, mRecentsView, false);
}
private void removeTaskViews() {
for (View taskView : mTaskViews) {
ViewGroup parent = (ViewGroup) taskView.getParent();
if (parent != null) {
parent.removeView(taskView);
}
}
}
private void clearTaskViews() {
removeTaskViews();
mTaskViews.clear();
}
private TaskView getChildViewForTask(Task task) {
for (TaskView tv : mTaskViews) {
if (tv.getTask() == task) {
return tv;
}
}
return null;
}
/**
* Starts animations for each task view to either enlarge it to the size of the screen (when
* launching a task), or (if {@code reverse} is true, to reduce it from the size of the screen
* back to its place in the recents layout (when opening recents).
* @param animationListener An animation listener for executing code before or after the
* animations run.
* @param reverse Whether the blow-up animations should be run in reverse.
*/
private void startBlowUpAnimations(Animation.AnimationListener animationListener,
boolean reverse) {
if (mTaskViews.size() == 0) {
return;
}
int screenWidth = mLastDisplayOrientation == Configuration.ORIENTATION_LANDSCAPE
? mScreenSize.x : mScreenSize.y;
int screenHeight = mLastDisplayOrientation == Configuration.ORIENTATION_LANDSCAPE
? mScreenSize.y : mScreenSize.x;
screenHeight -= mStatusBarHeightPx + mNavigationBarHeightPx;
for (int i = 0; i < mTaskViews.size(); i++) {
View tv = mTaskViews.get(i);
AnimationSet animations = new AnimationSet(true /* shareInterpolator */);
animations.setInterpolator(new DecelerateInterpolator());
if (i == 0 && animationListener != null) {
animations.setAnimationListener(animationListener);
}
animations.setFillBefore(reverse);
animations.setFillAfter(!reverse);
Rect initialRect = mTaskViewRects.get(mTaskViewRects.size() - 1 - i);
int xDelta = - initialRect.left;
int yDelta = - initialRect.top - mTitleBarHeightPx + mStatusBarHeightPx;
TranslateAnimation translate = new TranslateAnimation(
reverse ? xDelta : 0, reverse ? 0 : xDelta,
reverse ? yDelta : 0, reverse ? 0 : yDelta);
translate.setDuration(250);
animations.addAnimation(translate);
float xScale = (float) screenWidth / (float) initialRect.width();
float yScale = (float) screenHeight /
((float) initialRect.height() - mTitleBarHeightPx);
ScaleAnimation scale = new ScaleAnimation(
reverse ? xScale : 1, reverse ? 1 : xScale,
reverse ? yScale : 1, reverse ? 1 : yScale,
Animation.ABSOLUTE, 0, Animation.ABSOLUTE, mStatusBarHeightPx);
scale.setDuration(300);
animations.addAnimation(scale);
tv.startAnimation(animations);
}
}
private void updateControlVisibility() {
boolean empty = (mTasks.size() == 0);
mClearAllButton.setVisibility(empty ? View.INVISIBLE : View.VISIBLE);
mEmptyView.setVisibility(empty ? View.VISIBLE : View.INVISIBLE);
if (empty) {
mEmptyView.bringToFront();
}
}
private void updateModel() {
RecentsTaskLoader loader = Recents.getTaskLoader();
RecentsTaskLoadPlan plan = RecentsImpl.consumeInstanceLoadPlan();
if (plan == null) {
plan = loader.createLoadPlan(this);
}
RecentsConfiguration config = Recents.getConfiguration();
RecentsActivityLaunchState launchState = config.getLaunchState();
if (!plan.hasTasks()) {
loader.preloadTasks(plan, -1, !launchState.launchedFromHome);
}
mTaskStack = plan.getTaskStack();
RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
loadOpts.runningTaskId = launchState.launchedToTaskId;
loadOpts.numVisibleTasks = MAX_VISIBLE_TASKS;
loadOpts.numVisibleTaskThumbnails = MAX_VISIBLE_TASKS;
loader.loadTasks(this, plan, loadOpts);
mTasks = mTaskStack.getStackTasks();
}
private void updateViews() {
int screenWidth = mLastDisplayOrientation == Configuration.ORIENTATION_LANDSCAPE
? mScreenSize.x : mScreenSize.y;
int screenHeight = mLastDisplayOrientation == Configuration.ORIENTATION_LANDSCAPE
? mScreenSize.y : mScreenSize.x;
int paddingPixels = getResources().getDimensionPixelSize(
R.dimen.recents_grid_inter_task_padding);
mTaskViewRects = TaskGridLayoutAlgorithm.getRectsForTaskCount(
mTasks.size(), screenWidth, screenHeight, getAppRectRatio(), paddingPixels,
mMargins, mTitleBarHeightPx);
boolean recycleViews = (mTaskViews.size() == mTasks.size());
if (!recycleViews) {
clearTaskViews();
}
for (int i = 0; i < mTasks.size(); i++) {
Task task = mTasks.get(i);
// We keep the same ordering in the model as other Recents flavors (older tasks are
// first in the stack) so that the logic can be similar, but we reverse the order
// when placing views on the screen so that most recent tasks are displayed first.
Rect rect = mTaskViewRects.get(mTaskViewRects.size() - 1 - i);
TaskView taskView;
if (recycleViews) {
taskView = mTaskViews.get(i);
} else {
taskView = createView();
}
taskView.onTaskBound(task, mTouchExplorationEnabled, mLastDisplayOrientation,
mDisplayRect);
Recents.getTaskLoader().loadTaskData(task);
taskView.setTouchEnabled(true);
// Show dismiss button right away.
taskView.startNoUserInteractionAnimation();
taskView.setLayoutParams(new FrameLayout.LayoutParams(rect.width(), rect.height()));
taskView.setTranslationX(rect.left);
taskView.setTranslationY(rect.top);
if (!recycleViews) {
mRecentsView.addView(taskView);
mTaskViews.add(taskView);
}
}
updateControlVisibility();
}
private float getAppRectRatio() {
if (mLastDisplayOrientation == Configuration.ORIENTATION_LANDSCAPE) {
return (float) mScreenSize.x /
(float) (mScreenSize.y - mStatusBarHeightPx - mNavigationBarHeightPx);
} else {
return (float) mScreenSize.y /
(float) (mScreenSize.x - mStatusBarHeightPx - mNavigationBarHeightPx);
}
}
@Override
protected void onStart() {
super.onStart();
EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, true));
updateModel();
updateViews();
if (mTaskViews.size() > 0) {
mTaskViews.get(mTaskViews.size() - 1).bringToFront();
}
startBlowUpAnimations(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) { }
@Override
public void onAnimationEnd(Animation animation) {
updateViews();
}
@Override
public void onAnimationRepeat(Animation animation) { }
}, true /* reverse */);
}
@Override
protected void onStop() {
super.onStop();
EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, false));
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
@Override
public void onBackPressed() {
// Back behaves like the recents button so just trigger a toggle event.
EventBus.getDefault().send(new ToggleRecentsEvent());
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Notify of the config change.
Configuration newDeviceConfiguration = Utilities.getAppConfiguration(this);
mDisplayRect = Recents.getSystemServices().getDisplayRect();
int numStackTasks = mTaskStack.getStackTaskCount();
EventBus.getDefault().send(new ConfigurationChangedEvent(false /* fromMultiWindow */,
mLastDisplayOrientation != newDeviceConfiguration.orientation,
mLastDisplayDensity != newDeviceConfiguration.densityDpi, numStackTasks > 0));
mLastDisplayOrientation = newDeviceConfiguration.orientation;
mLastDisplayDensity = newDeviceConfiguration.densityDpi;
updateViews();
}
void dismissRecentsToHome() {
Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startActivity(startMain);
}
/** Launches the task that recents was launched from if possible. */
boolean launchPreviousTask() {
if (mRecentsView != null) {
Task task = mTaskStack.getLaunchTarget();
if (task != null) {
TaskView taskView = getChildViewForTask(task);
EventBus.getDefault().send(new LaunchTaskEvent(taskView, task, null,
INVALID_STACK_ID, false));
return true;
}
}
return false;
}
/** Dismisses recents back to the launch target task. */
boolean dismissRecentsToLaunchTargetTaskOrHome() {
SystemServicesProxy ssp = Recents.getSystemServices();
if (ssp.isRecentsActivityVisible()) {
// If we can launch the task that Recents was launched from, do that, otherwise go home.
if (launchPreviousTask()) return true;
dismissRecentsToHome();
}
return false;
}
/**** EventBus events ****/
public final void onBusEvent(HideRecentsEvent event) {
if (event.triggeredFromAltTab) {
dismissRecentsToLaunchTargetTaskOrHome();
} else if (event.triggeredFromHomeKey) {
dismissRecentsToHome();
} else {
// Fall through tap on the background view but not on any of the tasks.
dismissRecentsToHome();
}
}
public final void onBusEvent(ToggleRecentsEvent event) {
dismissRecentsToLaunchTargetTaskOrHome();
}
public final void onBusEvent(DismissTaskViewEvent event) {
int taskIndex = mTaskViews.indexOf(event.taskView);
if (taskIndex != -1) {
mTasks.remove(taskIndex);
((ViewGroup) event.taskView.getParent()).removeView(event.taskView);
mTaskViews.remove(taskIndex);
EventBus.getDefault().send(
new TaskViewDismissedEvent(event.taskView.getTask(), event.taskView, null));
}
}
public final void onBusEvent(TaskViewDismissedEvent event) {
mRecentsView.announceForAccessibility(this.getString(
R.string.accessibility_recents_item_dismissed, event.task.title));
updateControlVisibility();
EventBus.getDefault().send(new DeleteTaskDataEvent(event.task));
MetricsLogger.action(this, MetricsEvent.OVERVIEW_DISMISS,
event.task.key.getComponent().toString());
}
public final void onBusEvent(DeleteTaskDataEvent event) {
// Remove any stored data from the loader.
RecentsTaskLoader loader = Recents.getTaskLoader();
loader.deleteTaskData(event.task, false);
// Remove the task from activity manager.
SystemServicesProxy ssp = Recents.getSystemServices();
ssp.removeTask(event.task.key.id);
}
public final void onBusEvent(final DismissAllTaskViewsEvent event) {
// Keep track of the tasks which will have their data removed.
ArrayList<Task> tasks = new ArrayList<>(mTaskStack.getStackTasks());
mRecentsView.announceForAccessibility(this.getString(
R.string.accessibility_recents_all_items_dismissed));
mTaskStack.removeAllTasks();
for (int i = tasks.size() - 1; i >= 0; i--) {
EventBus.getDefault().send(new DeleteTaskDataEvent(tasks.get(i)));
}
mTasks = new ArrayList<>();
updateModel();
updateViews();
MetricsLogger.action(this, MetricsEvent.OVERVIEW_DISMISS_ALL);
}
public final void onBusEvent(AllTaskViewsDismissedEvent event) {
SystemServicesProxy ssp = Recents.getSystemServices();
if (!ssp.hasDockedTask()) {
dismissRecentsToHome();
}
}
public final void onBusEvent(LaunchNextTaskRequestEvent event) {
if (mTaskStack.getTaskCount() > 0) {
Task launchTask = mTaskStack.getNextLaunchTarget();
TaskView launchTaskView = getChildViewForTask(launchTask);
if (launchTaskView != null) {
EventBus.getDefault().send(new LaunchTaskEvent(launchTaskView,
launchTask, null, INVALID_STACK_ID, false /* screenPinningRequested */));
MetricsLogger.action(this, MetricsEvent.OVERVIEW_LAUNCH_PREVIOUS_TASK,
launchTask.key.getComponent().toString());
return;
}
}
// We couldn't find a matching task view, or there are no tasks. Just hide recents back
// to home.
EventBus.getDefault().send(new HideRecentsEvent(false, true));
}
public final void onBusEvent(LaunchTaskEvent event) {
event.taskView.bringToFront();
startActivity(event.task.key.baseIntent);
// Eventually we should start blow-up animations here, but we need to make sure it's done
// in parallel with starting the activity so that we don't introduce unneeded latency.
}
}

View File

@@ -1,47 +0,0 @@
/*
* Copyright (C) 2016 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.grid;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.os.UserHandle;
import com.android.systemui.recents.RecentsImpl;
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
public class RecentsGridImpl extends RecentsImpl {
public static final String RECENTS_MOSAIC_ACTIVITY =
"com.android.systemui.recents.grid.RecentsGridActivity";
public RecentsGridImpl(Context context) {
super(context);
}
@Override
protected void startRecentsActivity(ActivityManager.RunningTaskInfo runningTask,
boolean isHomeStackVisible, boolean animate, int growTarget) {
Intent intent = new Intent();
intent.setClassName(RECENTS_PACKAGE, RECENTS_MOSAIC_ACTIVITY);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
| Intent.FLAG_ACTIVITY_TASK_ON_HOME);
mContext.startActivityAsUser(intent, UserHandle.CURRENT);
EventBus.getDefault().send(new RecentsActivityStartingEvent());
}
}

View File

@@ -1,157 +0,0 @@
/*
* Copyright (C) 2016 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.grid;
import android.graphics.Rect;
import android.util.Log;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
class TaskGridLayoutAlgorithm {
public enum VerticalGravity {
START, END, CENTER
}
public static final List<Integer> ZERO_MARGIN = new ArrayList<>();
static {
Integer[] zero = {0, 0, 0, 0};
ZERO_MARGIN.addAll(Arrays.asList(zero));
}
private static final String TAG = "TaskGridLayoutAlgorithm";
/**
* Calculates the adequate rectangles for the specified number of tasks to be layed out on
* the screen.
* @param count The number of task views to layout.
* @param containerWidth The width of the whole area containing those tasks.
* @param containerHeight The height of the whole area containing those tasks.
* @param screenRatio The ratio of the device's screen, so that tasks have the same aspect
* ratio (ignoring the title bar).
* @param padding The amount of padding, in pixels, in between task views.
* @param margins The amount of space to be left blank around the area on the left, top, right
* and bottom.
* @param titleBarHeight The height, in pixels, of the task views title bar.
* @return A list of rectangles to be used for layout.
*/
static ArrayList<Rect> getRectsForTaskCount(int count, int containerWidth, int containerHeight,
float screenRatio, int padding, List<Integer> margins, int titleBarHeight) {
return getRectsForTaskCount(count, containerWidth, containerHeight, screenRatio, padding,
margins, titleBarHeight, null, VerticalGravity.CENTER);
}
private static ArrayList<Rect> getRectsForTaskCount(int count, int containerWidth,
int containerHeight, float screenRatio, int padding, List<Integer> margins,
int titleBarHeight, Rect preCalculatedTile, VerticalGravity gravity) {
ArrayList<Rect> rects = new ArrayList<>(count);
boolean landscape = (containerWidth > containerHeight);
containerWidth -= margins.get(0) + margins.get(2);
containerHeight -= margins.get(1) + margins.get(3);
// We support at most 9 tasks in this layout.
count = Math.min(count, RecentsGridActivity.MAX_VISIBLE_TASKS);
if (count == 0) {
return rects;
}
if (count <= 3) {
// Base case: single line.
int taskWidth, taskHeight;
if (preCalculatedTile != null) {
taskWidth = preCalculatedTile.width();
taskHeight = preCalculatedTile.height();
} else {
// Divide available width in equal parts.
int maxTaskWidth = (containerWidth - (count - 1) * padding) / count;
int maxTaskHeight = containerHeight;
if (maxTaskHeight >= maxTaskWidth / screenRatio + titleBarHeight) {
// Width bound.
taskWidth = maxTaskWidth;
taskHeight = (int) (maxTaskWidth / screenRatio + titleBarHeight);
} else {
// Height bound.
taskHeight = maxTaskHeight;
taskWidth = (int) ((taskHeight - titleBarHeight) * screenRatio);
}
}
int emptySpaceX = containerWidth - (count * taskWidth) - (count - 1) * padding;
int emptySpaceY = containerHeight - taskHeight;
for (int i = 0; i < count; i++) {
int left = emptySpaceX / 2 + i * taskWidth + i * padding;
int top;
switch (gravity) {
case CENTER:
top = emptySpaceY / 2;
break;
case END:
top = emptySpaceY;
break;
case START:
default:
top = 0;
break;
}
Rect rect = new Rect(left, top, left + taskWidth, top + taskHeight);
rect.offset(margins.get(0), margins.get(1));
rects.add(rect);
}
} else if (count < 7) {
// Two lines.
int lineHeight = (containerHeight - padding) / 2;
int lineTaskCount = (int) Math.ceil((double) count / 2);
List<Rect> rectsA = getRectsForTaskCount(lineTaskCount, containerWidth, lineHeight,
screenRatio, padding, ZERO_MARGIN, titleBarHeight, null, VerticalGravity.END);
List<Rect> rectsB = getRectsForTaskCount(count - lineTaskCount, containerWidth,
lineHeight, screenRatio, padding, ZERO_MARGIN, titleBarHeight, rectsA.get(0),
VerticalGravity.START);
for (int i = 0; i < rectsA.size(); i++) {
rectsA.get(i).offset(margins.get(0), margins.get(1));
}
for (int i = 0; i < rectsB.size(); i++) {
rectsB.get(i).offset(margins.get(0), margins.get(1) + lineHeight + padding);
}
rects.addAll(rectsA);
rects.addAll(rectsB);
} else {
// Three lines.
int lineHeight = (containerHeight - 2 * padding) / 3;
int lineTaskCount = (int) Math.ceil((double) count / 3);
List<Rect> rectsA = getRectsForTaskCount(lineTaskCount, containerWidth, lineHeight,
screenRatio, padding, ZERO_MARGIN, titleBarHeight, null, VerticalGravity.END);
List<Rect> rectsB = getRectsForTaskCount(lineTaskCount, containerWidth, lineHeight,
screenRatio, padding, ZERO_MARGIN, titleBarHeight, rectsA.get(0),
VerticalGravity.END);
List<Rect> rectsC = getRectsForTaskCount(count - (2 * lineTaskCount), containerWidth,
lineHeight, screenRatio, padding, ZERO_MARGIN, titleBarHeight, rectsA.get(0),
VerticalGravity.START);
for (int i = 0; i < rectsA.size(); i++) {
rectsA.get(i).offset(margins.get(0), margins.get(1));
}
for (int i = 0; i < rectsB.size(); i++) {
rectsB.get(i).offset(margins.get(0), margins.get(1) + lineHeight + padding);
}
for (int i = 0; i < rectsC.size(); i++) {
rectsC.get(i).offset(margins.get(0), margins.get(1) + 2 * (lineHeight + padding));
}
rects.addAll(rectsA);
rects.addAll(rectsB);
rects.addAll(rectsC);
}
return rects;
}
}

View File

@@ -1,120 +0,0 @@
/*
* Copyright (C) 2016 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.grid;
import android.graphics.Rect;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.systemui.SysuiTestCase;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
import org.junit.Test;
@SmallTest
public class TaskGridLayoutAlgorithmTest extends SysuiTestCase {
private static final List<Integer> ZERO_MARGIN = TaskGridLayoutAlgorithm.ZERO_MARGIN;
@Test
public void testOneTile() {
List<Rect> rects = TaskGridLayoutAlgorithm.getRectsForTaskCount(
1, 1000, 1000, 1 /* screenRatio */, 0 /* padding */, ZERO_MARGIN, 0);
assertEquals(1, rects.size());
Rect singleRect = rects.get(0);
assertEquals(1000, singleRect.width());
}
@Test
public void testTwoTilesLandscape() {
List<Rect> rects = TaskGridLayoutAlgorithm.getRectsForTaskCount(
2, 1200, 500, 1.2f /* screenRatio */, 0 /* padding */, ZERO_MARGIN, 0);
assertEquals(2, rects.size());
for (Rect rect : rects) {
assertEquals(600, rect.width());
assertEquals(499, rect.height());
}
}
@Test
public void testTwoTilesLandscapeWithPadding() {
List<Rect> rects = TaskGridLayoutAlgorithm.getRectsForTaskCount(
2, 1200, 500, 1.19f /* screenRatio */, 10 /* padding */, ZERO_MARGIN, 0);
assertEquals(2, rects.size());
Rect rectA = rects.get(0);
Rect rectB = rects.get(1);
assertEquals(595, rectA.width());
assertEquals(595, rectB.width());
assertEquals(605, rectB.left);
}
@Test
public void testTwoTilesPortrait() {
List<Rect> rects = TaskGridLayoutAlgorithm.getRectsForTaskCount(
2, 500, 1200, 1 /* screenRatio */, 0 /* padding */, ZERO_MARGIN, 0);
assertEquals(2, rects.size());
for (Rect rect : rects) {
assertEquals(250, rect.width());
assertEquals(250, rect.height());
}
}
@Test
public void testThreeTiles() {
List<Rect> rects = TaskGridLayoutAlgorithm.getRectsForTaskCount(
3, 1200, 500, 2 /* screenRatio */, 0 /* padding */, ZERO_MARGIN, 0);
assertEquals(3, rects.size());
for (Rect rect : rects) {
assertEquals(400, rect.width());
assertEquals(200, rect.height());
}
}
@Test
public void testFourTiles() {
List<Rect> rects = TaskGridLayoutAlgorithm.getRectsForTaskCount(
4, 1200, 500, 2.4f /* screenRatio */, 0 /* padding */, ZERO_MARGIN, 0);
assertEquals(4, rects.size());
for (Rect rect : rects) {
assertEquals(600, rect.width());
assertEquals(249, rect.height());
}
Rect rectD = rects.get(3);
assertEquals(600, rectD.left);
assertEquals(250, rectD.top);
}
@Test
public void testNineTiles() {
List<Rect> rects = TaskGridLayoutAlgorithm.getRectsForTaskCount(
9, 1200, 600, 2 /* screenRatio */, 0 /* padding */, ZERO_MARGIN, 0);
assertEquals(9, rects.size());
for (Rect rect : rects) {
assertEquals(400, rect.width());
assertEquals(200, rect.height());
}
Rect rectE = rects.get(4);
assertEquals(400, rectE.left);
assertEquals(200, rectE.top);
Rect rectI = rects.get(8);
assertEquals(800, rectI.left);
assertEquals(400, rectI.top);
}}