DO NOT MERGE - Delete the separate grid recents activity and related code
This was the first attempt at implementing grid-based Recents. The new implementation doesn't use a separate activity and reuses a lot more code. Bug: 32101881 Test: Checked Recents behavior on local sw600dp device Change-Id: Ic3535fc49f3f5448d6002d354678b633f122f57d
This commit is contained in:
@@ -267,22 +267,6 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</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.Wallpaper">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="com.android.systemui.recents.TOGGLE_RECENTS" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<activity android:name=".recents.tv.RecentsTvActivity"
|
<activity android:name=".recents.tv.RecentsTvActivity"
|
||||||
android:label="@string/accessibility_desc_recent_apps"
|
android:label="@string/accessibility_desc_recent_apps"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
|
|||||||
@@ -1,33 +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.
|
|
||||||
-->
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:id="@+id/recents_container">
|
|
||||||
<include layout="@layout/recents_stack_action_button" />
|
|
||||||
<FrameLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:id="@+id/recents_view"
|
|
||||||
android:layout_marginLeft="12dp"
|
|
||||||
android:layout_marginTop="10dp"
|
|
||||||
android:layout_marginRight="12dp"
|
|
||||||
android:layout_marginBottom="5dp"
|
|
||||||
android:gravity="center">
|
|
||||||
</FrameLayout>
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
@@ -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.events.ui.RecentsDrawnEvent;
|
||||||
import com.android.systemui.recents.misc.SystemServicesProxy;
|
import com.android.systemui.recents.misc.SystemServicesProxy;
|
||||||
import com.android.systemui.recents.model.RecentsTaskLoader;
|
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.recents.tv.RecentsTvImpl;
|
||||||
import com.android.systemui.stackdivider.Divider;
|
import com.android.systemui.stackdivider.Divider;
|
||||||
|
|
||||||
@@ -84,7 +83,6 @@ public class Recents extends SystemUI
|
|||||||
static {
|
static {
|
||||||
RECENTS_ACTIVITIES.add(RecentsImpl.RECENTS_ACTIVITY);
|
RECENTS_ACTIVITIES.add(RecentsImpl.RECENTS_ACTIVITY);
|
||||||
RECENTS_ACTIVITIES.add(RecentsTvImpl.RECENTS_TV_ACTIVITY);
|
RECENTS_ACTIVITIES.add(RecentsTvImpl.RECENTS_TV_ACTIVITY);
|
||||||
RECENTS_ACTIVITIES.add(RecentsGridImpl.RECENTS_MOSAIC_ACTIVITY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Purely for experimentation
|
// Purely for experimentation
|
||||||
|
|||||||
@@ -1,317 +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.Activity;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.res.Configuration;
|
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.Gravity;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.view.ViewTreeObserver;
|
|
||||||
import android.widget.FrameLayout;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import com.android.internal.logging.MetricsLogger;
|
|
||||||
import com.android.internal.logging.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.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The main grid recents activity started by the RecentsImpl.
|
|
||||||
*/
|
|
||||||
public class RecentsGridActivity extends Activity implements ViewTreeObserver.OnPreDrawListener {
|
|
||||||
private final static String TAG = "RecentsGridActivity";
|
|
||||||
|
|
||||||
private TaskStack mTaskStack;
|
|
||||||
private List<Task> mTasks = new ArrayList<>();
|
|
||||||
private List<View> mTaskViews = new ArrayList<>();
|
|
||||||
private FrameLayout mRecentsView;
|
|
||||||
private TextView mEmptyView;
|
|
||||||
private View mClearAllButton;
|
|
||||||
private int mDisplayOrientation = Configuration.ORIENTATION_UNDEFINED;
|
|
||||||
private Rect mDisplayRect = new Rect();
|
|
||||||
private LayoutInflater mInflater;
|
|
||||||
private boolean mTouchExplorationEnabled;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.recents_grid);
|
|
||||||
SystemServicesProxy ssp = Recents.getSystemServices();
|
|
||||||
|
|
||||||
mInflater = LayoutInflater.from(this);
|
|
||||||
mDisplayOrientation = Utilities.getAppConfiguration(this).orientation;
|
|
||||||
mDisplayRect = ssp.getDisplayRect();
|
|
||||||
mTouchExplorationEnabled = ssp.isTouchExplorationEnabled();
|
|
||||||
|
|
||||||
mRecentsView = (FrameLayout) findViewById(R.id.recents_view);
|
|
||||||
LinearLayout recentsContainer = (LinearLayout) findViewById(R.id.recents_container);
|
|
||||||
mEmptyView = (TextView) mInflater.inflate(R.layout.recents_empty, recentsContainer, 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);
|
|
||||||
LinearLayout.LayoutParams lp =
|
|
||||||
(LinearLayout.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 clearTaskViews() {
|
|
||||||
for (View taskView : mTaskViews) {
|
|
||||||
ViewGroup parent = (ViewGroup) taskView.getParent();
|
|
||||||
if (parent != null) {
|
|
||||||
parent.removeView(taskView);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mTaskViews.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
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 updateRecentsTasks() {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
int numVisibleTasks = 9;
|
|
||||||
mTaskStack = plan.getTaskStack();
|
|
||||||
RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
|
|
||||||
loadOpts.runningTaskId = launchState.launchedToTaskId;
|
|
||||||
loadOpts.numVisibleTasks = numVisibleTasks;
|
|
||||||
loadOpts.numVisibleTaskThumbnails = numVisibleTasks;
|
|
||||||
loader.loadTasks(this, plan, loadOpts);
|
|
||||||
|
|
||||||
List<Task> stackTasks = mTaskStack.getStackTasks();
|
|
||||||
Collections.reverse(stackTasks);
|
|
||||||
mTasks = stackTasks;
|
|
||||||
|
|
||||||
updateControlVisibility();
|
|
||||||
|
|
||||||
clearTaskViews();
|
|
||||||
for (int i = 0; i < mTasks.size(); i++) {
|
|
||||||
Task task = mTasks.get(i);
|
|
||||||
TaskView taskView = createView();
|
|
||||||
taskView.onTaskBound(task, mTouchExplorationEnabled, mDisplayOrientation, mDisplayRect);
|
|
||||||
Recents.getTaskLoader().loadTaskData(task);
|
|
||||||
taskView.setTouchEnabled(true);
|
|
||||||
// Show dismiss button right away.
|
|
||||||
taskView.startNoUserInteractionAnimation();
|
|
||||||
mTaskViews.add(taskView);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, true));
|
|
||||||
mRecentsView.getViewTreeObserver().addOnPreDrawListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
updateRecentsTasks();
|
|
||||||
}
|
|
||||||
|
|
||||||
@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 boolean onPreDraw() {
|
|
||||||
mRecentsView.getViewTreeObserver().removeOnPreDrawListener(this);
|
|
||||||
int width = mRecentsView.getWidth();
|
|
||||||
int height = mRecentsView.getHeight();
|
|
||||||
|
|
||||||
List<Rect> rects = TaskGridLayoutAlgorithm.getRectsForTaskCount(
|
|
||||||
mTasks.size(), width, height, false /* allowLineOfThree */, 30 /* padding */);
|
|
||||||
for (int i = 0; i < rects.size(); i++) {
|
|
||||||
Rect rect = rects.get(i);
|
|
||||||
View taskView = mTaskViews.get(i);
|
|
||||||
taskView.setLayoutParams(new FrameLayout.LayoutParams(rect.width(), rect.height()));
|
|
||||||
taskView.setTranslationX(rect.left);
|
|
||||||
taskView.setTranslationY(rect.top);
|
|
||||||
mRecentsView.addView(taskView);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dismissRecentsToHome() {
|
|
||||||
Intent startMain = new Intent(Intent.ACTION_MAIN);
|
|
||||||
startMain.addCategory(Intent.CATEGORY_HOME);
|
|
||||||
startActivity(startMain);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**** EventBus events ****/
|
|
||||||
|
|
||||||
public final void onBusEvent(HideRecentsEvent event) {
|
|
||||||
if (event.triggeredFromAltTab) {
|
|
||||||
// Do nothing for now.
|
|
||||||
} else if (event.triggeredFromHomeKey) {
|
|
||||||
dismissRecentsToHome();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void onBusEvent(ToggleRecentsEvent event) {
|
|
||||||
// Always go back home for simplicity for now. If recents is entered from another app, this
|
|
||||||
// code will eventually need to go back to the original app.
|
|
||||||
dismissRecentsToHome();
|
|
||||||
}
|
|
||||||
|
|
||||||
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<>();
|
|
||||||
updateRecentsTasks();
|
|
||||||
|
|
||||||
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) {
|
|
||||||
// Always go back home for simplicity for now. Quick switch will be supported soon.
|
|
||||||
EventBus.getDefault().send(new HideRecentsEvent(false, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void onBusEvent(LaunchTaskEvent event) {
|
|
||||||
startActivity(event.task.key.baseIntent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,48 +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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,110 +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.List;
|
|
||||||
|
|
||||||
class TaskGridLayoutAlgorithm {
|
|
||||||
|
|
||||||
private static final String TAG = "TaskGridLayoutAlgorithm";
|
|
||||||
|
|
||||||
static List<Rect> getRectsForTaskCount(int count, int containerWidth, int containerHeight,
|
|
||||||
boolean allowLineOfThree, int padding) {
|
|
||||||
return getRectsForTaskCount(count, containerWidth, containerHeight, allowLineOfThree,
|
|
||||||
padding, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
static List<Rect> getRectsForTaskCount(int count, int containerWidth, int containerHeight,
|
|
||||||
boolean allowLineOfThree, int padding, Rect preCalculatedTile) {
|
|
||||||
int singleLineMaxCount = allowLineOfThree ? 3 : 2;
|
|
||||||
List<Rect> rects = new ArrayList<>(count);
|
|
||||||
boolean landscape = (containerWidth > containerHeight);
|
|
||||||
|
|
||||||
// We support at most 9 tasks in this layout.
|
|
||||||
count = Math.min(count, 9);
|
|
||||||
|
|
||||||
if (count == 0) {
|
|
||||||
return rects;
|
|
||||||
}
|
|
||||||
if (count <= singleLineMaxCount) {
|
|
||||||
if (landscape) {
|
|
||||||
// Single line.
|
|
||||||
int taskWidth = 0;
|
|
||||||
int emptySpace = 0;
|
|
||||||
if (preCalculatedTile != null) {
|
|
||||||
taskWidth = preCalculatedTile.width();
|
|
||||||
emptySpace = containerWidth - (count * taskWidth) - (count - 1) * padding;
|
|
||||||
} else {
|
|
||||||
// Divide available space in equal parts.
|
|
||||||
taskWidth = (containerWidth - (count - 1) * padding) / count;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
int left = emptySpace / 2 + i * taskWidth + i * padding;
|
|
||||||
rects.add(new Rect(left, 0, left + taskWidth, containerHeight));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Single column. Divide available space in equal parts.
|
|
||||||
int taskHeight = (containerHeight - (count - 1) * padding) / count;
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
int top = i * taskHeight + i * padding;
|
|
||||||
rects.add(new Rect(0, top, containerWidth, top + taskHeight));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} 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, true /* allowLineOfThree */, padding,
|
|
||||||
null);
|
|
||||||
List<Rect> rectsB = getRectsForTaskCount(
|
|
||||||
count - lineTaskCount, containerWidth, lineHeight, true /* allowLineOfThree */,
|
|
||||||
padding, rectsA.get(0));
|
|
||||||
for (Rect rect : rectsB) {
|
|
||||||
rect.offset(0, 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, true /* allowLineOfThree */, padding, null);
|
|
||||||
List<Rect> rectsB = getRectsForTaskCount(
|
|
||||||
lineTaskCount, containerWidth, lineHeight, true /* allowLineOfThree */, padding,
|
|
||||||
rectsA.get(0));
|
|
||||||
List<Rect> rectsC = getRectsForTaskCount(
|
|
||||||
count - (2 * lineTaskCount), containerWidth, lineHeight,
|
|
||||||
true /* allowLineOfThree */, padding, rectsA.get(0));
|
|
||||||
for (Rect rect : rectsB) {
|
|
||||||
rect.offset(0, lineHeight + padding);
|
|
||||||
}
|
|
||||||
for (Rect rect : rectsC) {
|
|
||||||
rect.offset(0, 2 * (lineHeight + padding));
|
|
||||||
}
|
|
||||||
rects.addAll(rectsA);
|
|
||||||
rects.addAll(rectsB);
|
|
||||||
rects.addAll(rectsC);
|
|
||||||
}
|
|
||||||
return rects;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,112 +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.List;
|
|
||||||
|
|
||||||
import static junit.framework.Assert.assertEquals;
|
|
||||||
import static junit.framework.Assert.assertTrue;
|
|
||||||
|
|
||||||
@SmallTest
|
|
||||||
public class TaskGridLayoutAlgorithmTest extends SysuiTestCase {
|
|
||||||
|
|
||||||
public void testOneTile() {
|
|
||||||
List<Rect> rects = TaskGridLayoutAlgorithm.getRectsForTaskCount(
|
|
||||||
1, 1000, 500, false /* allowLineOfThree */, 0 /* padding */);
|
|
||||||
assertEquals(1, rects.size());
|
|
||||||
Rect singleRect = rects.get(0);
|
|
||||||
assertEquals(1000, singleRect.width());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testTwoTilesLandscape() {
|
|
||||||
List<Rect> rects = TaskGridLayoutAlgorithm.getRectsForTaskCount(
|
|
||||||
2, 1200, 500, false /* allowLineOfThree */, 0 /* padding */);
|
|
||||||
assertEquals(2, rects.size());
|
|
||||||
for (Rect rect : rects) {
|
|
||||||
assertEquals(600, rect.width());
|
|
||||||
assertEquals(500, rect.height());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testTwoTilesLandscapeWithPadding() {
|
|
||||||
List<Rect> rects = TaskGridLayoutAlgorithm.getRectsForTaskCount(
|
|
||||||
2, 1200, 500, false /* allowLineOfThree */, 10 /* padding */);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testTwoTilesPortrait() {
|
|
||||||
List<Rect> rects = TaskGridLayoutAlgorithm.getRectsForTaskCount(
|
|
||||||
2, 500, 1200, false /* allowLineOfThree */, 0 /* padding */);
|
|
||||||
assertEquals(2, rects.size());
|
|
||||||
for (Rect rect : rects) {
|
|
||||||
assertEquals(500, rect.width());
|
|
||||||
assertEquals(600, rect.height());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testThreeTiles() {
|
|
||||||
List<Rect> rects = TaskGridLayoutAlgorithm.getRectsForTaskCount(
|
|
||||||
3, 1200, 500, false /* allowLineOfThree */, 0 /* padding */);
|
|
||||||
assertEquals(3, rects.size());
|
|
||||||
for (Rect rect : rects) {
|
|
||||||
assertEquals(600, rect.width());
|
|
||||||
assertEquals(250, rect.height());
|
|
||||||
}
|
|
||||||
// The third tile should be on the second line, in the middle.
|
|
||||||
Rect rectC = rects.get(2);
|
|
||||||
assertEquals(300, rectC.left);
|
|
||||||
assertEquals(250, rectC.top);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testFourTiles() {
|
|
||||||
List<Rect> rects = TaskGridLayoutAlgorithm.getRectsForTaskCount(
|
|
||||||
4, 1200, 500, false /* allowLineOfThree */, 0 /* padding */);
|
|
||||||
assertEquals(4, rects.size());
|
|
||||||
for (Rect rect : rects) {
|
|
||||||
assertEquals(600, rect.width());
|
|
||||||
assertEquals(250, rect.height());
|
|
||||||
}
|
|
||||||
Rect rectD = rects.get(3);
|
|
||||||
assertEquals(600, rectD.left);
|
|
||||||
assertEquals(250, rectD.top);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testNineTiles() {
|
|
||||||
List<Rect> rects = TaskGridLayoutAlgorithm.getRectsForTaskCount(
|
|
||||||
9, 1200, 600, false /* allowLineOfThree */, 0 /* padding */);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user