diff --git a/go/quickstep/res/layout/fallback_recents_activity.xml b/go/quickstep/res/layout/fallback_recents_activity.xml new file mode 100644 index 0000000000..653f463c91 --- /dev/null +++ b/go/quickstep/res/layout/fallback_recents_activity.xml @@ -0,0 +1,30 @@ + + + + + diff --git a/go/quickstep/src/com/android/quickstep/RecentsActivity.java b/go/quickstep/src/com/android/quickstep/RecentsActivity.java new file mode 100644 index 0000000000..a186aaa839 --- /dev/null +++ b/go/quickstep/src/com/android/quickstep/RecentsActivity.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2019 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.quickstep; + +import android.app.ActivityOptions; +import android.view.View; + +import com.android.launcher3.R; +import com.android.launcher3.views.BaseDragLayer; +import com.android.quickstep.fallback.GoRecentsActivityRootView; +import com.android.quickstep.views.IconRecentsView; + +/** + * A recents activity that displays recent tasks with an icon and small snapshot. + */ +public final class RecentsActivity extends BaseRecentsActivity { + + private GoRecentsActivityRootView mRecentsRootView; + private IconRecentsView mIconRecentsView; + + @Override + protected void initViews() { + setContentView(R.layout.fallback_recents_activity); + mRecentsRootView = findViewById(R.id.drag_layer); + mIconRecentsView = findViewById(R.id.overview_panel); + } + + @Override + protected void reapplyUi() { + //TODO: Implement this depending on how insets will affect the view. + } + + @Override + public BaseDragLayer getDragLayer() { + return mRecentsRootView; + } + + @Override + public View getRootView() { + return mRecentsRootView; + } + + @Override + public T getOverviewPanel() { + return (T) mIconRecentsView; + } + + @Override + public ActivityOptions getActivityLaunchOptions(View v) { + //TODO: Hook into recents launch animation + return null; + } + + @Override + protected void onStart() { + // Set the alpha to 1 before calling super, as it may get set back to 0 due to + // onActivityStart callback. + mIconRecentsView.setAlpha(0); + super.onStart(); + } +} diff --git a/go/quickstep/src/com/android/quickstep/fallback/GoRecentsActivityRootView.java b/go/quickstep/src/com/android/quickstep/fallback/GoRecentsActivityRootView.java new file mode 100644 index 0000000000..d748e89e91 --- /dev/null +++ b/go/quickstep/src/com/android/quickstep/fallback/GoRecentsActivityRootView.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2019 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.quickstep.fallback; + +import android.content.Context; +import android.util.AttributeSet; + +import com.android.launcher3.views.BaseDragLayer; +import com.android.quickstep.RecentsActivity; + +/** + * Minimal implementation of {@link BaseDragLayer} for Go's fallback recents activity. + */ +public final class GoRecentsActivityRootView extends BaseDragLayer { + public GoRecentsActivityRootView(Context context, AttributeSet attrs) { + super(context, attrs, 1 /* alphaChannelCount */); + } +} diff --git a/quickstep/res/layout/fallback_recents_activity.xml b/quickstep/recents_ui_overrides/res/layout/fallback_recents_activity.xml similarity index 100% rename from quickstep/res/layout/fallback_recents_activity.xml rename to quickstep/recents_ui_overrides/res/layout/fallback_recents_activity.xml diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java similarity index 63% rename from quickstep/src/com/android/quickstep/RecentsActivity.java rename to quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java index b76a1ab466..8d7039e600 100644 --- a/quickstep/src/com/android/quickstep/RecentsActivity.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * Copyright (C) 2019 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. @@ -15,12 +15,11 @@ */ package com.android.quickstep; -import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION; -import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE; - import static com.android.launcher3.QuickstepAppTransitionManagerImpl.RECENTS_LAUNCH_DURATION; -import static com.android.launcher3.QuickstepAppTransitionManagerImpl.STATUS_BAR_TRANSITION_DURATION; -import static com.android.launcher3.QuickstepAppTransitionManagerImpl.STATUS_BAR_TRANSITION_PRE_DELAY; +import static com.android.launcher3.QuickstepAppTransitionManagerImpl + .STATUS_BAR_TRANSITION_DURATION; +import static com.android.launcher3.QuickstepAppTransitionManagerImpl + .STATUS_BAR_TRANSITION_PRE_DELAY; import static com.android.quickstep.TaskUtils.getRecentsWindowAnimator; import static com.android.quickstep.TaskUtils.taskIsATargetWithMode; import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING; @@ -29,23 +28,16 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.app.ActivityOptions; -import android.content.Intent; import android.content.res.Configuration; -import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.view.View; -import com.android.launcher3.AbstractFloatingView; -import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.DeviceProfile; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherAnimationRunner; import com.android.launcher3.R; import com.android.launcher3.anim.Interpolators; -import com.android.launcher3.uioverrides.UiFactory; -import com.android.launcher3.util.SystemUiController; -import com.android.launcher3.util.Themes; import com.android.launcher3.views.BaseDragLayer; import com.android.quickstep.fallback.FallbackRecentsView; import com.android.quickstep.fallback.RecentsRootView; @@ -56,46 +48,22 @@ import com.android.systemui.shared.system.RemoteAnimationAdapterCompat; import com.android.systemui.shared.system.RemoteAnimationRunnerCompat; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; -import java.io.FileDescriptor; -import java.io.PrintWriter; - /** - * A simple activity to show the recently launched tasks + * A recents activity that shows the recently launched tasks as swipable task cards. + * See {@link com.android.quickstep.views.RecentsView}. */ -public class RecentsActivity extends BaseDraggingActivity { +public final class RecentsActivity extends BaseRecentsActivity { private Handler mUiHandler = new Handler(Looper.getMainLooper()); private RecentsRootView mRecentsRootView; private FallbackRecentsView mFallbackRecentsView; - private Configuration mOldConfig; - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - mOldConfig = new Configuration(getResources().getConfiguration()); - initDeviceProfile(); - + protected void initViews() { setContentView(R.layout.fallback_recents_activity); mRecentsRootView = findViewById(R.id.drag_layer); mFallbackRecentsView = findViewById(R.id.overview_panel); - mRecentsRootView.setup(); - - getSystemUiController().updateUiState(SystemUiController.UI_STATE_BASE_WINDOW, - Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText)); - RecentsActivityTracker.onRecentsActivityCreate(this); - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - int diff = newConfig.diff(mOldConfig); - if ((diff & (CONFIG_ORIENTATION | CONFIG_SCREEN_SIZE)) != 0) { - onHandleConfigChanged(); - } - mOldConfig.setTo(newConfig); - super.onConfigurationChanged(newConfig); } @Override @@ -110,16 +78,10 @@ public class RecentsActivity extends BaseDraggingActivity { } } - private void onHandleConfigChanged() { - mUserEventDispatcher = null; - initDeviceProfile(); - - AbstractFloatingView.closeOpenViews(this, true, - AbstractFloatingView.TYPE_ALL & ~AbstractFloatingView.TYPE_REBIND_SAFE); - dispatchDeviceProfileChanged(); - + @Override + protected void onHandleConfigChanged() { + super.onHandleConfigChanged(); mRecentsRootView.setup(); - reapplyUi(); } @Override @@ -127,15 +89,12 @@ public class RecentsActivity extends BaseDraggingActivity { mRecentsRootView.dispatchInsets(); } - private void initDeviceProfile() { + @Override + protected DeviceProfile createDeviceProfile() { DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(this).getDeviceProfile(this); - - // In case we are reusing IDP, create a copy so that we don't conflict with Launcher - // activity. - mDeviceProfile = (mRecentsRootView != null) && isInMultiWindowMode() + return (mRecentsRootView != null) && isInMultiWindowMode() ? dp.getMultiWindowProfile(this, mRecentsRootView.getLastKnownSize()) - : dp.copy(this); - onDeviceProfileInitiated(); + : super.createDeviceProfile(); } @Override @@ -211,55 +170,4 @@ public class RecentsActivity extends BaseDraggingActivity { super.onStart(); mFallbackRecentsView.resetTaskVisuals(); } - - @Override - protected void onStop() { - super.onStop(); - - // Workaround for b/78520668, explicitly trim memory once UI is hidden - onTrimMemory(TRIM_MEMORY_UI_HIDDEN); - } - - @Override - public void onEnterAnimationComplete() { - super.onEnterAnimationComplete(); - UiFactory.onEnterAnimationComplete(this); - } - - @Override - public void onTrimMemory(int level) { - super.onTrimMemory(level); - UiFactory.onTrimMemory(this, level); - } - - @Override - protected void onNewIntent(Intent intent) { - super.onNewIntent(intent); - RecentsActivityTracker.onRecentsActivityNewIntent(this); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - RecentsActivityTracker.onRecentsActivityDestroy(this); - } - - @Override - public void onBackPressed() { - // TODO: Launch the task we came from - startHome(); - } - - public void startHome() { - startActivity(new Intent(Intent.ACTION_MAIN) - .addCategory(Intent.CATEGORY_HOME) - .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); - } - - @Override - public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { - super.dump(prefix, fd, writer, args); - writer.println(prefix + "Misc:"); - dumpMisc(writer); - } } diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java similarity index 100% rename from quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java rename to quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java diff --git a/quickstep/src/com/android/quickstep/fallback/RecentsRootView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsRootView.java similarity index 100% rename from quickstep/src/com/android/quickstep/fallback/RecentsRootView.java rename to quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsRootView.java diff --git a/quickstep/src/com/android/quickstep/fallback/RecentsTaskController.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsTaskController.java similarity index 100% rename from quickstep/src/com/android/quickstep/fallback/RecentsTaskController.java rename to quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsTaskController.java diff --git a/quickstep/src/com/android/quickstep/BaseRecentsActivity.java b/quickstep/src/com/android/quickstep/BaseRecentsActivity.java new file mode 100644 index 0000000000..c84013257b --- /dev/null +++ b/quickstep/src/com/android/quickstep/BaseRecentsActivity.java @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2019 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.quickstep; + +import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION; +import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE; + +import android.content.Intent; +import android.content.res.Configuration; +import android.os.Bundle; + +import com.android.launcher3.AbstractFloatingView; +import com.android.launcher3.BaseDraggingActivity; +import com.android.launcher3.DeviceProfile; +import com.android.launcher3.InvariantDeviceProfile; +import com.android.launcher3.R; +import com.android.launcher3.uioverrides.UiFactory; +import com.android.launcher3.util.SystemUiController; +import com.android.launcher3.util.Themes; + +import java.io.FileDescriptor; +import java.io.PrintWriter; + +/** + * A base fallback recents activity that provides support for device profile changes, activity + * lifecycle tracking, and basic input handling from recents. + * + * This class is only used as a fallback in case the default launcher does not have a recents + * implementation. + */ +public abstract class BaseRecentsActivity extends BaseDraggingActivity { + + private Configuration mOldConfig; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mOldConfig = new Configuration(getResources().getConfiguration()); + initDeviceProfile(); + initViews(); + + getSystemUiController().updateUiState(SystemUiController.UI_STATE_BASE_WINDOW, + Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText)); + RecentsActivityTracker.onRecentsActivityCreate(this); + } + + /** + * Init drag layer and overview panel views. + */ + abstract protected void initViews(); + + @Override + public void onConfigurationChanged(Configuration newConfig) { + int diff = newConfig.diff(mOldConfig); + if ((diff & (CONFIG_ORIENTATION | CONFIG_SCREEN_SIZE)) != 0) { + onHandleConfigChanged(); + } + mOldConfig.setTo(newConfig); + super.onConfigurationChanged(newConfig); + } + + /** + * Logic for when device configuration changes (rotation, screen size change, multi-window, + * etc.) + */ + protected void onHandleConfigChanged() { + mUserEventDispatcher = null; + initDeviceProfile(); + + AbstractFloatingView.closeOpenViews(this, true, + AbstractFloatingView.TYPE_ALL & ~AbstractFloatingView.TYPE_REBIND_SAFE); + dispatchDeviceProfileChanged(); + + reapplyUi(); + } + + /** + * Initialize/update the device profile. + */ + private void initDeviceProfile() { + mDeviceProfile = createDeviceProfile(); + onDeviceProfileInitiated(); + } + + /** + * Generate the device profile to use in this activity. + * @return device profile + */ + protected DeviceProfile createDeviceProfile() { + DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(this).getDeviceProfile(this); + + // In case we are reusing IDP, create a copy so that we don't conflict with Launcher + // activity. + return dp.copy(this); + } + + + @Override + protected void onStop() { + super.onStop(); + + // Workaround for b/78520668, explicitly trim memory once UI is hidden + onTrimMemory(TRIM_MEMORY_UI_HIDDEN); + } + + @Override + public void onEnterAnimationComplete() { + super.onEnterAnimationComplete(); + UiFactory.onEnterAnimationComplete(this); + } + + @Override + public void onTrimMemory(int level) { + super.onTrimMemory(level); + UiFactory.onTrimMemory(this, level); + } + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + RecentsActivityTracker.onRecentsActivityNewIntent(this); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + RecentsActivityTracker.onRecentsActivityDestroy(this); + } + + @Override + public void onBackPressed() { + // TODO: Launch the task we came from + startHome(); + } + + public void startHome() { + startActivity(new Intent(Intent.ACTION_MAIN) + .addCategory(Intent.CATEGORY_HOME) + .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); + } + + @Override + public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { + super.dump(prefix, fd, writer, args); + writer.println(prefix + "Misc:"); + dumpMisc(writer); + } +} diff --git a/quickstep/src/com/android/quickstep/RecentsActivityTracker.java b/quickstep/src/com/android/quickstep/RecentsActivityTracker.java index fb6090e2a5..0822e6199b 100644 --- a/quickstep/src/com/android/quickstep/RecentsActivityTracker.java +++ b/quickstep/src/com/android/quickstep/RecentsActivityTracker.java @@ -30,17 +30,18 @@ import java.lang.ref.WeakReference; import java.util.function.BiPredicate; /** - * Utility class to track create/destroy for RecentsActivity + * Utility class to track create/destroy for some {@link BaseRecentsActivity}. */ @TargetApi(Build.VERSION_CODES.P) -public class RecentsActivityTracker implements ActivityInitListener { +public class RecentsActivityTracker implements ActivityInitListener { - private static WeakReference sCurrentActivity = new WeakReference<>(null); + private static WeakReference sCurrentActivity = + new WeakReference<>(null); private static final Scheduler sScheduler = new Scheduler(); - private final BiPredicate mOnInitListener; + private final BiPredicate mOnInitListener; - public RecentsActivityTracker(BiPredicate onInitListener) { + public RecentsActivityTracker(BiPredicate onInitListener) { mOnInitListener = onInitListener; } @@ -54,12 +55,12 @@ public class RecentsActivityTracker implements ActivityInitListener { sScheduler.clearReference(this); } - private boolean init(RecentsActivity activity, boolean visible) { + private boolean init(T activity, boolean visible) { return mOnInitListener.test(activity, visible); } - public static RecentsActivity getCurrentActivity() { - return sCurrentActivity.get(); + public static T getCurrentActivity() { + return (T) sCurrentActivity.get(); } @Override @@ -71,17 +72,17 @@ public class RecentsActivityTracker implements ActivityInitListener { context.startActivity(intent, options); } - public static void onRecentsActivityCreate(RecentsActivity activity) { + public static void onRecentsActivityCreate(BaseRecentsActivity activity) { sCurrentActivity = new WeakReference<>(activity); sScheduler.initIfPending(activity, false); } - public static void onRecentsActivityNewIntent(RecentsActivity activity) { + public static void onRecentsActivityNewIntent(BaseRecentsActivity activity) { sScheduler.initIfPending(activity, activity.isStarted()); } - public static void onRecentsActivityDestroy(RecentsActivity activity) { + public static void onRecentsActivityDestroy(BaseRecentsActivity activity) { if (sCurrentActivity.get() == activity) { sCurrentActivity.clear(); } @@ -103,13 +104,14 @@ public class RecentsActivityTracker implements ActivityInitListener { @Override public void run() { - RecentsActivity activity = sCurrentActivity.get(); + BaseRecentsActivity activity = sCurrentActivity.get(); if (activity != null) { initIfPending(activity, activity.isStarted()); } } - public synchronized boolean initIfPending(RecentsActivity activity, boolean alreadyOnHome) { + public synchronized boolean initIfPending(BaseRecentsActivity activity, + boolean alreadyOnHome) { RecentsActivityTracker tracker = mPendingTracker.get(); if (tracker != null) { if (!tracker.init(activity, alreadyOnHome)) {