Merge "Remove ConcurrentModificationException for snapshot logging Bug: 159282737" into ub-launcher3-rvc-dev
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 7b3e378..cd64a94 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.
-->
-<com.android.quickstep.fallback.RecentsRootView
+<com.android.launcher3.LauncherRootView
xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/drag_layer"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:clipChildren="false"
android:fitsSystemWindows="true">
- <com.android.quickstep.fallback.FallbackRecentsView
- android:id="@id/overview_panel"
+ <com.android.quickstep.fallback.RecentsDragLayer
+ android:id="@+id/drag_layer"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:clipChildren="false"
- android:clipToPadding="false"
- android:outlineProvider="none"
- android:theme="@style/HomeScreenElementTheme" />
+ android:clipChildren="false">
- <include
- android:id="@+id/overview_actions_view"
- layout="@layout/overview_actions_container" />
+ <com.android.quickstep.fallback.FallbackRecentsView
+ android:id="@id/overview_panel"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:outlineProvider="none"
+ android:theme="@style/HomeScreenElementTheme" />
-</com.android.quickstep.fallback.RecentsRootView>
+ <include
+ android:id="@+id/overview_actions_view"
+ layout="@layout/overview_actions_container" />
+
+ </com.android.quickstep.fallback.RecentsDragLayer>
+</com.android.launcher3.LauncherRootView>
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
index 7334d80..e103f66 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
@@ -30,8 +30,10 @@
import android.app.prediction.AppTarget;
import android.app.prediction.AppTargetEvent;
import android.content.ComponentName;
+import android.content.pm.ShortcutInfo;
import android.os.Process;
import android.util.Log;
+import android.util.SparseArray;
import android.view.HapticFeedbackConstants;
import android.view.View;
import android.view.ViewGroup;
@@ -65,6 +67,7 @@
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.popup.SystemShortcut;
import com.android.launcher3.shortcuts.ShortcutKey;
+import com.android.launcher3.shortcuts.ShortcutRequest;
import com.android.launcher3.touch.ItemLongClickListener;
import com.android.launcher3.uioverrides.PredictedAppIcon;
import com.android.launcher3.uioverrides.QuickstepLauncher;
@@ -379,16 +382,24 @@
mRestoreHelper.restoreBackup();
}
StringBuilder predictionLog = new StringBuilder("predictedApps: [\n");
- ArrayList<ComponentKey> componentKeys = new ArrayList<>();
+ ArrayList<ComponentKey> componentKeysToBeCached = new ArrayList<>();
+ SparseArray<ShortcutRequest> requests = new SparseArray<>();
for (AppTarget appTarget : appTargets) {
ComponentKey key;
- if (appTarget.getShortcutInfo() != null) {
- key = ShortcutKey.fromInfo(appTarget.getShortcutInfo());
+ ShortcutRequest request = requests.get(appTarget.getUser().getIdentifier());
+ if (request == null) {
+ request = new ShortcutRequest(mLauncher, appTarget.getUser());
+ requests.put(appTarget.getUser().getIdentifier(), request);
+ }
+ List<ShortcutInfo> shortcutInfos = request.forPackage(appTarget.getPackageName(),
+ appTarget.getClassName()).query(ShortcutRequest.ALL);
+ if (!shortcutInfos.isEmpty()) {
+ key = ShortcutKey.fromInfo(shortcutInfos.get(0));
} else {
key = new ComponentKey(new ComponentName(appTarget.getPackageName(),
appTarget.getClassName()), appTarget.getUser());
+ componentKeysToBeCached.add(key);
}
- componentKeys.add(key);
predictionLog.append(key.toString());
predictionLog.append(",rank:");
predictionLog.append(appTarget.getRank());
@@ -401,7 +412,7 @@
}
updateDependencies();
fillGapsWithPrediction();
- cachePredictionComponentKeysIfNecessary(componentKeys);
+ cachePredictionComponentKeysIfNecessary(componentKeysToBeCached);
}
private void cachePredictionComponentKeysIfNecessary(ArrayList<ComponentKey> componentKeys) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/PredictedAppIcon.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
index 597c17b..51d53fd 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
@@ -36,6 +36,7 @@
import com.android.launcher3.CellLayout;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherSettings;
import com.android.launcher3.R;
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
import com.android.launcher3.graphics.IconPalette;
@@ -90,8 +91,9 @@
public void onDraw(Canvas canvas) {
int count = canvas.save();
if (!mIsPinned) {
- boolean isBadged = getTag() instanceof WorkspaceItemInfo
- && !Process.myUserHandle().equals(((ItemInfo) getTag()).user);
+ ItemInfo info = (ItemInfo) getTag();
+ boolean isBadged = info != null && (!Process.myUserHandle().equals(info.user)
+ || info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT);
drawEffect(canvas, isBadged);
canvas.translate(getWidth() * RING_EFFECT_RATIO, getHeight() * RING_EFFECT_RATIO);
canvas.scale(1 - 2 * RING_EFFECT_RATIO, 1 - 2 * RING_EFFECT_RATIO);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
index 9db6576..02bae64 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
@@ -121,10 +121,6 @@
});
mRecentsView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
- // Wait until the first scroll event before applying scroll to taskViewSimulator.
- // Since, by default the current/running task already centered, this ensures that we
- // do not move the running task, in case RecentsView has not yet laid out completely.
- mRecentsViewScrollLinked = true;
if (moveWindowWithRecentsScroll()) {
updateFinalShift();
}
@@ -132,6 +128,7 @@
runOnRecentsAnimationStart(() ->
mRecentsView.setRecentsAnimationTargets(mRecentsAnimationController,
mRecentsAnimationTargets));
+ mRecentsViewScrollLinked = true;
}
protected void startNewTask(Consumer<Boolean> resultCallback) {
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 1701020..6f2f9fb 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.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 @@
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 @@
/**
* 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 @@
super.onMultiWindowModeChanged(isInMultiWindowMode, newConfig);
}
- public void onRootViewSizeChanged() {
- if (isInMultiWindowMode()) {
- onHandleConfigChanged();
- }
- }
-
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
@@ -130,7 +126,7 @@
dispatchDeviceProfileChanged();
reapplyUi();
- mRecentsRootView.recreateControllers();
+ mDragLayer.recreateControllers();
}
/**
@@ -142,19 +138,14 @@
// 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 @@
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 9242771..d20bbe9 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
@@ -107,11 +107,22 @@
}
@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<Task> 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 0000000..a00015a
--- /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<RecentsActivity> {
+
+ 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 7f5ec9b..0000000
--- 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<RecentsActivity> {
-
- 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 6380bbe..cb22570 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.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 @@
* A list of recent tasks.
*/
@TargetApi(Build.VERSION_CODES.P)
-public abstract class RecentsView<T extends BaseActivity> extends PagedView implements Insettable,
- TaskThumbnailCache.HighResLoadingState.HighResLoadingStateChangedCallback,
+public abstract class RecentsView<T extends StatefulActivity> extends PagedView implements
+ Insettable, TaskThumbnailCache.HighResLoadingState.HighResLoadingStateChangedCallback,
InvariantDeviceProfile.OnIDPChangeListener, TaskVisualsChangeListener,
SplitScreenBounds.OnChangeListener {
@@ -389,12 +390,12 @@
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);
@@ -1115,13 +1116,20 @@
}
/**
+ * 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}.
*
* All subsequent calls to reload will keep the task as the first item until {@link #reset()}
* 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();
@@ -1656,6 +1664,8 @@
!mOrientationState.canLauncherRotate() && isInLandscape);
resetPaddingFromTaskSize();
requestLayout();
+ // Reapply the current page to update page scrolls.
+ setCurrentPage(mCurrentPage);
}
}
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
index b3b899e..d605317 100644
--- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -34,6 +34,9 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.logger.LauncherAtom.ContainerInfo;
+import com.android.launcher3.logger.LauncherAtom.FolderIcon;
+import com.android.launcher3.logger.LauncherAtom.FromState;
+import com.android.launcher3.logger.LauncherAtom.ToState;
import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.logging.InstanceIdSequence;
import com.android.launcher3.logging.StatsLogManager;
@@ -178,6 +181,9 @@
private Optional<ContainerInfo> mContainerInfo = Optional.empty();
private int mSrcState = LAUNCHER_UICHANGED__SRC_STATE__HOME;
private int mDstState = LAUNCHER_UICHANGED__DST_STATE__BACKGROUND;
+ private Optional<FromState> mFromState = Optional.empty();
+ private Optional<ToState> mToState = Optional.empty();
+ private Optional<String> mEditText = Optional.empty();
@Override
public StatsLogger withItemInfo(ItemInfo itemInfo) {
@@ -224,25 +230,33 @@
}
@Override
+ public StatsLogger withFromState(FromState fromState) {
+ this.mFromState = Optional.of(fromState);
+ return this;
+ }
+
+ @Override
+ public StatsLogger withToState(ToState toState) {
+ this.mToState = Optional.of(toState);
+ return this;
+ }
+
+ @Override
+ public StatsLogger withEditText(String editText) {
+ this.mEditText = Optional.of(editText);
+ return this;
+ }
+
+ @Override
public void log(EventEnum event) {
if (!Utilities.ATLEAST_R) {
return;
}
- LauncherAtom.ItemInfo.Builder itemInfoBuilder =
- (LauncherAtom.ItemInfo.Builder) mItemInfo.buildProto().toBuilder();
- mRank.ifPresent(itemInfoBuilder::setRank);
- if (mContainerInfo.isPresent()) {
- // User already provided container info;
- // default container info from item info will be ignored.
- itemInfoBuilder.setContainerInfo(mContainerInfo.get());
- write(event, mInstanceId, itemInfoBuilder.build(), mSrcState, mDstState);
- return;
- }
-
if (mItemInfo.container < 0) {
// Item is not within a folder. Write to StatsLog in same thread.
- write(event, mInstanceId, itemInfoBuilder.build(), mSrcState, mDstState);
+ write(event, mInstanceId, applyOverwrites(mItemInfo.buildProto()), mSrcState,
+ mDstState);
} else {
// Item is inside the folder, fetch folder info in a BG thread
// and then write to StatsLog.
@@ -252,17 +266,33 @@
public void execute(LauncherAppState app, BgDataModel dataModel,
AllAppsList apps) {
FolderInfo folderInfo = dataModel.folders.get(mItemInfo.container);
- LauncherAtom.ItemInfo.Builder atomInfoBuilder =
- (LauncherAtom.ItemInfo.Builder) mItemInfo
- .buildProto(folderInfo).toBuilder();
- mRank.ifPresent(atomInfoBuilder::setRank);
- write(event, mInstanceId, atomInfoBuilder.build(), mSrcState,
- mDstState);
+ write(event, mInstanceId,
+ applyOverwrites(mItemInfo.buildProto(folderInfo)),
+ mSrcState, mDstState);
}
});
}
}
+ private LauncherAtom.ItemInfo applyOverwrites(LauncherAtom.ItemInfo atomInfo) {
+ LauncherAtom.ItemInfo.Builder itemInfoBuilder =
+ (LauncherAtom.ItemInfo.Builder) atomInfo.toBuilder();
+
+ mRank.ifPresent(itemInfoBuilder::setRank);
+ mContainerInfo.ifPresent(itemInfoBuilder::setContainerInfo);
+
+ if (mFromState.isPresent() || mToState.isPresent() || mEditText.isPresent()) {
+ FolderIcon.Builder folderIconBuilder = (FolderIcon.Builder) itemInfoBuilder
+ .getFolderIcon()
+ .toBuilder();
+ mFromState.ifPresent(folderIconBuilder::setFromLabelState);
+ mToState.ifPresent(folderIconBuilder::setToLabelState);
+ mEditText.ifPresent(folderIconBuilder::setLabelInfo);
+ itemInfoBuilder.setFolderIcon(folderIconBuilder);
+ }
+ return itemInfoBuilder.build();
+ }
+
private void write(EventEnum event, InstanceId instanceId, LauncherAtom.ItemInfo atomInfo,
int srcState, int dstState) {
if (IS_VERBOSE) {
diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
index bd8ab08..b9e0f62 100644
--- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
@@ -131,6 +131,10 @@
TestCommandReceiver.GET_SYSTEM_HEALTH_MESSAGE, startTime.toString()).
getString("result"));
}
+ // b/143488140
+ mDevice.pressHome();
+ mDevice.waitForIdle();
+ startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
}
// b/143488140
diff --git a/res/layout/work_mode_switch.xml b/res/layout/work_mode_switch.xml
index b5237db..31953c7 100644
--- a/res/layout/work_mode_switch.xml
+++ b/res/layout/work_mode_switch.xml
@@ -17,7 +17,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- style="@style/PrimaryMediumText"
+ style="@style/PrimaryHeadline"
android:id="@+id/work_mode_toggle"
android:drawableStart="@drawable/ic_corp"
android:drawablePadding="16dp"
@@ -25,6 +25,7 @@
android:textColor="?attr/workProfileOverlayTextColor"
android:layout_alignParentBottom="true"
android:ellipsize="end"
+ android:elevation="10dp"
android:gravity="start"
android:lines="1"
android:showText="false"
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 82f5dc6..25f21f3 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -246,7 +246,6 @@
<style name="DropTargetButton" parent="DropTargetButtonBase" />
<style name="TextHeadline" parent="@android:style/TextAppearance.DeviceDefault.DialogWindowTitle" />
- <style name="PrimaryMediumText" parent="@android:style/TextAppearance.DeviceDefault.Medium"/>
<style name="PrimaryHeadline" parent="@android:style/TextAppearance.DeviceDefault.DialogWindowTitle"/>
<style name="TextTitle" parent="@android:style/TextAppearance.DeviceDefault" />
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index ec32e62..7fc64ea 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -260,7 +260,6 @@
@Thunk
Workspace mWorkspace;
- private View mLauncherView;
@Thunk
DragLayer mDragLayer;
private DragController mDragController;
@@ -363,6 +362,7 @@
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 @@
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 @@
// For handling default keys
setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
- setContentView(mLauncherView);
+ setContentView(getRootView());
getRootView().dispatchInsets();
// Listen for broadcasts
@@ -520,12 +519,6 @@
}
@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 @@
return mStateManager;
}
- @Override
- public <T extends View> T findViewById(int id) {
- return mLauncherView.findViewById(id);
- }
-
private LauncherCallbacks mLauncherCallbacks;
/**
@@ -1118,10 +1106,6 @@
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);
@@ -1335,11 +1319,6 @@
}
@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 6951ff2..51504ce 100644
--- a/src/com/android/launcher3/LauncherRootView.java
+++ b/src/com/android/launcher3/LauncherRootView.java
@@ -10,6 +10,8 @@
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 @@
private final Rect mTempRect = new Rect();
- private final Launcher mLauncher;
+ private final StatefulActivity mActivity;
@ViewDebug.ExportedProperty(category = "launcher")
private static final List<Rect> SYSTEM_GESTURE_EXCLUSION_RECT =
@@ -31,17 +33,17 @@
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 void dispatchInsets() {
- mLauncher.getDeviceProfile().updateInsets(mInsets);
+ mActivity.getDeviceProfile().updateInsets(mInsets);
super.setInsets(mInsets);
}
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index fb58f21..a8dca12 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -415,7 +415,7 @@
// Always enter the spring loaded mode
mLauncher.getStateManager().goToState(SPRING_LOADED);
- mStatsLogManager.logger().withItemInfo(dragObject.originalDragInfo)
+ mStatsLogManager.logger().withItemInfo(dragObject.dragInfo)
.withInstanceId(dragObject.logInstanceId)
.log(LauncherEvent.LAUNCHER_ITEM_DRAG_STARTED);
}
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 301f79c..e950f3c 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -81,7 +81,10 @@
import com.android.launcher3.dragndrop.DragController.DragListener;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.dragndrop.DragOptions;
+import com.android.launcher3.logger.LauncherAtom.FromState;
+import com.android.launcher3.logger.LauncherAtom.ToState;
import com.android.launcher3.logging.StatsLogManager;
+import com.android.launcher3.logging.StatsLogManager.StatsLogger;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.FolderInfo.FolderListener;
@@ -99,6 +102,7 @@
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
+import java.util.StringJoiner;
import java.util.stream.Collectors;
/**
@@ -109,6 +113,12 @@
View.OnFocusChangeListener, DragListener, ExtendedEditText.OnBackKeyListener {
private static final String TAG = "Launcher.Folder";
private static final boolean DEBUG = false;
+
+ /**
+ * Used for separating folder title when logging together.
+ */
+ private static final CharSequence FOLDER_LABEL_DELIMITER = "~";
+
/**
* We avoid measuring {@link #mContent} with a 0 width or height, as this
* results in CellLayout being measured as UNSPECIFIED, which it does not support.
@@ -155,6 +165,8 @@
protected final Launcher mLauncher;
protected DragController mDragController;
public FolderInfo mInfo;
+ private CharSequence mFromTitle;
+ private FromState mFromLabelState;
@Thunk FolderIcon mFolderIcon;
@@ -335,7 +347,6 @@
Log.d(TAG, "onBackKey newTitle=" + newTitle);
}
mInfo.setTitle(newTitle);
- mInfo.fromCustom = mInfo.hasOption(FLAG_MANUAL_FOLDER_NAME);
mInfo.setOption(FLAG_MANUAL_FOLDER_NAME, !mInfo.getAcceptedSuggestionIndex().isPresent(),
mLauncher.getModelWriter());
mFolderIcon.onTitleChanged(newTitle);
@@ -415,6 +426,8 @@
void bind(FolderInfo info) {
mInfo = info;
+ mFromTitle = info.title;
+ mFromLabelState = info.getFromLabelState();
ArrayList<WorkspaceItemInfo> children = info.contents;
Collections.sort(children, ITEM_POS_COMPARATOR);
updateItemLocationsInDatabaseBatch(true);
@@ -1442,10 +1455,38 @@
public void onFocusChange(View v, boolean hasFocus) {
if (v == mFolderName) {
if (hasFocus) {
+ mFromLabelState = mInfo.getFromLabelState();
+ mFromTitle = mInfo.title;
startEditingFolderName();
} else {
- mStatsLogManager.logger().withItemInfo(mInfo).log(LAUNCHER_FOLDER_LABEL_UPDATED);
- logFolderLabelState();
+ StatsLogger statsLogger = mStatsLogManager.logger()
+ .withItemInfo(mInfo)
+ .withFromState(mFromLabelState);
+
+ // If the folder label is suggested, it is logged to improve prediction model.
+ // When both old and new labels are logged together delimiter is used.
+ StringJoiner labelInfoBuilder = new StringJoiner(FOLDER_LABEL_DELIMITER);
+ if (mFromLabelState.equals(FromState.FROM_SUGGESTED)) {
+ labelInfoBuilder.add(mFromTitle);
+ }
+
+ ToState toLabelState;
+ if (mFromTitle != null && mFromTitle.equals(mInfo.title)) {
+ toLabelState = ToState.UNCHANGED;
+ } else {
+ toLabelState = mInfo.getToLabelState();
+ if (toLabelState.toString().startsWith("TO_SUGGESTION")) {
+ labelInfoBuilder.add(mInfo.title);
+ }
+ }
+ statsLogger.withToState(toLabelState);
+
+ if (labelInfoBuilder.length() > 0) {
+ statsLogger.withEditText(labelInfoBuilder.toString());
+ }
+
+ statsLogger.log(LAUNCHER_FOLDER_LABEL_UPDATED);
+ logFolderLabelState(mFromLabelState, toLabelState);
mFolderName.dispatchBackKey();
}
}
@@ -1650,8 +1691,8 @@
* @deprecated This method is only used for log validation and soon will be removed.
*/
@Deprecated
- public void logFolderLabelState() {
+ public void logFolderLabelState(FromState fromState, ToState toState) {
mLauncher.getUserEventDispatcher()
- .logLauncherEvent(mInfo.getFolderLabelStateLauncherEvent());
+ .logLauncherEvent(mInfo.getFolderLabelStateLauncherEvent(fromState, toState));
}
}
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index 7af4664..e24033f 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -20,7 +20,9 @@
import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.MAX_NUM_ITEMS_IN_PREVIEW;
import static com.android.launcher3.folder.PreviewItemManager.INITIAL_ITEM_ANIMATION_DURATION;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_LABEL_UPDATED;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_AUTO_LABELED;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_AUTO_LABELING_SKIPPED_EMPTY_PRIMARY;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_AUTO_LABELING_SKIPPED_EMPTY_SUGGESTIONS;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -63,6 +65,8 @@
import com.android.launcher3.dragndrop.DragView;
import com.android.launcher3.dragndrop.DraggableView;
import com.android.launcher3.icons.DotRenderer;
+import com.android.launcher3.logger.LauncherAtom.FromState;
+import com.android.launcher3.logger.LauncherAtom.ToState;
import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.model.data.AppInfo;
@@ -80,6 +84,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
+import java.util.stream.Stream;
/**
* An icon that can appear on in the workspace representing an {@link Folder}.
@@ -428,7 +433,6 @@
mPreviewItemManager.hidePreviewItem(finalIndex, false);
mFolder.showItem(item);
setLabelSuggestion(nameInfos, instanceId);
- mFolder.logFolderLabelState();
invalidate();
}, DROP_IN_ANIMATION_DURATION);
}
@@ -444,15 +448,40 @@
|| mInfo.hasOption(FolderInfo.FLAG_MANUAL_FOLDER_NAME)) {
return;
}
- if (nameInfos == null || nameInfos[0] == null || isEmpty(nameInfos[0].getLabel())) {
+ if (nameInfos == null || Stream.of(nameInfos)
+ .allMatch(nameInfo -> nameInfo == null || isEmpty(nameInfo.getLabel()))) {
+ StatsLogManager.newInstance(getContext()).logger()
+ .withInstanceId(instanceId)
+ .withItemInfo(mInfo)
+ .log(LAUNCHER_FOLDER_AUTO_LABELING_SKIPPED_EMPTY_SUGGESTIONS);
return;
}
- mInfo.setTitle(nameInfos[0].getLabel());
- StatsLogManager.newInstance(getContext()).logger().withItemInfo(mInfo)
- .withInstanceId(instanceId).log(LAUNCHER_FOLDER_LABEL_UPDATED);
+ if (nameInfos[0] == null || isEmpty(nameInfos[0].getLabel())) {
+ StatsLogManager.newInstance(getContext()).logger()
+ .withInstanceId(instanceId)
+ .withItemInfo(mInfo)
+ .log(LAUNCHER_FOLDER_AUTO_LABELING_SKIPPED_EMPTY_PRIMARY);
+ return;
+ }
+ CharSequence newTitle = nameInfos[0].getLabel();
+ FromState fromState = mInfo.getFromLabelState();
+
+ mInfo.setTitle(newTitle);
onTitleChanged(mInfo.title);
mFolder.mFolderName.setText(mInfo.title);
mFolder.mLauncher.getModelWriter().updateItemInDatabase(mInfo);
+
+ // Logging for folder creation flow
+ StatsLogManager.newInstance(getContext()).logger()
+ .withInstanceId(instanceId)
+ .withItemInfo(mInfo)
+ .withFromState(fromState)
+ .withToState(ToState.TO_SUGGESTION0)
+ // When LAUNCHER_FOLDER_LABEL_UPDATED event.edit_text does not have delimiter,
+ // event is assumed to be folder creation on the server side.
+ .withEditText(newTitle.toString())
+ .log(LAUNCHER_FOLDER_AUTO_LABELED);
+ mFolder.logFolderLabelState(fromState, ToState.TO_SUGGESTION0);
}
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index 82d61da..3edfa8d 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -21,6 +21,8 @@
import com.android.launcher3.R;
import com.android.launcher3.logger.LauncherAtom.ContainerInfo;
+import com.android.launcher3.logger.LauncherAtom.FromState;
+import com.android.launcher3.logger.LauncherAtom.ToState;
import com.android.launcher3.logging.StatsLogUtils.LogStateProvider;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.util.ResourceBasedOverride;
@@ -66,8 +68,16 @@
+ "resulting in a new folder creation")
LAUNCHER_ITEM_DROP_FOLDER_CREATED(386),
- @UiEvent(doc = "User action resulted in or manually updated the folder label to "
- + "new/same value.")
+ @UiEvent(doc = "Folder's label is automatically assigned.")
+ LAUNCHER_FOLDER_AUTO_LABELED(591),
+
+ @UiEvent(doc = "Could not auto-label a folder because primary suggestion is null or empty.")
+ LAUNCHER_FOLDER_AUTO_LABELING_SKIPPED_EMPTY_PRIMARY(592),
+
+ @UiEvent(doc = "Could not auto-label a folder because no suggestions exist.")
+ LAUNCHER_FOLDER_AUTO_LABELING_SKIPPED_EMPTY_SUGGESTIONS(593),
+
+ @UiEvent(doc = "User manually updated the folder label.")
LAUNCHER_FOLDER_LABEL_UPDATED(460),
@UiEvent(doc = "User long pressed on the workspace empty space.")
@@ -246,6 +256,27 @@
}
/**
+ * Sets FromState field of log message.
+ */
+ default StatsLogger withFromState(FromState fromState) {
+ return this;
+ }
+
+ /**
+ * Sets ToState field of log message.
+ */
+ default StatsLogger withToState(ToState toState) {
+ return this;
+ }
+
+ /**
+ * Sets editText field of log message.
+ */
+ default StatsLogger withEditText(String editText) {
+ return this;
+ }
+
+ /**
* Sets the final value for container related fields of log message.
*
* By default container related fields are derived from {@link ItemInfo}, this method would
diff --git a/src/com/android/launcher3/model/data/FolderInfo.java b/src/com/android/launcher3/model/data/FolderInfo.java
index 8f577b5..08eb383 100644
--- a/src/com/android/launcher3/model/data/FolderInfo.java
+++ b/src/com/android/launcher3/model/data/FolderInfo.java
@@ -54,7 +54,6 @@
import java.util.Objects;
import java.util.Optional;
import java.util.OptionalInt;
-import java.util.StringJoiner;
import java.util.stream.IntStream;
@@ -88,20 +87,6 @@
public Intent suggestedFolderNames;
- // Represents the title before current.
- // Primarily used for logging purpose.
- private CharSequence mPreviousTitle;
-
- // True if the title before was manually entered, suggested otherwise.
- // Primarily used for logging purpose.
- public boolean fromCustom;
-
- /**
- * Used for separating {@link #mPreviousTitle} and {@link #title} when concatenating them
- * for logging.
- */
- private static final CharSequence FOLDER_LABEL_DELIMITER = "=>";
-
/**
* The apps and shortcuts
*/
@@ -207,21 +192,16 @@
return getDefaultItemInfoBuilder()
.setFolderIcon(LauncherAtom.FolderIcon.newBuilder().setCardinality(contents.size()))
.setRank(rank)
- .setAttribute(fromCustom ? MANUAL_LABEL : SUGGESTED_LABEL)
+ .setAttribute(hasOption(FLAG_MANUAL_FOLDER_NAME) ? MANUAL_LABEL : SUGGESTED_LABEL)
.setContainerInfo(getContainerInfo())
.build();
}
@Override
public void setTitle(CharSequence title) {
- mPreviousTitle = this.title;
this.title = title;
}
- public CharSequence getPreviousTitle() {
- return mPreviousTitle;
- }
-
@Override
public ItemInfo makeShallowCopy() {
FolderInfo folderInfo = new FolderInfo();
@@ -235,30 +215,7 @@
*/
@Override
public LauncherAtom.ItemInfo buildProto() {
- FromState fromFolderLabelState = getFromFolderLabelState();
- ToState toFolderLabelState = getToFolderLabelState();
- LauncherAtom.FolderIcon.Builder folderIconBuilder = LauncherAtom.FolderIcon.newBuilder()
- .setCardinality(contents.size())
- .setFromLabelState(fromFolderLabelState)
- .setToLabelState(toFolderLabelState);
-
- // If the folder label is suggested, it is logged to improve prediction model.
- // When both old and new labels are logged together delimiter is used.
- StringJoiner labelInfoBuilder = new StringJoiner(FOLDER_LABEL_DELIMITER);
- if (fromFolderLabelState.equals(FromState.FROM_SUGGESTED)) {
- labelInfoBuilder.add(mPreviousTitle);
- }
- if (toFolderLabelState.toString().startsWith("TO_SUGGESTION")) {
- labelInfoBuilder.add(title);
- }
- if (labelInfoBuilder.length() > 0) {
- folderIconBuilder.setLabelInfo(labelInfoBuilder.toString());
- }
-
- return getDefaultItemInfoBuilder()
- .setFolderIcon(folderIconBuilder)
- .setContainerInfo(getContainerInfo())
- .build();
+ return buildProto(null);
}
/**
@@ -280,15 +237,27 @@
}
- private LauncherAtom.ToState getToFolderLabelState() {
+ /**
+ * Returns {@link FromState} based on current {@link #title}.
+ */
+ public LauncherAtom.FromState getFromLabelState() {
+ return title == null
+ ? LauncherAtom.FromState.FROM_STATE_UNSPECIFIED
+ : title.length() == 0
+ ? LauncherAtom.FromState.FROM_EMPTY
+ : hasOption(FLAG_MANUAL_FOLDER_NAME)
+ ? LauncherAtom.FromState.FROM_CUSTOM
+ : LauncherAtom.FromState.FROM_SUGGESTED;
+ }
+
+ /**
+ * Returns {@link ToState} based on current {@link #title}.
+ */
+ public LauncherAtom.ToState getToLabelState() {
if (title == null) {
return LauncherAtom.ToState.TO_STATE_UNSPECIFIED;
}
- if (title.equals(mPreviousTitle)) {
- return LauncherAtom.ToState.UNCHANGED;
- }
-
if (!FeatureFlags.FOLDER_NAME_SUGGEST.get()) {
return title.length() > 0
? LauncherAtom.ToState.TO_CUSTOM_WITH_SUGGESTIONS_DISABLED
@@ -335,17 +304,6 @@
// fall through
}
return LauncherAtom.ToState.TO_STATE_UNSPECIFIED;
-
- }
-
- private LauncherAtom.FromState getFromFolderLabelState() {
- return mPreviousTitle == null
- ? LauncherAtom.FromState.FROM_STATE_UNSPECIFIED
- : mPreviousTitle.length() == 0
- ? LauncherAtom.FromState.FROM_EMPTY
- : fromCustom
- ? LauncherAtom.FromState.FROM_CUSTOM
- : LauncherAtom.FromState.FROM_SUGGESTED;
}
private Optional<String[]> getSuggestedLabels() {
@@ -368,7 +326,8 @@
* @deprecated This method is used only for validation purpose and soon will be removed.
*/
@Deprecated
- public LauncherLogProto.LauncherEvent getFolderLabelStateLauncherEvent() {
+ public LauncherLogProto.LauncherEvent getFolderLabelStateLauncherEvent(FromState fromState,
+ ToState toState) {
return LauncherLogProto.LauncherEvent.newBuilder()
.setAction(LauncherLogProto.Action
.newBuilder()
@@ -377,8 +336,8 @@
.newBuilder()
.setType(Target.Type.ITEM)
.setItemType(LauncherLogProto.ItemType.EDITTEXT)
- .setFromFolderLabelState(convertFolderLabelState(getFromFolderLabelState()))
- .setToFolderLabelState(convertFolderLabelState(getToFolderLabelState())))
+ .setFromFolderLabelState(convertFolderLabelState(fromState))
+ .setToFolderLabelState(convertFolderLabelState(toState)))
.addSrcTarget(Target.newBuilder()
.setType(Target.Type.CONTAINER)
.setContainerType(LauncherLogProto.ContainerType.FOLDER)
diff --git a/src/com/android/launcher3/statemanager/StatefulActivity.java b/src/com/android/launcher3/statemanager/StatefulActivity.java
index 0a1607c..dbe5f42 100644
--- a/src/com/android/launcher3/statemanager/StatefulActivity.java
+++ b/src/com/android/launcher3/statemanager/StatefulActivity.java
@@ -18,10 +18,13 @@
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 @@
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 StateManager<STATE_TYPE> 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 extends View> T findViewById(int id) {
+ return mRootView.findViewById(id);
+ }
+
/**
* Called when transition to the state starts
*/
@@ -87,6 +109,7 @@
* the transition if requested.
*/
public void reapplyUi(boolean cancelCurrentAnimation) {
+ getRootView().dispatchInsets();
getStateManager().reapplyState(cancelCurrentAnimation);
}