diff --git a/quickstep/recents_ui_overrides/res/layout/fallback_recents_activity.xml b/quickstep/recents_ui_overrides/res/layout/fallback_recents_activity.xml
index 7b3e37835f..cd64a94bab 100644
--- a/quickstep/recents_ui_overrides/res/layout/fallback_recents_activity.xml
+++ b/quickstep/recents_ui_overrides/res/layout/fallback_recents_activity.xml
@@ -13,25 +13,30 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
-
+ android:clipChildren="false">
-
+
-
+
+
+
+
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java
index 170102047b..6f2f9fb523 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java
@@ -55,7 +55,7 @@ import com.android.launcher3.util.Themes;
import com.android.launcher3.views.BaseDragLayer;
import com.android.quickstep.fallback.FallbackRecentsStateController;
import com.android.quickstep.fallback.FallbackRecentsView;
-import com.android.quickstep.fallback.RecentsRootView;
+import com.android.quickstep.fallback.RecentsDragLayer;
import com.android.quickstep.fallback.RecentsState;
import com.android.quickstep.util.RecentsAtomicAnimationFactory;
import com.android.quickstep.views.OverviewActionsView;
@@ -78,7 +78,8 @@ public final class RecentsActivity extends StatefulActivity {
new ActivityTracker<>();
private Handler mUiHandler = new Handler(Looper.getMainLooper());
- private RecentsRootView mRecentsRootView;
+
+ private RecentsDragLayer mDragLayer;
private FallbackRecentsView mFallbackRecentsView;
private OverviewActionsView mActionsView;
@@ -89,13 +90,14 @@ public final class RecentsActivity extends StatefulActivity {
/**
* Init drag layer and overview panel views.
*/
- protected void initViews() {
- setContentView(R.layout.fallback_recents_activity);
- mRecentsRootView = findViewById(R.id.drag_layer);
+ protected void setupViews() {
+ inflateRootView(R.layout.fallback_recents_activity);
+ setContentView(getRootView());
+ mDragLayer = findViewById(R.id.drag_layer);
mFallbackRecentsView = findViewById(R.id.overview_panel);
mActionsView = findViewById(R.id.overview_actions_view);
- mRecentsRootView.recreateControllers();
+ mDragLayer.recreateControllers();
mFallbackRecentsView.init(mActionsView);
}
@@ -105,12 +107,6 @@ public final class RecentsActivity extends StatefulActivity {
super.onMultiWindowModeChanged(isInMultiWindowMode, newConfig);
}
- public void onRootViewSizeChanged() {
- if (isInMultiWindowMode()) {
- onHandleConfigChanged();
- }
- }
-
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
@@ -130,7 +126,7 @@ public final class RecentsActivity extends StatefulActivity {
dispatchDeviceProfileChanged();
reapplyUi();
- mRecentsRootView.recreateControllers();
+ mDragLayer.recreateControllers();
}
/**
@@ -142,19 +138,14 @@ public final class RecentsActivity extends StatefulActivity {
// In case we are reusing IDP, create a copy so that we don't conflict with Launcher
// activity.
- return (mRecentsRootView != null) && isInMultiWindowMode()
+ return (mDragLayer != null) && isInMultiWindowMode()
? dp.getMultiWindowProfile(this, getMultiWindowDisplaySize())
: dp.copy(this);
}
@Override
public BaseDragLayer getDragLayer() {
- return mRecentsRootView;
- }
-
- @Override
- public View getRootView() {
- return mRecentsRootView;
+ return mDragLayer;
}
@Override
@@ -252,7 +243,7 @@ public final class RecentsActivity extends StatefulActivity {
mOldConfig = new Configuration(getResources().getConfiguration());
initDeviceProfile();
- initViews();
+ setupViews();
getSystemUiController().updateUiState(SystemUiController.UI_STATE_BASE_WINDOW,
Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText));
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java
index 9242771dd9..d20bbe9780 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -106,12 +106,23 @@ public class FallbackRecentsView extends RecentsView
}
}
+ @Override
+ protected boolean shouldAddDummyTaskView(int runningTaskId) {
+ if (mHomeTaskInfo != null && mHomeTaskInfo.taskId == runningTaskId
+ && getTaskViewCount() == 0) {
+ // Do not add a dummy task if we are running over home with empty recents, so that we
+ // show the empty recents message instead of showing a dummy task and later removing it.
+ return false;
+ }
+ return super.shouldAddDummyTaskView(runningTaskId);
+ }
+
@Override
protected void applyLoadPlan(ArrayList tasks) {
// When quick-switching on 3p-launcher, we add a "dummy" tile corresponding to Launcher
// as well. This tile is never shown as we have setCurrentTaskHidden, but allows use to
// track the index of the next task appropriately, as if we are switching on any other app.
- if (mHomeTaskInfo != null && mHomeTaskInfo.taskId == mRunningTaskId) {
+ if (mHomeTaskInfo != null && mHomeTaskInfo.taskId == mRunningTaskId && !tasks.isEmpty()) {
// Check if the task list has running task
boolean found = false;
for (Task t : tasks) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsDragLayer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsDragLayer.java
new file mode 100644
index 0000000000..a00015a233
--- /dev/null
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsDragLayer.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2018 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.graphics.Rect;
+import android.util.AttributeSet;
+
+import com.android.launcher3.R;
+import com.android.launcher3.util.Themes;
+import com.android.launcher3.util.TouchController;
+import com.android.launcher3.views.BaseDragLayer;
+import com.android.quickstep.RecentsActivity;
+
+/**
+ * Drag layer for fallback recents activity
+ */
+public class RecentsDragLayer extends BaseDragLayer {
+
+ public RecentsDragLayer(Context context, AttributeSet attrs) {
+ super(context, attrs, 1 /* alphaChannelCount */);
+ }
+
+ @Override
+ public void recreateControllers() {
+ mControllers = new TouchController[] {
+ new RecentsTaskController(mActivity),
+ new FallbackNavBarTouchController(mActivity),
+ };
+ }
+
+ @Override
+ public void setInsets(Rect insets) {
+ super.setInsets(insets);
+ setBackground(insets.top == 0 || !mAllowSysuiScrims
+ ? null
+ : Themes.getAttrDrawable(getContext(), R.attr.workspaceStatusBarScrim));
+ }
+}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsRootView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsRootView.java
deleted file mode 100644
index 7f5ec9bc12..0000000000
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsRootView.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2018 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.annotation.TargetApi;
-import android.content.Context;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-
-import com.android.launcher3.R;
-import com.android.launcher3.util.Themes;
-import com.android.launcher3.util.TouchController;
-import com.android.launcher3.views.BaseDragLayer;
-import com.android.quickstep.RecentsActivity;
-
-public class RecentsRootView extends BaseDragLayer {
-
- private static final int MIN_SIZE = 10;
-
- private final Point mLastKnownSize = new Point(MIN_SIZE, MIN_SIZE);
-
- public RecentsRootView(Context context, AttributeSet attrs) {
- super(context, attrs, 1 /* alphaChannelCount */);
- setSystemUiVisibility(SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- | SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
- | SYSTEM_UI_FLAG_LAYOUT_STABLE);
- }
-
- public Point getLastKnownSize() {
- return mLastKnownSize;
- }
-
- @Override
- public void recreateControllers() {
- mControllers = new TouchController[] {
- new RecentsTaskController(mActivity),
- new FallbackNavBarTouchController(mActivity),
- };
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- // Check size changes before the actual measure, to avoid multiple measure calls.
- int width = Math.max(MIN_SIZE, MeasureSpec.getSize(widthMeasureSpec));
- int height = Math.max(MIN_SIZE, MeasureSpec.getSize(heightMeasureSpec));
- if (mLastKnownSize.x != width || mLastKnownSize.y != height) {
- mLastKnownSize.set(width, height);
- mActivity.onRootViewSizeChanged();
- }
-
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- }
-
- @TargetApi(23)
- @Override
- protected boolean fitSystemWindows(Rect insets) {
- // Update device profile before notifying the children.
- mActivity.getDeviceProfile().updateInsets(insets);
- setInsets(insets);
- return false; // Let children get the full insets
- }
-
- @Override
- public void setInsets(Rect insets) {
- // If the insets haven't changed, this is a no-op. Avoid unnecessary layout caused by
- // modifying child layout params.
- if (!insets.equals(mInsets)) {
- super.setInsets(insets);
- }
- setBackground(insets.top == 0 || !mAllowSysuiScrims
- ? null
- : Themes.getAttrDrawable(getContext(), R.attr.workspaceStatusBarScrim));
- }
-
- public void dispatchInsets() {
- mActivity.getDeviceProfile().updateInsets(mInsets);
- super.setInsets(mInsets);
- }
-}
\ No newline at end of file
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
index 6380bbefa0..e89e56641b 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
@@ -105,6 +105,7 @@ import com.android.launcher3.anim.SpringProperty;
import com.android.launcher3.compat.AccessibilityManagerCompat;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.statehandlers.DepthController;
+import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.touch.PagedOrientationHandler.CurveProperties;
import com.android.launcher3.userevent.nano.LauncherLogProto;
@@ -146,8 +147,8 @@ import java.util.function.Consumer;
* A list of recent tasks.
*/
@TargetApi(Build.VERSION_CODES.P)
-public abstract class RecentsView extends PagedView implements Insettable,
- TaskThumbnailCache.HighResLoadingState.HighResLoadingStateChangedCallback,
+public abstract class RecentsView extends PagedView implements
+ Insettable, TaskThumbnailCache.HighResLoadingState.HighResLoadingStateChangedCallback,
InvariantDeviceProfile.OnIDPChangeListener, TaskVisualsChangeListener,
SplitScreenBounds.OnChangeListener {
@@ -389,12 +390,12 @@ public abstract class RecentsView extends PagedView impl
setPageSpacing(getResources().getDimensionPixelSize(R.dimen.recents_page_spacing));
setEnableFreeScroll(true);
mSizeStrategy = sizeStrategy;
+ mActivity = BaseActivity.fromContext(context);
mOrientationState = new RecentsOrientedState(
context, mSizeStrategy, this::animateRecentsRotationInPlace);
mFastFlingVelocity = getResources()
.getDimensionPixelSize(R.dimen.recents_fast_fling_velocity);
- mActivity = BaseActivity.fromContext(context);
mModel = RecentsModel.INSTANCE.get(context);
mIdp = InvariantDeviceProfile.INSTANCE.get(context);
@@ -1114,6 +1115,13 @@ public abstract class RecentsView extends PagedView impl
animateActionsViewIn();
}
+ /**
+ * Returns true if we should add a dummy taskView for the running task id
+ */
+ protected boolean shouldAddDummyTaskView(int runningTaskId) {
+ return getTaskView(runningTaskId) == null;
+ }
+
/**
* Creates a task view (if necessary) to represent the task with the {@param runningTaskId}.
*
@@ -1121,7 +1129,7 @@ public abstract class RecentsView extends PagedView impl
* is called. Also scrolls the view to this task.
*/
public void showCurrentTask(int runningTaskId) {
- if (getTaskView(runningTaskId) == null) {
+ if (shouldAddDummyTaskView(runningTaskId)) {
boolean wasEmpty = getChildCount() == 0;
// Add an empty view for now until the task plan is loaded and applied
final TaskView taskView = mTaskViewPool.getView();
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index ec32e62c2a..7fc64ea073 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -260,7 +260,6 @@ public class Launcher extends StatefulActivity implements Launche
@Thunk
Workspace mWorkspace;
- private View mLauncherView;
@Thunk
DragLayer mDragLayer;
private DragController mDragController;
@@ -363,6 +362,7 @@ public class Launcher extends StatefulActivity implements Launche
LauncherAppState app = LauncherAppState.getInstance(this);
mOldConfig = new Configuration(getResources().getConfiguration());
mModel = app.getModel();
+
mRotationHelper = new RotationHelper(this);
InvariantDeviceProfile idp = app.getInvariantDeviceProfile();
initDeviceProfile(idp);
@@ -382,8 +382,7 @@ public class Launcher extends StatefulActivity implements Launche
appWidgetId -> getWorkspace().removeWidget(appWidgetId));
mAppWidgetHost.startListening();
- mLauncherView = LayoutInflater.from(this).inflate(R.layout.launcher, null);
-
+ inflateRootView(R.layout.launcher);
setupViews();
mPopupDataProvider = new PopupDataProvider(this::updateNotificationDots);
@@ -420,7 +419,7 @@ public class Launcher extends StatefulActivity implements Launche
// For handling default keys
setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
- setContentView(mLauncherView);
+ setContentView(getRootView());
getRootView().dispatchInsets();
// Listen for broadcasts
@@ -519,12 +518,6 @@ public class Launcher extends StatefulActivity implements Launche
super.onConfigurationChanged(newConfig);
}
- @Override
- public void reapplyUi(boolean cancelCurrentAnimation) {
- getRootView().dispatchInsets();
- super.reapplyUi(cancelCurrentAnimation);
- }
-
@Override
public void onIdpChanged(int changeFlags, InvariantDeviceProfile idp) {
onIdpChanged(idp);
@@ -581,11 +574,6 @@ public class Launcher extends StatefulActivity implements Launche
return mStateManager;
}
- @Override
- public T findViewById(int id) {
- return mLauncherView.findViewById(id);
- }
-
private LauncherCallbacks mLauncherCallbacks;
/**
@@ -1118,10 +1106,6 @@ public class Launcher extends StatefulActivity implements Launche
mHotseat = findViewById(R.id.hotseat);
mHotseat.setWorkspace(mWorkspace);
- mLauncherView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
- | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
-
// Setup the drag layer
mDragLayer.setup(mDragController, mWorkspace);
@@ -1334,11 +1318,6 @@ public class Launcher extends StatefulActivity implements Launche
return mAllAppsController;
}
- @Override
- public LauncherRootView getRootView() {
- return (LauncherRootView) mLauncherView;
- }
-
@Override
public DragLayer getDragLayer() {
return mDragLayer;
diff --git a/src/com/android/launcher3/LauncherRootView.java b/src/com/android/launcher3/LauncherRootView.java
index 6951ff2804..51504ce6a4 100644
--- a/src/com/android/launcher3/LauncherRootView.java
+++ b/src/com/android/launcher3/LauncherRootView.java
@@ -10,6 +10,8 @@ import android.util.AttributeSet;
import android.view.ViewDebug;
import android.view.WindowInsets;
+import com.android.launcher3.statemanager.StatefulActivity;
+
import java.util.Collections;
import java.util.List;
@@ -17,7 +19,7 @@ public class LauncherRootView extends InsettableFrameLayout {
private final Rect mTempRect = new Rect();
- private final Launcher mLauncher;
+ private final StatefulActivity mActivity;
@ViewDebug.ExportedProperty(category = "launcher")
private static final List SYSTEM_GESTURE_EXCLUSION_RECT =
@@ -31,17 +33,17 @@ public class LauncherRootView extends InsettableFrameLayout {
public LauncherRootView(Context context, AttributeSet attrs) {
super(context, attrs);
- mLauncher = Launcher.getLauncher(context);
+ mActivity = StatefulActivity.fromContext(context);
}
private void handleSystemWindowInsets(Rect insets) {
// Update device profile before notifying th children.
- mLauncher.getDeviceProfile().updateInsets(insets);
+ mActivity.getDeviceProfile().updateInsets(insets);
boolean resetState = !insets.equals(mInsets);
setInsets(insets);
if (resetState) {
- mLauncher.getStateManager().reapplyState(true /* cancelCurrentAnimation */);
+ mActivity.getStateManager().reapplyState(true /* cancelCurrentAnimation */);
}
}
@@ -63,7 +65,7 @@ public class LauncherRootView extends InsettableFrameLayout {
}
public void dispatchInsets() {
- mLauncher.getDeviceProfile().updateInsets(mInsets);
+ mActivity.getDeviceProfile().updateInsets(mInsets);
super.setInsets(mInsets);
}
diff --git a/src/com/android/launcher3/statemanager/StatefulActivity.java b/src/com/android/launcher3/statemanager/StatefulActivity.java
index 0a1607cf04..dbe5f42e31 100644
--- a/src/com/android/launcher3/statemanager/StatefulActivity.java
+++ b/src/com/android/launcher3/statemanager/StatefulActivity.java
@@ -18,10 +18,13 @@ package com.android.launcher3.statemanager;
import static com.android.launcher3.LauncherState.FLAG_NON_INTERACTIVE;
import android.os.Handler;
+import android.view.LayoutInflater;
+import android.view.View;
import androidx.annotation.CallSuper;
import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.LauncherRootView;
import com.android.launcher3.Utilities;
import com.android.launcher3.statemanager.StateManager.AtomicAnimationFactory;
import com.android.launcher3.statemanager.StateManager.StateHandler;
@@ -38,6 +41,8 @@ public abstract class StatefulActivity>
private final Runnable mHandleDeferredResume = this::handleDeferredResume;
private boolean mDeferredResumePending;
+ private LauncherRootView mRootView;
+
/**
* Create handlers to control the property changes for this activity
*/
@@ -55,6 +60,23 @@ public abstract class StatefulActivity>
*/
public abstract StateManager getStateManager();
+ protected void inflateRootView(int layoutId) {
+ mRootView = (LauncherRootView) LayoutInflater.from(this).inflate(layoutId, null);
+ mRootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
+ }
+
+ @Override
+ public final LauncherRootView getRootView() {
+ return mRootView;
+ }
+
+ @Override
+ public T findViewById(int id) {
+ return mRootView.findViewById(id);
+ }
+
/**
* Called when transition to the state starts
*/
@@ -87,6 +109,7 @@ public abstract class StatefulActivity>
* the transition if requested.
*/
public void reapplyUi(boolean cancelCurrentAnimation) {
+ getRootView().dispatchInsets();
getStateManager().reapplyState(cancelCurrentAnimation);
}