Merge "Fix a couple issues with overview to home transition" into ub-launcher3-master
diff --git a/Android.mk b/Android.mk
index 752b530..25f5412 100644
--- a/Android.mk
+++ b/Android.mk
@@ -28,6 +28,7 @@
androidx.recyclerview_recyclerview \
androidx.dynamicanimation_dynamicanimation \
androidx.preference_preference \
+ androidx.slice_slice-view \
iconloader_base
LOCAL_STATIC_JAVA_LIBRARIES := \
diff --git a/go/AndroidManifest.xml b/go/AndroidManifest.xml
index f84a82e..f36439d 100644
--- a/go/AndroidManifest.xml
+++ b/go/AndroidManifest.xml
@@ -46,6 +46,12 @@
tools:node="replace" >
</activity>
+ <service
+ android:name="com.android.launcher3.notification.NotificationListener"
+ android:label="@string/notification_dots_service_title"
+ android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
+ android:enabled="false"
+ tools:node="replace" />
</application>
</manifest>
diff --git a/go/src/com/android/launcher3/model/WidgetsModel.java b/go/src/com/android/launcher3/model/WidgetsModel.java
index 3b3dc01..89b3831 100644
--- a/go/src/com/android/launcher3/model/WidgetsModel.java
+++ b/go/src/com/android/launcher3/model/WidgetsModel.java
@@ -41,6 +41,7 @@
// True is the widget support is disabled.
public static final boolean GO_DISABLE_WIDGETS = true;
+ public static final boolean GO_DISABLE_NOTIFICATION_DOTS = true;
private static final ArrayList<WidgetListRowEntry> EMPTY_WIDGET_LIST = new ArrayList<>();
diff --git a/quickstep/res/values/override.xml b/quickstep/res/values/override.xml
index 397ea82..8f4ce43 100644
--- a/quickstep/res/values/override.xml
+++ b/quickstep/res/values/override.xml
@@ -27,8 +27,6 @@
<string name="user_event_dispatcher_class" translatable="false">com.android.quickstep.logging.UserEventDispatcherExtension</string>
- <string name="prediction_model_class" translatable="false">com.android.launcher3.hybridhotseat.HotseatPredictionModel</string>
-
<string name="model_delegate_class" translatable="false">com.android.launcher3.model.QuickstepModelDelegate</string>
</resources>
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index a0016cb..68111d2 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -26,12 +26,10 @@
import android.animation.ValueAnimator;
import android.content.Intent;
import android.content.IntentSender;
-import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.CancellationSignal;
import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.hybridhotseat.HotseatPredictionController;
import com.android.launcher3.model.WellbeingModel;
import com.android.launcher3.popup.SystemShortcut;
import com.android.launcher3.proxy.ProxyActivityStarter;
@@ -40,14 +38,12 @@
import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.statemanager.StateManager.StateHandler;
import com.android.launcher3.uioverrides.RecentsViewStateController;
-import com.android.launcher3.util.OnboardingPrefs;
import com.android.launcher3.util.UiThreadHelper;
import com.android.quickstep.RecentsModel;
import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener;
import com.android.quickstep.SystemUiProxy;
-import com.android.quickstep.util.QuickstepOnboardingPrefs;
import com.android.quickstep.util.RemoteAnimationProvider;
import com.android.quickstep.util.RemoteFadeOutAnimationListener;
import com.android.quickstep.views.OverviewActionsView;
@@ -73,7 +69,6 @@
Float.intBitsToFloat(arg1), arg2 != 0);
private OverviewActionsView mActionsView;
- protected HotseatPredictionController mHotseatPredictionController;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -222,11 +217,6 @@
}
@Override
- protected OnboardingPrefs createOnboardingPrefs(SharedPreferences sharedPrefs) {
- return new QuickstepOnboardingPrefs(this, sharedPrefs);
- }
-
- @Override
public void useFadeOutAnimationForLauncherStart(CancellationSignal signal) {
QuickstepAppTransitionManagerImpl appTransitionManager =
(QuickstepAppTransitionManagerImpl) getAppTransitionManager();
@@ -314,13 +304,6 @@
Stream.of(WellbeingModel.SHORTCUT_FACTORY));
}
- /**
- * Returns Prediction controller for hybrid hotseat
- */
- public HotseatPredictionController getHotseatPredictionController() {
- return mHotseatPredictionController;
- }
-
public void setHintUserWillBeActive() {
addActivityFlags(ACTIVITY_STATE_USER_WILL_BE_ACTIVE);
}
diff --git a/quickstep/src/com/android/launcher3/appprediction/AllAppsTipView.java b/quickstep/src/com/android/launcher3/appprediction/AllAppsTipView.java
index 8477b10..98bf483 100644
--- a/quickstep/src/com/android/launcher3/appprediction/AllAppsTipView.java
+++ b/quickstep/src/com/android/launcher3/appprediction/AllAppsTipView.java
@@ -19,7 +19,6 @@
import static com.android.launcher3.AbstractFloatingView.TYPE_DISCOVERY_BOUNCE;
import static com.android.launcher3.AbstractFloatingView.TYPE_ON_BOARD_POPUP;
import static com.android.launcher3.LauncherState.ALL_APPS;
-import static com.android.quickstep.logging.UserEventDispatcherExtension.ALL_APPS_PREDICTION_TIPS;
import android.os.UserManager;
@@ -31,7 +30,6 @@
import com.android.launcher3.allapps.FloatingHeaderView;
import com.android.launcher3.statemanager.StateManager.StateListener;
import com.android.launcher3.views.ArrowTipView;
-import com.android.systemui.shared.system.LauncherEventUtil;
/**
* ArrowTip helper aligned just above prediction apps, shown to users that enter all apps for the
@@ -57,8 +55,7 @@
floatingHeaderView.findFixedRowByType(PredictionRowView.class).getLocationOnScreen(coords);
ArrowTipView arrowTipView = new ArrowTipView(launcher).setOnClosedCallback(() -> {
launcher.getSharedPrefs().edit().putBoolean(ALL_APPS_TIP_SEEN, true).apply();
- launcher.getUserEventDispatcher().logActionTip(LauncherEventUtil.DISMISS,
- ALL_APPS_PREDICTION_TIPS);
+ // TODO: add log to WW
});
arrowTipView.show(launcher.getString(R.string.all_apps_prediction_tip), coords[1]);
diff --git a/quickstep/src/com/android/launcher3/appprediction/ComponentKeyMapper.java b/quickstep/src/com/android/launcher3/appprediction/ComponentKeyMapper.java
deleted file mode 100644
index d200868..0000000
--- a/quickstep/src/com/android/launcher3/appprediction/ComponentKeyMapper.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * 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.launcher3.appprediction;
-
-import static com.android.quickstep.InstantAppResolverImpl.COMPONENT_CLASS_MARKER;
-
-import com.android.launcher3.allapps.AllAppsStore;
-import com.android.launcher3.model.data.AppInfo;
-import com.android.launcher3.model.data.ItemInfoWithIcon;
-import com.android.launcher3.util.ComponentKey;
-
-public class ComponentKeyMapper {
-
- protected final ComponentKey componentKey;
- private final DynamicItemCache mCache;
-
- public ComponentKeyMapper(ComponentKey key, DynamicItemCache cache) {
- componentKey = key;
- mCache = cache;
- }
-
- public String getPackage() {
- return componentKey.componentName.getPackageName();
- }
-
- public String getComponentClass() {
- return componentKey.componentName.getClassName();
- }
-
- public ComponentKey getComponentKey() {
- return componentKey;
- }
-
- @Override
- public String toString() {
- return componentKey.toString();
- }
-
- public ItemInfoWithIcon getApp(AllAppsStore store) {
- AppInfo item = store.getApp(componentKey);
- if (item != null) {
- return item;
- } else if (getComponentClass().equals(COMPONENT_CLASS_MARKER)) {
- return mCache.getInstantApp(componentKey.componentName.getPackageName());
- } else {
- return mCache.getShortcutInfo(componentKey);
- }
- }
-}
diff --git a/quickstep/src/com/android/launcher3/appprediction/DynamicItemCache.java b/quickstep/src/com/android/launcher3/appprediction/DynamicItemCache.java
deleted file mode 100644
index ab96b1340..0000000
--- a/quickstep/src/com/android/launcher3/appprediction/DynamicItemCache.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/**
- * 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.launcher3.appprediction;
-
-import static android.content.pm.PackageManager.MATCH_INSTANT;
-
-import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
-import static com.android.quickstep.InstantAppResolverImpl.COMPONENT_CLASS_MARKER;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ShortcutInfo;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import androidx.annotation.MainThread;
-import androidx.annotation.Nullable;
-import androidx.annotation.UiThread;
-import androidx.annotation.WorkerThread;
-
-import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.allapps.AllAppsStore;
-import com.android.launcher3.icons.IconCache;
-import com.android.launcher3.model.data.AppInfo;
-import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.shortcuts.ShortcutKey;
-import com.android.launcher3.shortcuts.ShortcutRequest;
-import com.android.launcher3.util.ComponentKey;
-import com.android.launcher3.util.InstantAppResolver;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Utility class which loads and caches predicted items like instant apps and shortcuts, before
- * they can be displayed on the UI
- */
-public class DynamicItemCache {
-
- private static final String TAG = "DynamicItemCache";
- private static final boolean DEBUG = false;
- private static final String DEFAULT_URL = "default-url";
-
- private static final int BG_MSG_LOAD_SHORTCUTS = 1;
- private static final int BG_MSG_LOAD_INSTANT_APPS = 2;
-
- private static final int UI_MSG_UPDATE_SHORTCUTS = 1;
- private static final int UI_MSG_UPDATE_INSTANT_APPS = 2;
-
- private final Context mContext;
- private final Handler mWorker;
- private final Handler mUiHandler;
- private final InstantAppResolver mInstantAppResolver;
- private final Runnable mOnUpdateCallback;
- private final IconCache mIconCache;
-
- private final Map<ComponentKey, WorkspaceItemInfo> mShortcuts;
- private final Map<String, InstantAppItemInfo> mInstantApps;
-
- public DynamicItemCache(Context context, Runnable onUpdateCallback) {
- mContext = context;
- mWorker = new Handler(MODEL_EXECUTOR.getLooper(), this::handleWorkerMessage);
- mUiHandler = new Handler(Looper.getMainLooper(), this::handleUiMessage);
- mInstantAppResolver = InstantAppResolver.newInstance(context);
- mOnUpdateCallback = onUpdateCallback;
- mIconCache = LauncherAppState.getInstance(mContext).getIconCache();
-
- mShortcuts = new HashMap<>();
- mInstantApps = new HashMap<>();
- }
-
- public void cacheItems(List<ShortcutKey> shortcutKeys, List<String> pkgNames) {
- if (!shortcutKeys.isEmpty()) {
- mWorker.removeMessages(BG_MSG_LOAD_SHORTCUTS);
- Message.obtain(mWorker, BG_MSG_LOAD_SHORTCUTS, shortcutKeys).sendToTarget();
- }
- if (!pkgNames.isEmpty()) {
- mWorker.removeMessages(BG_MSG_LOAD_INSTANT_APPS);
- Message.obtain(mWorker, BG_MSG_LOAD_INSTANT_APPS, pkgNames).sendToTarget();
- }
- }
-
- private boolean handleWorkerMessage(Message msg) {
- switch (msg.what) {
- case BG_MSG_LOAD_SHORTCUTS: {
- List<ShortcutKey> shortcutKeys = msg.obj != null ?
- (List<ShortcutKey>) msg.obj : Collections.EMPTY_LIST;
- Map<ShortcutKey, WorkspaceItemInfo> shortcutKeyAndInfos = new ArrayMap<>();
- for (ShortcutKey shortcutKey : shortcutKeys) {
- WorkspaceItemInfo workspaceItemInfo = loadShortcutWorker(shortcutKey);
- if (workspaceItemInfo != null) {
- shortcutKeyAndInfos.put(shortcutKey, workspaceItemInfo);
- }
- }
- Message.obtain(mUiHandler, UI_MSG_UPDATE_SHORTCUTS, shortcutKeyAndInfos)
- .sendToTarget();
- return true;
- }
- case BG_MSG_LOAD_INSTANT_APPS: {
- List<String> pkgNames = msg.obj != null ?
- (List<String>) msg.obj : Collections.EMPTY_LIST;
- List<InstantAppItemInfo> instantAppItemInfos = new ArrayList<>();
- for (String pkgName : pkgNames) {
- InstantAppItemInfo instantAppItemInfo = loadInstantApp(pkgName);
- if (instantAppItemInfo != null) {
- instantAppItemInfos.add(instantAppItemInfo);
- }
- }
- Message.obtain(mUiHandler, UI_MSG_UPDATE_INSTANT_APPS, instantAppItemInfos)
- .sendToTarget();
- return true;
- }
- }
-
- return false;
- }
-
- private boolean handleUiMessage(Message msg) {
- switch (msg.what) {
- case UI_MSG_UPDATE_SHORTCUTS: {
- mShortcuts.clear();
- mShortcuts.putAll((Map<ShortcutKey, WorkspaceItemInfo>) msg.obj);
- mOnUpdateCallback.run();
- return true;
- }
- case UI_MSG_UPDATE_INSTANT_APPS: {
- List<InstantAppItemInfo> instantAppItemInfos = (List<InstantAppItemInfo>) msg.obj;
- mInstantApps.clear();
- for (InstantAppItemInfo instantAppItemInfo : instantAppItemInfos) {
- mInstantApps.put(instantAppItemInfo.getTargetComponent().getPackageName(),
- instantAppItemInfo);
- }
- mOnUpdateCallback.run();
- if (DEBUG) {
- Log.d(TAG, String.format("Cache size: %d, Cache: %s",
- mInstantApps.size(), mInstantApps.toString()));
- }
- return true;
- }
- }
-
- return false;
- }
-
- @WorkerThread
- private WorkspaceItemInfo loadShortcutWorker(ShortcutKey shortcutKey) {
- List<ShortcutInfo> details = shortcutKey.buildRequest(mContext).query(ShortcutRequest.ALL);
- if (!details.isEmpty()) {
- WorkspaceItemInfo si = new WorkspaceItemInfo(details.get(0), mContext);
- mIconCache.getShortcutIcon(si, details.get(0));
- return si;
- }
- if (DEBUG) {
- Log.d(TAG, "No shortcut found: " + shortcutKey.toString());
- }
- return null;
- }
-
- private InstantAppItemInfo loadInstantApp(String pkgName) {
- PackageManager pm = mContext.getPackageManager();
-
- try {
- ApplicationInfo ai = pm.getApplicationInfo(pkgName, 0);
- if (!mInstantAppResolver.isInstantApp(ai)) {
- return null;
- }
- } catch (PackageManager.NameNotFoundException e) {
- return null;
- }
-
- String url = retrieveDefaultUrl(pkgName, pm);
- if (url == null) {
- Log.w(TAG, "no default-url available for pkg " + pkgName);
- return null;
- }
-
- Intent intent = new Intent(Intent.ACTION_VIEW)
- .addCategory(Intent.CATEGORY_BROWSABLE)
- .setData(Uri.parse(url));
- InstantAppItemInfo info = new InstantAppItemInfo(intent, pkgName);
- IconCache iconCache = LauncherAppState.getInstance(mContext).getIconCache();
- iconCache.getTitleAndIcon(info, false);
- if (info.bitmap.icon == null || iconCache.isDefaultIcon(info.bitmap, info.user)) {
- return null;
- }
- return info;
- }
-
- @Nullable
- public static String retrieveDefaultUrl(String pkgName, PackageManager pm) {
- Intent mainIntent = new Intent().setAction(Intent.ACTION_MAIN)
- .addCategory(Intent.CATEGORY_LAUNCHER).setPackage(pkgName);
- List<ResolveInfo> resolveInfos = pm.queryIntentActivities(
- mainIntent, MATCH_INSTANT | PackageManager.GET_META_DATA);
- String url = null;
- for (ResolveInfo resolveInfo : resolveInfos) {
- if (resolveInfo.activityInfo.metaData != null
- && resolveInfo.activityInfo.metaData.containsKey(DEFAULT_URL)) {
- url = resolveInfo.activityInfo.metaData.getString(DEFAULT_URL);
- }
- }
- return url;
- }
-
- @UiThread
- public InstantAppItemInfo getInstantApp(String pkgName) {
- return mInstantApps.get(pkgName);
- }
-
- @MainThread
- public WorkspaceItemInfo getShortcutInfo(ComponentKey key) {
- return mShortcuts.get(key);
- }
-
- /**
- * requests and caches icons for app targets
- */
- public void updateDependencies(List<ComponentKeyMapper> componentKeyMappers,
- AllAppsStore appsStore, IconCache.ItemInfoUpdateReceiver callback, int itemCount) {
- List<String> instantAppsToLoad = new ArrayList<>();
- List<ShortcutKey> shortcutsToLoad = new ArrayList<>();
- int total = componentKeyMappers.size();
- for (int i = 0, count = 0; i < total && count < itemCount; i++) {
- ComponentKeyMapper mapper = componentKeyMappers.get(i);
- // Update instant apps
- if (COMPONENT_CLASS_MARKER.equals(mapper.getComponentClass())) {
- instantAppsToLoad.add(mapper.getPackage());
- count++;
- } else if (mapper.getComponentKey() instanceof ShortcutKey) {
- shortcutsToLoad.add((ShortcutKey) mapper.getComponentKey());
- count++;
- } else {
- // Reload high res icon
- AppInfo info = (AppInfo) mapper.getApp(appsStore);
- if (info != null) {
- if (info.usingLowResIcon()) {
- mIconCache.updateIconInBackground(callback, info);
- }
- count++;
- }
- }
- }
- cacheItems(shortcutsToLoad, instantAppsToLoad);
- }
-}
diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduController.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
index 8ebf125..4451e7a 100644
--- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
+++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
@@ -47,35 +47,27 @@
*/
public class HotseatEduController {
- public static final String HOTSEAT_EDU_ACTION =
- "com.android.launcher3.action.SHOW_HYBRID_HOTSEAT_EDU";
public static final String SETTINGS_ACTION =
"android.settings.ACTION_CONTENT_SUGGESTIONS_SETTINGS";
private final Launcher mLauncher;
private final Hotseat mHotseat;
- private HotseatRestoreHelper mRestoreHelper;
private List<WorkspaceItemInfo> mPredictedApps;
private HotseatEduDialog mActiveDialog;
private ArrayList<ItemInfo> mNewItems = new ArrayList<>();
private IntArray mNewScreens = null;
- private Runnable mOnOnboardingComplete;
- HotseatEduController(Launcher launcher, HotseatRestoreHelper restoreHelper, Runnable runnable) {
+ HotseatEduController(Launcher launcher) {
mLauncher = launcher;
mHotseat = launcher.getHotseat();
- mRestoreHelper = restoreHelper;
- mOnOnboardingComplete = runnable;
}
/**
* Checks what type of migration should be used and migrates hotseat
*/
void migrate() {
- if (mRestoreHelper != null) {
- mRestoreHelper.createBackup();
- }
+ HotseatRestoreHelper.createBackup(mLauncher);
if (FeatureFlags.HOTSEAT_MIGRATE_TO_FOLDER.get()) {
migrateToFolder();
} else {
@@ -227,7 +219,7 @@
}
void finishOnboarding() {
- mOnOnboardingComplete.run();
+ mLauncher.getModel().onWorkspaceUiChanged();
}
void showDimissTip() {
diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java
index 2b3f395..39bf008 100644
--- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java
+++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java
@@ -40,7 +40,6 @@
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.uioverrides.PredictedAppIcon;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.views.AbstractSlideInView;
import java.util.List;
@@ -123,16 +122,6 @@
}
@Override
- public void logActionCommand(int command) {
- // Since this is on-boarding popup, it is not a user controlled action.
- }
-
- @Override
- public int getLogContainerType() {
- return LauncherLogProto.ContainerType.TIP;
- }
-
- @Override
protected boolean isOfType(int type) {
return (type & TYPE_ON_BOARD_POPUP) != 0;
}
diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
index b94e633..151a113 100644
--- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
+++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
@@ -15,23 +15,17 @@
*/
package com.android.launcher3.hybridhotseat;
-import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_GRID;
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.hybridhotseat.HotseatEduController.getSettingsIntent;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOTSEAT_PREDICTION_PINNED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOTSEAT_RANKED;
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
-import android.app.prediction.AppPredictionContext;
-import android.app.prediction.AppPredictionManager;
-import android.app.prediction.AppPredictor;
-import android.app.prediction.AppTarget;
-import android.app.prediction.AppTargetEvent;
import android.content.ComponentName;
import android.os.Process;
-import android.util.Log;
import android.view.HapticFeedbackConstants;
import android.view.View;
import android.view.ViewGroup;
@@ -44,77 +38,51 @@
import com.android.launcher3.Hotseat;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.allapps.AllAppsStore;
import com.android.launcher3.anim.AnimationSuccessListener;
-import com.android.launcher3.appprediction.ComponentKeyMapper;
-import com.android.launcher3.appprediction.DynamicItemCache;
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragOptions;
-import com.android.launcher3.icons.IconCache;
+import com.android.launcher3.graphics.DragPreviewProvider;
import com.android.launcher3.logger.LauncherAtom.ContainerInfo;
import com.android.launcher3.logger.LauncherAtom.PredictedHotseatContainer;
import com.android.launcher3.logging.InstanceId;
-import com.android.launcher3.model.data.AppInfo;
-import com.android.launcher3.model.data.FolderInfo;
+import com.android.launcher3.model.BgDataModel.FixedContainerItems;
import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.popup.SystemShortcut;
-import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.touch.ItemLongClickListener;
import com.android.launcher3.uioverrides.PredictedAppIcon;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.userevent.nano.LauncherLogProto;
-import com.android.launcher3.util.ComponentKey;
-import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.OnboardingPrefs;
import com.android.launcher3.views.ArrowTipView;
import com.android.launcher3.views.Snackbar;
-import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.OptionalInt;
-import java.util.stream.IntStream;
+import java.util.stream.Collectors;
/**
* Provides prediction ability for the hotseat. Fills gaps in hotseat with predicted items, allows
* pinning of predicted apps and manages replacement of predicted apps with user drag.
*/
public class HotseatPredictionController implements DragController.DragListener,
- View.OnAttachStateChangeListener, SystemShortcut.Factory<QuickstepLauncher>,
- InvariantDeviceProfile.OnIDPChangeListener, AllAppsStore.OnUpdateListener,
- IconCache.ItemInfoUpdateReceiver, DragSource {
+ SystemShortcut.Factory<QuickstepLauncher>, InvariantDeviceProfile.OnIDPChangeListener,
+ DragSource {
- private static final String TAG = "PredictiveHotseat";
- private static final boolean DEBUG = false;
-
- private static final String PREDICTION_CLIENT = "hotseat";
- private DropTarget.DragObject mDragObject;
private int mHotSeatItemsCount;
- private int mPredictedSpotsCount = 0;
private Launcher mLauncher;
private final Hotseat mHotseat;
- private final HotseatRestoreHelper mRestoreHelper;
+ private List<ItemInfo> mPredictedItems = Collections.emptyList();
- private List<ComponentKeyMapper> mComponentKeyMappers = new ArrayList<>();
-
- private DynamicItemCache mDynamicItemCache;
-
- private final HotseatPredictionModel mPredictionModel;
- private AppPredictor mAppPredictor;
- private AllAppsStore mAllAppsStore;
private AnimatorSet mIconRemoveAnimators;
private boolean mUIUpdatePaused = false;
- private boolean mIsDestroyed = false;
-
+ private boolean mDragInProgress = false;
private List<PredictedAppIcon.PredictedIconOutlineDrawing> mOutlineDrawings = new ArrayList<>();
@@ -130,26 +98,23 @@
mLauncher.getDragLayer().performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
return true;
}
+
// Start the drag
- mLauncher.getWorkspace().beginDragShared(v, this, new DragOptions());
+ // Use a new itemInfo so that the original predicted item is stable
+ WorkspaceItemInfo dragItem = new WorkspaceItemInfo((WorkspaceItemInfo) v.getTag());
+ v.setVisibility(View.INVISIBLE);
+ mLauncher.getWorkspace().beginDragShared(
+ v, null, this, dragItem, new DragPreviewProvider(v), new DragOptions());
return true;
};
public HotseatPredictionController(Launcher launcher) {
mLauncher = launcher;
mHotseat = launcher.getHotseat();
- mAllAppsStore = mLauncher.getAppsView().getAppsStore();
- LauncherAppState appState = LauncherAppState.getInstance(launcher);
- mPredictionModel = (HotseatPredictionModel) appState.getPredictionModel();
- mAllAppsStore.addUpdateListener(this);
- mDynamicItemCache = new DynamicItemCache(mLauncher, this::fillGapsWithPrediction);
mHotSeatItemsCount = mLauncher.getDeviceProfile().inv.numHotseatIcons;
+ mLauncher.getDragController().addDragListener(this);
+
launcher.getDeviceProfile().inv.addOnChangeListener(this);
- mHotseat.addOnAttachStateChangeListener(this);
- mRestoreHelper = new HotseatRestoreHelper(mLauncher);
- if (mHotseat.isAttachedToWindow()) {
- onViewAttachedToWindow(mHotseat);
- }
}
/**
@@ -157,7 +122,7 @@
*/
public void showEdu() {
mLauncher.getStateManager().goToState(NORMAL, true, () -> {
- if (mComponentKeyMappers.isEmpty()) {
+ if (mPredictedItems.isEmpty()) {
// launcher has empty predictions set
Snackbar.show(mLauncher, R.string.hotsaet_tip_prediction_disabled,
R.string.hotseat_prediction_settings, null,
@@ -165,10 +130,10 @@
} else if (getPredictedIcons().size() >= (mHotSeatItemsCount + 1) / 2) {
showDiscoveryTip();
} else {
- HotseatEduController eduController = new HotseatEduController(mLauncher,
- mRestoreHelper,
- this::createPredictor);
- eduController.setPredictedApps(mapToWorkspaceItemInfo(mComponentKeyMappers));
+ HotseatEduController eduController = new HotseatEduController(mLauncher);
+ eduController.setPredictedApps(mPredictedItems.stream()
+ .map(i -> (WorkspaceItemInfo) i)
+ .collect(Collectors.toList()));
eduController.showEdu();
}
});
@@ -192,17 +157,7 @@
* Returns if hotseat client has predictions
*/
public boolean hasPredictions() {
- return !mComponentKeyMappers.isEmpty();
- }
-
- @Override
- public void onViewAttachedToWindow(View view) {
- mLauncher.getDragController().addDragListener(this);
- }
-
- @Override
- public void onViewDetachedFromWindow(View view) {
- mLauncher.getDragController().removeDragListener(this);
+ return !mPredictedItems.isEmpty();
}
private void fillGapsWithPrediction() {
@@ -210,15 +165,10 @@
}
private void fillGapsWithPrediction(boolean animate, Runnable callback) {
- if (mUIUpdatePaused || mDragObject != null) {
+ if (mUIUpdatePaused || mDragInProgress) {
return;
}
- List<WorkspaceItemInfo> predictedApps = mapToWorkspaceItemInfo(mComponentKeyMappers);
- if (mComponentKeyMappers.isEmpty() != predictedApps.isEmpty()) {
- // Safely ignore update as AppsList is not ready yet. This will called again once
- // apps are ready (HotseatPredictionController#onAppsUpdated)
- return;
- }
+
int predictionIndex = 0;
ArrayList<WorkspaceItemInfo> newItems = new ArrayList<>();
// make sure predicted icon removal and filling predictions don't step on each other
@@ -240,14 +190,15 @@
if (child != null && !isPredictedIcon(child)) {
continue;
}
- if (predictedApps.size() <= predictionIndex) {
+ if (mPredictedItems.size() <= predictionIndex) {
// Remove predicted apps from the past
if (isPredictedIcon(child)) {
mHotseat.removeView(child);
}
continue;
}
- WorkspaceItemInfo predictedItem = predictedApps.get(predictionIndex++);
+ WorkspaceItemInfo predictedItem =
+ (WorkspaceItemInfo) mPredictedItems.get(predictionIndex++);
if (isPredictedIcon(child) && child.isEnabled()) {
PredictedAppIcon icon = (PredictedAppIcon) child;
icon.applyFromWorkspaceItem(predictedItem);
@@ -257,7 +208,6 @@
}
preparePredictionInfo(predictedItem, rank);
}
- mPredictedSpotsCount = predictionIndex;
bindItems(newItems, animate, callback);
}
@@ -285,13 +235,7 @@
* Unregisters callbacks and frees resources
*/
public void destroy() {
- mIsDestroyed = true;
- mAllAppsStore.removeUpdateListener(this);
mLauncher.getDeviceProfile().inv.removeOnChangeListener(this);
- mHotseat.removeOnAttachStateChangeListener(this);
- if (mAppPredictor != null) {
- mAppPredictor.destroy();
- }
}
/**
@@ -305,97 +249,14 @@
}
/**
- * Creates App Predictor with all the current apps pinned on the hotseat
+ * Sets or updates the predicted items
*/
- public void createPredictor() {
- AppPredictionManager apm = mLauncher.getSystemService(AppPredictionManager.class);
- if (apm == null) {
- return;
+ public void setPredictedItems(FixedContainerItems items) {
+ mPredictedItems = items.items;
+ if (mPredictedItems.isEmpty()) {
+ HotseatRestoreHelper.restoreBackup(mLauncher);
}
- if (mAppPredictor != null) {
- mAppPredictor.destroy();
- mAppPredictor = null;
- }
- WeakReference<HotseatPredictionController> controllerRef = new WeakReference<>(this);
-
-
- mPredictionModel.createBundle(bundle -> {
- if (mIsDestroyed) return;
- mAppPredictor = apm.createAppPredictionSession(
- new AppPredictionContext.Builder(mLauncher)
- .setUiSurface(PREDICTION_CLIENT)
- .setPredictedTargetCount(mHotSeatItemsCount)
- .setExtras(bundle)
- .build());
- mAppPredictor.registerPredictionUpdates(
- mLauncher.getApplicationContext().getMainExecutor(),
- list -> {
- if (controllerRef.get() != null) {
- controllerRef.get().setPredictedApps(list);
- }
- });
- mAppPredictor.requestPredictionUpdate();
- });
- setPauseUIUpdate(false);
- }
-
- /**
- * Create WorkspaceItemInfo objects and binds PredictedAppIcon views for cached predicted items.
- */
- public void showCachedItems(List<AppInfo> apps, IntArray ranks) {
- if (hasPredictions() && mAppPredictor != null) {
- mAppPredictor.requestPredictionUpdate();
- fillGapsWithPrediction();
- return;
- }
- int count = Math.min(ranks.size(), apps.size());
- List<WorkspaceItemInfo> items = new ArrayList<>(count);
- for (int i = 0; i < count; i++) {
- WorkspaceItemInfo item = new WorkspaceItemInfo(apps.get(i));
- ComponentKey componentKey = new ComponentKey(item.getTargetComponent(), item.user);
- preparePredictionInfo(item, ranks.get(i));
- items.add(item);
-
- mComponentKeyMappers.add(new ComponentKeyMapper(componentKey, mDynamicItemCache));
- }
- updateDependencies();
- bindItems(items, false, null);
- }
-
- private void setPredictedApps(List<AppTarget> appTargets) {
- mComponentKeyMappers.clear();
- if (appTargets.isEmpty()) {
- mRestoreHelper.restoreBackup();
- }
- StringBuilder predictionLog = new StringBuilder("predictedApps: [\n");
- ArrayList<ComponentKey> componentKeys = new ArrayList<>();
- for (AppTarget appTarget : appTargets) {
- ComponentKey key;
- if (appTarget.getShortcutInfo() != null) {
- key = ShortcutKey.fromInfo(appTarget.getShortcutInfo());
- } else {
- key = new ComponentKey(new ComponentName(appTarget.getPackageName(),
- appTarget.getClassName()), appTarget.getUser());
- }
- componentKeys.add(key);
- predictionLog.append(key.toString());
- predictionLog.append(",rank:");
- predictionLog.append(appTarget.getRank());
- predictionLog.append("\n");
- mComponentKeyMappers.add(new ComponentKeyMapper(key, mDynamicItemCache));
- }
- predictionLog.append("]");
- if (Utilities.IS_DEBUG_DEVICE) {
- HotseatFileLog.INSTANCE.get(mLauncher).log(TAG, predictionLog.toString());
- }
- updateDependencies();
fillGapsWithPrediction();
- mPredictionModel.cachePredictionComponentKeys(componentKeys);
- }
-
- private void updateDependencies() {
- mDynamicItemCache.updateDependencies(mComponentKeyMappers, mAllAppsStore, this,
- mHotSeatItemsCount);
}
/**
@@ -414,42 +275,9 @@
workspaceItemInfo.cellX, workspaceItemInfo.cellY);
ObjectAnimator.ofFloat(icon, SCALE_PROPERTY, 1, 0.8f, 1).start();
icon.pin(workspaceItemInfo);
- AppTarget appTarget = mPredictionModel.getAppTargetFromInfo(workspaceItemInfo);
- if (appTarget != null) {
- notifyItemAction(mPredictionModel.wrapAppTargetWithLocation(appTarget,
- AppTargetEvent.ACTION_PIN, workspaceItemInfo));
- }
- }
-
- private List<WorkspaceItemInfo> mapToWorkspaceItemInfo(
- List<ComponentKeyMapper> components) {
- AllAppsStore allAppsStore = mLauncher.getAppsView().getAppsStore();
- if (allAppsStore.getApps().length == 0) {
- return Collections.emptyList();
- }
-
- List<WorkspaceItemInfo> predictedApps = new ArrayList<>();
- for (ComponentKeyMapper mapper : components) {
- ItemInfoWithIcon info = mapper.getApp(allAppsStore);
- if (info instanceof AppInfo) {
- WorkspaceItemInfo predictedApp = new WorkspaceItemInfo((AppInfo) info);
- predictedApp.container = LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
- predictedApps.add(predictedApp);
- } else if (info instanceof WorkspaceItemInfo) {
- WorkspaceItemInfo predictedApp = new WorkspaceItemInfo((WorkspaceItemInfo) info);
- predictedApp.container = LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
- predictedApps.add(predictedApp);
- } else {
- if (DEBUG) {
- Log.e(TAG, "Predicted app not found: " + mapper);
- }
- }
- // Stop at the number of hotseat items
- if (predictedApps.size() == mHotSeatItemsCount) {
- break;
- }
- }
- return predictedApps;
+ mLauncher.getStatsLogManager().logger()
+ .withItemInfo(workspaceItemInfo)
+ .log(LAUNCHER_HOTSEAT_PREDICTION_PINNED);
}
private List<PredictedAppIcon> getPredictedIcons() {
@@ -465,7 +293,7 @@
}
private void removePredictedApps(List<PredictedAppIcon.PredictedIconOutlineDrawing> outlines,
- ItemInfo draggedInfo) {
+ DropTarget.DragObject dragObject) {
if (mIconRemoveAnimators != null) {
mIconRemoveAnimators.end();
}
@@ -475,7 +303,7 @@
if (!icon.isEnabled()) {
continue;
}
- if (icon.getTag().equals(draggedInfo)) {
+ if (dragObject.dragSource == this && icon.equals(dragObject.originalView)) {
mHotseat.removeView(icon);
continue;
}
@@ -497,84 +325,23 @@
mIconRemoveAnimators.start();
}
- private void notifyItemAction(AppTargetEvent event) {
- if (mAppPredictor != null) {
- mAppPredictor.notifyAppTargetEvent(event);
- }
- }
-
@Override
public void onDragStart(DropTarget.DragObject dragObject, DragOptions options) {
- removePredictedApps(mOutlineDrawings, dragObject.dragInfo);
- mDragObject = dragObject;
+ removePredictedApps(mOutlineDrawings, dragObject);
if (mOutlineDrawings.isEmpty()) return;
for (PredictedAppIcon.PredictedIconOutlineDrawing outlineDrawing : mOutlineDrawings) {
mHotseat.addDelegatedCellDrawing(outlineDrawing);
}
+ mDragInProgress = true;
mHotseat.invalidate();
}
- /**
- * Unpins pinned app when it's converted into a folder
- */
- public void folderCreatedFromWorkspaceItem(ItemInfo itemInfo, FolderInfo folderInfo) {
- AppTarget folderTarget = mPredictionModel.getAppTargetFromInfo(folderInfo);
- AppTarget itemTarget = mPredictionModel.getAppTargetFromInfo(itemInfo);
- if (folderTarget != null && HotseatPredictionModel.isTrackedForPrediction(folderInfo)) {
- notifyItemAction(mPredictionModel.wrapAppTargetWithLocation(folderTarget,
- AppTargetEvent.ACTION_PIN, folderInfo));
- }
- // using folder info with isTrackedForPrediction as itemInfo.container is already changed
- // to folder by this point
- if (itemTarget != null && HotseatPredictionModel.isTrackedForPrediction(folderInfo)) {
- notifyItemAction(mPredictionModel.wrapAppTargetWithLocation(itemTarget,
- AppTargetEvent.ACTION_UNPIN, folderInfo
- ));
- }
- }
-
- /**
- * Pins workspace item created when all folder items are removed but one
- */
- public void folderConvertedToWorkspaceItem(ItemInfo itemInfo, FolderInfo folderInfo) {
- AppTarget folderTarget = mPredictionModel.getAppTargetFromInfo(folderInfo);
- AppTarget itemTarget = mPredictionModel.getAppTargetFromInfo(itemInfo);
- if (folderTarget != null && HotseatPredictionModel.isTrackedForPrediction(folderInfo)) {
- notifyItemAction(mPredictionModel.wrapAppTargetWithLocation(folderTarget,
- AppTargetEvent.ACTION_UNPIN, folderInfo));
- }
- if (itemTarget != null && HotseatPredictionModel.isTrackedForPrediction(itemInfo)) {
- notifyItemAction(mPredictionModel.wrapAppTargetWithLocation(itemTarget,
- AppTargetEvent.ACTION_PIN, itemInfo));
- }
- }
-
@Override
public void onDragEnd() {
- if (mDragObject == null) {
- return;
- }
-
- ItemInfo dragInfo = mDragObject.dragInfo;
- if (mDragObject.isMoved()) {
- AppTarget appTarget = mPredictionModel.getAppTargetFromInfo(dragInfo);
- //always send pin event first to prevent AiAi from predicting an item moved within
- // the same page
- if (appTarget != null && HotseatPredictionModel.isTrackedForPrediction(dragInfo)) {
- notifyItemAction(mPredictionModel.wrapAppTargetWithLocation(appTarget,
- AppTargetEvent.ACTION_PIN, dragInfo));
- }
- if (appTarget != null && HotseatPredictionModel.isTrackedForPrediction(
- mDragObject.originalDragInfo)) {
- notifyItemAction(mPredictionModel.wrapAppTargetWithLocation(appTarget,
- AppTargetEvent.ACTION_UNPIN, mDragObject.originalDragInfo));
- }
- }
- mDragObject = null;
+ mDragInProgress = false;
fillGapsWithPrediction(true, this::removeOutlineDrawings);
}
-
@Nullable
@Override
public SystemShortcut<QuickstepLauncher> getShortcut(QuickstepLauncher activity,
@@ -604,19 +371,7 @@
@Override
public void onIdpChanged(int changeFlags, InvariantDeviceProfile profile) {
- if ((changeFlags & CHANGE_FLAG_GRID) != 0) {
- this.mHotSeatItemsCount = profile.numHotseatIcons;
- createPredictor();
- }
- }
-
- @Override
- public void onAppsUpdated() {
- fillGapsWithPrediction();
- }
-
- @Override
- public void reapplyItemInfo(ItemInfoWithIcon info) {
+ this.mHotSeatItemsCount = profile.numHotseatIcons;
}
@Override
@@ -624,12 +379,6 @@
//Does nothing
}
- @Override
- public void fillInLogContainerData(ItemInfo childInfo, LauncherLogProto.Target child,
- ArrayList<LauncherLogProto.Target> parents) {
- mHotseat.fillInLogContainerData(childInfo, child, parents);
- }
-
/**
* Logs rank info based on current list of predicted items
*/
@@ -643,17 +392,20 @@
+ ",launchLocation:" + itemInfo.container);
}
- if (itemInfo.getTargetComponent() == null || itemInfo.user == null) {
+
+ ComponentName targetCN = itemInfo.getTargetComponent();
+ if (targetCN == null) {
return;
}
-
- final ComponentKey key = new ComponentKey(itemInfo.getTargetComponent(), itemInfo.user);
-
- final List<ComponentKeyMapper> predictedApps = new ArrayList<>(mComponentKeyMappers);
- OptionalInt rank = IntStream.range(0, predictedApps.size())
- .filter(index -> key.equals(predictedApps.get(index).getComponentKey()))
- .findFirst();
- if (!rank.isPresent()) {
+ int rank = -1;
+ for (int i = mPredictedItems.size() - 1; i >= 0; i--) {
+ ItemInfo info = mPredictedItems.get(i);
+ if (targetCN.equals(info.getTargetComponent()) && itemInfo.user.equals(info.user)) {
+ rank = i;
+ break;
+ }
+ }
+ if (rank < 0) {
return;
}
@@ -666,11 +418,11 @@
PredictedHotseatContainer.Builder containerBuilder = PredictedHotseatContainer.newBuilder();
containerBuilder.setCardinality(cardinality);
if (itemInfo.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION) {
- containerBuilder.setIndex(rank.getAsInt());
+ containerBuilder.setIndex(rank);
}
mLauncher.getStatsLogManager().logger()
.withInstanceId(instanceId)
- .withRank(rank.getAsInt())
+ .withRank(rank)
.withContainerInfo(ContainerInfo.newBuilder()
.setPredictedHotseatContainer(containerBuilder)
.build())
@@ -691,30 +443,6 @@
}
}
- /**
- * Fill in predicted_rank field based on app prediction.
- * Only applicable when {@link ItemInfo#itemType} is PREDICTED_HOTSEAT
- */
- public static void encodeHotseatLayoutIntoPredictionRank(
- @NonNull ItemInfo itemInfo, @NonNull LauncherLogProto.Target target) {
- QuickstepLauncher launcher = QuickstepLauncher.ACTIVITY_TRACKER.getCreatedActivity();
- if (launcher == null || launcher.getHotseatPredictionController() == null
- || itemInfo.getTargetComponent() == null) {
- return;
- }
- HotseatPredictionController controller = launcher.getHotseatPredictionController();
-
- final ComponentKey k = new ComponentKey(itemInfo.getTargetComponent(), itemInfo.user);
-
- final List<ComponentKeyMapper> predictedApps = controller.mComponentKeyMappers;
- OptionalInt rank = IntStream.range(0, predictedApps.size())
- .filter((i) -> k.equals(predictedApps.get(i).getComponentKey()))
- .findFirst();
-
- target.predictedRank = 10000 + (controller.mPredictedSpotsCount * 100)
- + (rank.isPresent() ? rank.getAsInt() + 1 : 0);
- }
-
private static boolean isPredictedIcon(View view) {
return view instanceof PredictedAppIcon && view.getTag() instanceof WorkspaceItemInfo
&& ((WorkspaceItemInfo) view.getTag()).container
diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionModel.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionModel.java
index 5a038d2..8f31c22 100644
--- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionModel.java
+++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionModel.java
@@ -15,7 +15,7 @@
*/
package com.android.launcher3.hybridhotseat;
-import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
import android.app.prediction.AppTarget;
import android.app.prediction.AppTargetEvent;
@@ -24,13 +24,10 @@
import android.content.Context;
import android.os.Bundle;
-import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.Workspace;
-import com.android.launcher3.model.AllAppsList;
-import com.android.launcher3.model.BaseModelUpdateTask;
import com.android.launcher3.model.BgDataModel;
-import com.android.launcher3.model.PredictionModel;
+import com.android.launcher3.model.BgDataModel.FixedContainerItems;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
@@ -38,55 +35,48 @@
import java.util.ArrayList;
import java.util.Locale;
-import java.util.function.Consumer;
/**
* Model helper for app predictions in workspace
*/
-public class HotseatPredictionModel extends PredictionModel {
+public class HotseatPredictionModel {
private static final String APP_LOCATION_HOTSEAT = "hotseat";
private static final String APP_LOCATION_WORKSPACE = "workspace";
private static final String BUNDLE_KEY_PIN_EVENTS = "pin_events";
private static final String BUNDLE_KEY_CURRENT_ITEMS = "current_items";
-
- public HotseatPredictionModel(Context context) { }
-
/**
- * Creates and returns bundle using workspace items and cached items
+ * Creates and returns bundle using workspace items
*/
- public void createBundle(Consumer<Bundle> cb) {
- LauncherAppState appState = LauncherAppState.getInstance(mContext);
- appState.getModel().enqueueModelUpdateTask(new BaseModelUpdateTask() {
- @Override
- public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
- Bundle bundle = new Bundle();
- ArrayList<AppTargetEvent> events = new ArrayList<>();
- ArrayList<ItemInfo> workspaceItems = new ArrayList<>(dataModel.workspaceItems);
- workspaceItems.addAll(dataModel.appWidgets);
- for (ItemInfo item : workspaceItems) {
- AppTarget target = getAppTargetFromInfo(item);
- if (target != null && !isTrackedForPrediction(item)) continue;
- events.add(wrapAppTargetWithLocation(target, AppTargetEvent.ACTION_PIN, item));
- }
- ArrayList<AppTarget> currentTargets = new ArrayList<>();
- for (ItemInfo itemInfo : dataModel.cachedPredictedItems) {
- AppTarget target = getAppTargetFromInfo(itemInfo);
- if (target != null) currentTargets.add(target);
- }
- bundle.putParcelableArrayList(BUNDLE_KEY_PIN_EVENTS, events);
- bundle.putParcelableArrayList(BUNDLE_KEY_CURRENT_ITEMS, currentTargets);
- MAIN_EXECUTOR.execute(() -> cb.accept(bundle));
+ public static Bundle convertDataModelToAppTargetBundle(Context context, BgDataModel dataModel) {
+ Bundle bundle = new Bundle();
+ ArrayList<AppTargetEvent> events = new ArrayList<>();
+ ArrayList<ItemInfo> workspaceItems = new ArrayList<>(dataModel.workspaceItems);
+ workspaceItems.addAll(dataModel.appWidgets);
+ for (ItemInfo item : workspaceItems) {
+ AppTarget target = getAppTargetFromInfo(context, item);
+ if (target != null && !isTrackedForPrediction(item)) continue;
+ events.add(wrapAppTargetWithLocation(target, AppTargetEvent.ACTION_PIN, item));
+ }
+ ArrayList<AppTarget> currentTargets = new ArrayList<>();
+ FixedContainerItems hotseatItems = dataModel.extraItems.get(CONTAINER_HOTSEAT_PREDICTION);
+ if (hotseatItems != null) {
+ for (ItemInfo itemInfo : hotseatItems.items) {
+ AppTarget target = getAppTargetFromInfo(context, itemInfo);
+ if (target != null) currentTargets.add(target);
}
- });
+ }
+ bundle.putParcelableArrayList(BUNDLE_KEY_PIN_EVENTS, events);
+ bundle.putParcelableArrayList(BUNDLE_KEY_CURRENT_ITEMS, currentTargets);
+ return bundle;
}
/**
* Creates and returns for {@link AppTarget} object given an {@link ItemInfo}. Returns null
* if item is not supported prediction
*/
- public AppTarget getAppTargetFromInfo(ItemInfo info) {
+ public static AppTarget getAppTargetFromInfo(Context context, ItemInfo info) {
if (info == null) return null;
if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET
&& info instanceof LauncherAppWidgetInfo
@@ -107,17 +97,17 @@
shortcutKey.componentName.getPackageName(), shortcutKey.user).build();
} else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
return new AppTarget.Builder(new AppTargetId("folder:" + info.id),
- mContext.getPackageName(), info.user).build();
+ context.getPackageName(), info.user).build();
}
return null;
}
-
/**
* Creates and returns {@link AppTargetEvent} from an {@link AppTarget}, action, and item
* location using {@link ItemInfo}
*/
- public AppTargetEvent wrapAppTargetWithLocation(AppTarget target, int action, ItemInfo info) {
+ public static AppTargetEvent wrapAppTargetWithLocation(
+ AppTarget target, int action, ItemInfo info) {
String location = String.format(Locale.ENGLISH, "%s/%d/[%d,%d]/[%d,%d]",
info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT
? APP_LOCATION_HOTSEAT : APP_LOCATION_WORKSPACE,
diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatRestoreHelper.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatRestoreHelper.java
index 9e7c9fb..90f762e 100644
--- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatRestoreHelper.java
+++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatRestoreHelper.java
@@ -19,8 +19,10 @@
import static com.android.launcher3.provider.LauncherDbUtils.tableExists;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
+import android.content.Context;
+
import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.model.GridBackupTable;
import com.android.launcher3.provider.LauncherDbUtils;
@@ -29,29 +31,24 @@
* A helper class to manage migration revert restoration for hybrid hotseat
*/
public class HotseatRestoreHelper {
- private final Launcher mLauncher;
-
- HotseatRestoreHelper(Launcher context) {
- mLauncher = context;
- }
/**
* Creates a snapshot backup of Favorite table for future restoration use.
*/
- public void createBackup() {
+ public static void createBackup(Context context) {
MODEL_EXECUTOR.execute(() -> {
try (LauncherDbUtils.SQLiteTransaction transaction = (LauncherDbUtils.SQLiteTransaction)
LauncherSettings.Settings.call(
- mLauncher.getContentResolver(),
+ context.getContentResolver(),
LauncherSettings.Settings.METHOD_NEW_TRANSACTION)
.getBinder(LauncherSettings.Settings.EXTRA_VALUE)) {
- InvariantDeviceProfile idp = mLauncher.getDeviceProfile().inv;
- GridBackupTable backupTable = new GridBackupTable(mLauncher,
+ InvariantDeviceProfile idp = LauncherAppState.getIDP(context);
+ GridBackupTable backupTable = new GridBackupTable(context,
transaction.getDb(), idp.numHotseatIcons, idp.numColumns,
idp.numRows);
backupTable.createCustomBackupTable(HYBRID_HOTSEAT_BACKUP_TABLE);
transaction.commit();
- LauncherSettings.Settings.call(mLauncher.getContentResolver(),
+ LauncherSettings.Settings.call(context.getContentResolver(),
LauncherSettings.Settings.METHOD_REFRESH_HOTSEAT_RESTORE_TABLE);
}
});
@@ -60,23 +57,23 @@
/**
* Finds and restores a previously saved snapshow of Favorites table
*/
- public void restoreBackup() {
+ public static void restoreBackup(Context context) {
MODEL_EXECUTOR.execute(() -> {
try (LauncherDbUtils.SQLiteTransaction transaction = (LauncherDbUtils.SQLiteTransaction)
LauncherSettings.Settings.call(
- mLauncher.getContentResolver(),
+ context.getContentResolver(),
LauncherSettings.Settings.METHOD_NEW_TRANSACTION)
.getBinder(LauncherSettings.Settings.EXTRA_VALUE)) {
if (!tableExists(transaction.getDb(), HYBRID_HOTSEAT_BACKUP_TABLE)) {
return;
}
- InvariantDeviceProfile idp = mLauncher.getDeviceProfile().inv;
- GridBackupTable backupTable = new GridBackupTable(mLauncher,
+ InvariantDeviceProfile idp = LauncherAppState.getIDP(context);
+ GridBackupTable backupTable = new GridBackupTable(context,
transaction.getDb(), idp.numHotseatIcons, idp.numColumns,
idp.numRows);
backupTable.restoreFromCustomBackupTable(HYBRID_HOTSEAT_BACKUP_TABLE, true);
transaction.commit();
- mLauncher.getModel().forceReload();
+ LauncherAppState.getInstance(context).getModel().forceReload();
}
});
}
diff --git a/quickstep/src/com/android/launcher3/model/AppEventProducer.java b/quickstep/src/com/android/launcher3/model/AppEventProducer.java
index 8e4c43f..364a321 100644
--- a/quickstep/src/com/android/launcher3/model/AppEventProducer.java
+++ b/quickstep/src/com/android/launcher3/model/AppEventProducer.java
@@ -15,8 +15,21 @@
*/
package com.android.launcher3.model;
+import static android.app.prediction.AppTargetEvent.ACTION_DISMISS;
+import static android.app.prediction.AppTargetEvent.ACTION_LAUNCH;
+import static android.app.prediction.AppTargetEvent.ACTION_PIN;
+import static android.app.prediction.AppTargetEvent.ACTION_UNPIN;
+
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_PREDICTION;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_CONVERTED_TO_ICON;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOTSEAT_PREDICTION_PINNED;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DRAG_STARTED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROPPED_ON_DONT_SUGGEST;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROPPED_ON_REMOVE;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROP_FOLDER_CREATED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_QUICKSWITCH_LEFT;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_QUICKSWITCH_RIGHT;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_SWIPE_DOWN;
@@ -47,11 +60,12 @@
import com.android.launcher3.logger.LauncherAtom.HotseatContainer;
import com.android.launcher3.logger.LauncherAtom.WorkspaceContainer;
import com.android.launcher3.logging.StatsLogManager.EventEnum;
+import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.pm.UserCache;
import com.android.quickstep.logging.StatsLogCompatManager.StatsLogConsumer;
import java.util.Locale;
-import java.util.function.Consumer;
+import java.util.function.ObjIntConsumer;
import java.util.function.Predicate;
/**
@@ -64,9 +78,11 @@
private final Context mContext;
private final Handler mMessageHandler;
- private final Consumer<AppTargetEvent> mCallback;
+ private final ObjIntConsumer<AppTargetEvent> mCallback;
- public AppEventProducer(Context context, Consumer<AppTargetEvent> callback) {
+ private LauncherAtom.ItemInfo mLastDragItem;
+
+ public AppEventProducer(Context context, ObjIntConsumer<AppTargetEvent> callback) {
mContext = context;
mMessageHandler = new Handler(MODEL_EXECUTOR.getLooper(), this::handleMessage);
mCallback = callback;
@@ -76,7 +92,7 @@
private boolean handleMessage(Message msg) {
switch (msg.what) {
case MSG_LAUNCH: {
- mCallback.accept((AppTargetEvent) msg.obj);
+ mCallback.accept((AppTargetEvent) msg.obj, msg.arg1);
return true;
}
}
@@ -84,13 +100,18 @@
}
@AnyThread
- private void sendEvent(LauncherAtom.ItemInfo atomInfo, int eventId) {
- AppTarget target = toAppTarget(atomInfo);
+ private void sendEvent(LauncherAtom.ItemInfo atomInfo, int eventId, int targetPredictor) {
+ sendEvent(toAppTarget(atomInfo), atomInfo, eventId, targetPredictor);
+ }
+
+ @AnyThread
+ private void sendEvent(AppTarget target, LauncherAtom.ItemInfo locationInfo, int eventId,
+ int targetPredictor) {
if (target != null) {
AppTargetEvent event = new AppTargetEvent.Builder(target, eventId)
- .setLaunchLocation(getContainer(atomInfo))
+ .setLaunchLocation(getContainer(locationInfo))
.build();
- Message.obtain(mMessageHandler, MSG_LAUNCH, event).sendToTarget();
+ mMessageHandler.obtainMessage(MSG_LAUNCH, targetPredictor, 0, event).sendToTarget();
}
}
@@ -101,9 +122,42 @@
|| event == LAUNCHER_TASK_LAUNCH_TAP
|| event == LAUNCHER_QUICKSWITCH_RIGHT
|| event == LAUNCHER_QUICKSWITCH_LEFT) {
- sendEvent(atomInfo, AppTargetEvent.ACTION_LAUNCH);
+ sendEvent(atomInfo, ACTION_LAUNCH, CONTAINER_PREDICTION);
} else if (event == LAUNCHER_ITEM_DROPPED_ON_DONT_SUGGEST) {
- sendEvent(atomInfo, AppTargetEvent.ACTION_DISMISS);
+ sendEvent(atomInfo, ACTION_DISMISS, CONTAINER_PREDICTION);
+ } else if (event == LAUNCHER_ITEM_DRAG_STARTED) {
+ mLastDragItem = atomInfo;
+ } else if (event == LAUNCHER_ITEM_DROP_COMPLETED) {
+ if (mLastDragItem == null) {
+ return;
+ }
+ if (isTrackedForHotseatPrediction(atomInfo)) {
+ sendEvent(atomInfo, ACTION_PIN, CONTAINER_HOTSEAT_PREDICTION);
+ }
+ if (isTrackedForHotseatPrediction(mLastDragItem)) {
+ sendEvent(mLastDragItem, ACTION_UNPIN, CONTAINER_HOTSEAT_PREDICTION);
+ }
+ mLastDragItem = null;
+ } else if (event == LAUNCHER_ITEM_DROP_FOLDER_CREATED) {
+ if (isTrackedForHotseatPrediction(atomInfo)) {
+ sendEvent(createTempFolderTarget(), atomInfo, ACTION_PIN,
+ CONTAINER_HOTSEAT_PREDICTION);
+ sendEvent(atomInfo, ACTION_UNPIN, CONTAINER_HOTSEAT_PREDICTION);
+ }
+ } else if (event == LAUNCHER_FOLDER_CONVERTED_TO_ICON) {
+ if (isTrackedForHotseatPrediction(atomInfo)) {
+ sendEvent(createTempFolderTarget(), atomInfo, ACTION_UNPIN,
+ CONTAINER_HOTSEAT_PREDICTION);
+ sendEvent(atomInfo, ACTION_PIN, CONTAINER_HOTSEAT_PREDICTION);
+ }
+ } else if (event == LAUNCHER_ITEM_DROPPED_ON_REMOVE) {
+ if (mLastDragItem != null && isTrackedForHotseatPrediction(mLastDragItem)) {
+ sendEvent(mLastDragItem, ACTION_UNPIN, CONTAINER_HOTSEAT_PREDICTION);
+ }
+ } else if (event == LAUNCHER_HOTSEAT_PREDICTION_PINNED) {
+ if (isTrackedForHotseatPrediction(atomInfo)) {
+ sendEvent(atomInfo, ACTION_PIN, CONTAINER_HOTSEAT_PREDICTION);
+ }
}
}
@@ -152,10 +206,8 @@
}
break;
}
- case FOLDER_ICON: {
- id = "folder:" + SystemClock.uptimeMillis();
- cn = new ComponentName(mContext.getPackageName(), "#folder");
- }
+ case FOLDER_ICON:
+ return createTempFolderTarget();
}
if (id != null && cn != null) {
return new AppTarget.Builder(new AppTargetId(id), cn.getPackageName(), userHandle)
@@ -165,6 +217,12 @@
return null;
}
+ private AppTarget createTempFolderTarget() {
+ return new AppTarget.Builder(new AppTargetId("folder:" + SystemClock.uptimeMillis()),
+ mContext.getPackageName(), Process.myUserHandle())
+ .build();
+ }
+
private String getContainer(LauncherAtom.ItemInfo info) {
ContainerInfo ci = info.getContainerInfo();
switch (ci.getContainerCase()) {
@@ -212,11 +270,26 @@
}
private static String getHotseatContainerString(HotseatContainer hc) {
- return String.format(Locale.ENGLISH, "hotseat/%d", hc.getIndex());
+ return String.format(Locale.ENGLISH, "hotseat/%1$d/[%1$d,0]/[1,1]", hc.getIndex());
}
private static ComponentName parseNullable(String componentNameString) {
return TextUtils.isEmpty(componentNameString)
? null : ComponentName.unflattenFromString(componentNameString);
}
+
+ /**
+ * Helper method to determine if {@link ItemInfo} should be tracked and reported to predictors
+ */
+ private static boolean isTrackedForHotseatPrediction(LauncherAtom.ItemInfo info) {
+ ContainerInfo ci = info.getContainerInfo();
+ switch (ci.getContainerCase()) {
+ case HOTSEAT:
+ return true;
+ case WORKSPACE:
+ return ci.getWorkspace().getPageIndex() == 0;
+ default:
+ return false;
+ }
+ }
}
diff --git a/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java b/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
index 166cb6c..be57dec 100644
--- a/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
+++ b/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
@@ -16,9 +16,11 @@
package com.android.launcher3.model;
import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_GRID;
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_PREDICTION;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
+import static com.android.launcher3.hybridhotseat.HotseatPredictionModel.convertDataModelToAppTargetBundle;
import android.app.prediction.AppPredictionContext;
import android.app.prediction.AppPredictionManager;
@@ -62,6 +64,8 @@
private final PredictorState mAllAppsState =
new PredictorState(CONTAINER_PREDICTION, "all_apps_predictions");
+ private final PredictorState mHotseatState =
+ new PredictorState(CONTAINER_HOTSEAT_PREDICTION, "hotseat_predictions");
private final InvariantDeviceProfile mIDP;
private final AppEventProducer mAppEventProducer;
@@ -81,13 +85,23 @@
// TODO: Implement caching and preloading
super.loadItems(ums, pinnedShortcuts);
- WorkspaceItemFactory factory =
+ WorkspaceItemFactory allAppsFactory =
new WorkspaceItemFactory(mApp, ums, pinnedShortcuts, mIDP.numAllAppsColumns);
mAllAppsState.items.setItems(
- mAllAppsState.storage.read(mApp.getContext(), factory, ums.allUsers::get));
+ mAllAppsState.storage.read(mApp.getContext(), allAppsFactory, ums.allUsers::get));
mDataModel.extraItems.put(CONTAINER_PREDICTION, mAllAppsState.items);
+ WorkspaceItemFactory hotseatFactory =
+ new WorkspaceItemFactory(mApp, ums, pinnedShortcuts, mIDP.numHotseatIcons);
+ mHotseatState.items.setItems(
+ mHotseatState.storage.read(mApp.getContext(), hotseatFactory, ums.allUsers::get));
+ mDataModel.extraItems.put(CONTAINER_HOTSEAT_PREDICTION, mHotseatState.items);
mActive = true;
+ }
+
+ @Override
+ public void workspaceLoadComplete() {
+ super.workspaceLoadComplete();
recreatePredictors();
}
@@ -111,6 +125,7 @@
private void destroyPredictors() {
mAllAppsState.destroyPredictor();
+ mHotseatState.destroyPredictor();
}
@WorkerThread
@@ -125,18 +140,28 @@
return;
}
- int count = mIDP.numAllAppsColumns;
-
- mAllAppsState.predictor = apm.createAppPredictionSession(
+ registerPredictor(mAllAppsState, apm.createAppPredictionSession(
new AppPredictionContext.Builder(context)
.setUiSurface("home")
- .setPredictedTargetCount(count)
- .build());
- mAllAppsState.predictor.registerPredictionUpdates(
- Executors.MODEL_EXECUTOR, t -> handleUpdate(mAllAppsState, t));
- mAllAppsState.predictor.requestPredictionUpdate();
+ .setPredictedTargetCount(mIDP.numAllAppsColumns)
+ .build()));
+
+ // TODO: get bundle
+ registerPredictor(mHotseatState, apm.createAppPredictionSession(
+ new AppPredictionContext.Builder(context)
+ .setUiSurface("hotseat")
+ .setPredictedTargetCount(mIDP.numHotseatIcons)
+ .setExtras(convertDataModelToAppTargetBundle(context, mDataModel))
+ .build()));
+
}
+ private void registerPredictor(PredictorState state, AppPredictor predictor) {
+ state.predictor = predictor;
+ state.predictor.registerPredictionUpdates(
+ Executors.MODEL_EXECUTOR, t -> handleUpdate(state, t));
+ state.predictor.requestPredictionUpdate();
+ }
private void handleUpdate(PredictorState state, List<AppTarget> targets) {
if (state.setTargets(targets)) {
@@ -154,9 +179,10 @@
}
}
- private void onAppTargetEvent(AppTargetEvent event) {
- if (mAllAppsState.predictor != null) {
- mAllAppsState.predictor.notifyAppTargetEvent(event);
+ private void onAppTargetEvent(AppTargetEvent event, int client) {
+ PredictorState state = client == CONTAINER_PREDICTION ? mAllAppsState : mHotseatState;
+ if (state.predictor != null) {
+ state.predictor.notifyAppTargetEvent(event);
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index f7bc0b3..e808f8c 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -33,8 +33,8 @@
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.content.res.Configuration;
-import android.os.Bundle;
import android.util.Log;
import android.view.View;
@@ -48,14 +48,11 @@
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.appprediction.PredictionRowView;
import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.folder.Folder;
import com.android.launcher3.hybridhotseat.HotseatPredictionController;
import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.logging.StatsLogManager.StatsLogger;
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
-import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.popup.SystemShortcut;
import com.android.launcher3.statemanager.StateManager.AtomicAnimationFactory;
import com.android.launcher3.testing.TestProtocol;
@@ -70,13 +67,14 @@
import com.android.launcher3.uioverrides.touchcontrollers.StatusBarTouchController;
import com.android.launcher3.uioverrides.touchcontrollers.TaskViewTouchController;
import com.android.launcher3.uioverrides.touchcontrollers.TransposedQuickSwitchTouchController;
-import com.android.launcher3.util.IntArray;
+import com.android.launcher3.util.OnboardingPrefs;
import com.android.launcher3.util.TouchController;
import com.android.launcher3.util.UiThreadHelper;
import com.android.launcher3.util.UiThreadHelper.AsyncCommand;
import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.SystemUiProxy;
+import com.android.quickstep.util.QuickstepOnboardingPrefs;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -84,7 +82,6 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;
@@ -98,14 +95,7 @@
SystemUiProxy.INSTANCE.get(context).setShelfHeight(arg1 != 0, arg2);
private FixedContainerItems mAllAppsPredictions;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- if (mHotseatPredictionController != null) {
- mHotseatPredictionController.createPredictor();
- }
- }
+ private HotseatPredictionController mHotseatPredictionController;
@Override
protected void setupViews() {
@@ -143,6 +133,18 @@
}
}
+ /**
+ * Returns Prediction controller for hybrid hotseat
+ */
+ public HotseatPredictionController getHotseatPredictionController() {
+ return mHotseatPredictionController;
+ }
+
+ @Override
+ protected OnboardingPrefs createOnboardingPrefs(SharedPreferences sharedPrefs) {
+ return new QuickstepOnboardingPrefs(this, sharedPrefs);
+ }
+
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
@@ -179,22 +181,6 @@
}
@Override
- public void folderCreatedFromItem(Folder folder, WorkspaceItemInfo itemInfo) {
- super.folderCreatedFromItem(folder, itemInfo);
- if (mHotseatPredictionController != null) {
- mHotseatPredictionController.folderCreatedFromWorkspaceItem(itemInfo, folder.getInfo());
- }
- }
-
- @Override
- public void folderConvertedToItem(Folder folder, WorkspaceItemInfo itemInfo) {
- super.folderConvertedToItem(folder, itemInfo);
- if (mHotseatPredictionController != null) {
- mHotseatPredictionController.folderConvertedToWorkspaceItem(itemInfo, folder.getInfo());
- }
- }
-
- @Override
public Stream<SystemShortcut.Factory> getSupportedShortcuts() {
if (mHotseatPredictionController != null) {
return Stream.concat(super.getSupportedShortcuts(),
@@ -222,19 +208,14 @@
}
@Override
- public void bindPredictedItems(List<AppInfo> appInfos, IntArray ranks) {
- super.bindPredictedItems(appInfos, ranks);
- if (mHotseatPredictionController != null) {
- mHotseatPredictionController.showCachedItems(appInfos, ranks);
- }
- }
-
- @Override
public void bindExtraContainerItems(FixedContainerItems item) {
if (item.containerId == Favorites.CONTAINER_PREDICTION) {
mAllAppsPredictions = item;
getAppsView().getFloatingHeaderView().findFixedRowByType(PredictionRowView.class)
.setPredictedApps(item.items);
+ } else if (item.containerId == Favorites.CONTAINER_HOTSEAT_PREDICTION
+ && mHotseatPredictionController != null) {
+ mHotseatPredictionController.setPredictedItems(item);
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
index 6ec114e..bbe7821 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -16,7 +16,6 @@
package com.android.launcher3.uioverrides.states;
import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
-import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
import static com.android.quickstep.SysUINavigationMode.hideShelfInTwoButtonLandscape;
import static com.android.quickstep.SysUINavigationMode.removeShelfFromOverview;
@@ -30,7 +29,6 @@
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
import com.android.launcher3.Workspace;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.util.LayoutUtils;
@@ -177,8 +175,6 @@
public void onBackPressed(Launcher launcher) {
TaskView taskView = launcher.<RecentsView>getOverviewPanel().getRunningTaskView();
if (taskView != null) {
- launcher.getUserEventDispatcher().logActionCommand(Action.Command.BACK,
- newContainerTarget(ContainerType.OVERVIEW));
taskView.launchTask(true);
} else {
super.onBackPressed(launcher);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
index e3d9498..d574294 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
@@ -228,12 +228,12 @@
() -> onSwipeInteractionCompleted(mEndState));
}
if (mStartState != mEndState) {
- logStateChange(mStartState.containerType, logAction);
+ // TODO: add to WW log
}
AbstractFloatingView topOpenView = AbstractFloatingView.getTopOpenView(mLauncher);
if (topOpenView != null) {
AbstractFloatingView.closeAllOpenViews(mLauncher);
- logStateChange(topOpenView.getLogContainerType(), logAction);
+ // TODO: add to WW log
}
ActivityManagerWrapper.getInstance()
.closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
index dca3378..365cff5 100644
--- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
+++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
@@ -29,7 +29,6 @@
import androidx.annotation.BinderThread;
-import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.quickstep.util.ActivityInitListener;
@@ -87,12 +86,6 @@
MAIN_EXECUTOR.execute(new HideRecentsCommand());
}
- @BinderThread
- public void onTip(int actionType, int viewType) {
- MAIN_EXECUTOR.execute(() ->
- UserEventDispatcher.newInstance(mContext).logActionTip(actionType, viewType));
- }
-
private class ShowRecentsCommand extends RecentsActivityCommand {
private final boolean mTriggeredFromAltTab;
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index ba0a81f..5b4a239 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -22,7 +22,6 @@
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.quickstep.GestureState.DEFAULT_STATE;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_INPUT_MONITOR;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY;
@@ -61,7 +60,6 @@
import com.android.launcher3.ResourceUtils;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.provider.RestoreDbTask;
import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.testing.TestLogging;
@@ -141,7 +139,6 @@
}
@BinderThread
- @Override
public void onOverviewToggle() {
TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "onOverviewToggle");
mOverviewCommandHelper.onOverviewToggle();
@@ -165,7 +162,7 @@
@BinderThread
@Override
public void onTip(int actionType, int viewType) {
- mOverviewCommandHelper.onTip(actionType, viewType);
+ // Please delete this method from the interface
}
@BinderThread
@@ -189,18 +186,7 @@
@BinderThread
public void onBackAction(boolean completed, int downX, int downY, boolean isButton,
boolean gestureSwipeLeft) {
- if (mOverviewComponentObserver == null) {
- return;
- }
-
- final BaseActivityInterface activityInterface =
- mOverviewComponentObserver.getActivityInterface();
- UserEventDispatcher.newInstance(getBaseContext()).logActionBack(completed, downX, downY,
- isButton, gestureSwipeLeft, activityInterface.getContainerType());
-
- if (completed && !isButton && shouldNotifyBackGesture()) {
- UI_HELPER_EXECUTOR.execute(TouchInteractionService.this::tryNotifyBackGesture);
- }
+ // Remove this method from the interface
}
@BinderThread
@@ -263,10 +249,10 @@
mMainChoreographer = Choreographer.getInstance();
mAM = ActivityManagerWrapper.getInstance();
mDeviceState = new RecentsAnimationDeviceState(this);
+ mRotationTouchHelper = mDeviceState.getRotationTouchHelper();
mDeviceState.addNavigationModeChangedCallback(this::onNavigationModeChanged);
mDeviceState.addOneHandedModeChangedCallback(this::onOneHandedModeOverlayChanged);
mDeviceState.runOnUserUnlocked(this::onUserUnlocked);
- mRotationTouchHelper = mDeviceState.getRotationTouchHelper();
ProtoTracer.INSTANCE.get(this).add(this);
sConnected = true;
diff --git a/quickstep/src/com/android/quickstep/logging/UserEventDispatcherExtension.java b/quickstep/src/com/android/quickstep/logging/UserEventDispatcherExtension.java
deleted file mode 100644
index 9ca7f23..0000000
--- a/quickstep/src/com/android/quickstep/logging/UserEventDispatcherExtension.java
+++ /dev/null
@@ -1,86 +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.logging;
-
-import android.content.Context;
-import android.util.Log;
-
-import static com.android.launcher3.logging.LoggerUtils.newLauncherEvent;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.ControlType.CANCEL_TARGET;
-import static com.android.systemui.shared.system.LauncherEventUtil.DISMISS;
-import static com.android.systemui.shared.system.LauncherEventUtil.RECENTS_QUICK_SCRUB_ONBOARDING_TIP;
-import static com.android.systemui.shared.system.LauncherEventUtil.RECENTS_SWIPE_UP_ONBOARDING_TIP;
-import static com.android.systemui.shared.system.LauncherEventUtil.VISIBLE;
-
-import com.android.launcher3.logging.UserEventDispatcher;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
-import com.android.systemui.shared.system.MetricsLoggerCompat;
-
-/**
- * This class handles AOSP MetricsLogger function calls and logging around
- * quickstep interactions.
- */
-@SuppressWarnings("unused")
-public class UserEventDispatcherExtension extends UserEventDispatcher {
-
- public static final int ALL_APPS_PREDICTION_TIPS = 2;
-
- private static final String TAG = "UserEventDispatcher";
-
- public UserEventDispatcherExtension(Context context) { }
-
- public void logStateChangeAction(int action, int dir, int downX, int downY,
- int srcChildTargetType, int srcParentContainerType,
- int dstContainerType, int pageIndex) {
- new MetricsLoggerCompat().visibility(MetricsLoggerCompat.OVERVIEW_ACTIVITY,
- dstContainerType == LauncherLogProto.ContainerType.TASKSWITCHER);
- super.logStateChangeAction(action, dir, downX, downY, srcChildTargetType,
- srcParentContainerType, dstContainerType, pageIndex);
- }
-
- public void logActionTip(int actionType, int viewType) {
- LauncherLogProto.Action action = new LauncherLogProto.Action();
- LauncherLogProto.Target target = new LauncherLogProto.Target();
- switch(actionType) {
- case VISIBLE:
- action.type = LauncherLogProto.Action.Type.TIP;
- target.type = LauncherLogProto.Target.Type.CONTAINER;
- target.containerType = LauncherLogProto.ContainerType.TIP;
- break;
- case DISMISS:
- action.type = LauncherLogProto.Action.Type.TOUCH;
- action.touch = LauncherLogProto.Action.Touch.TAP;
- target.type = LauncherLogProto.Target.Type.CONTROL;
- target.controlType = CANCEL_TARGET;
- break;
- default:
- Log.e(TAG, "Unexpected action type = " + actionType);
- }
-
- switch(viewType) {
- case RECENTS_QUICK_SCRUB_ONBOARDING_TIP:
- target.tipType = LauncherLogProto.TipType.QUICK_SCRUB_TEXT;
- break;
- case RECENTS_SWIPE_UP_ONBOARDING_TIP:
- target.tipType = LauncherLogProto.TipType.SWIPE_UP_TEXT;
- break;
- default:
- Log.e(TAG, "Unexpected viewType = " + viewType);
- }
- LauncherLogProto.LauncherEvent event = newLauncherEvent(action, target);
- dispatchUserEvent(event, null);
- }
-}
diff --git a/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java b/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
index 7eda627..b10adb4 100644
--- a/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
+++ b/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
@@ -26,13 +26,13 @@
import android.content.SharedPreferences;
-import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.Workspace;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.hybridhotseat.HotseatPredictionController;
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.statemanager.StateManager.StateListener;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.OnboardingPrefs;
import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.views.AllAppsEduView;
@@ -40,9 +40,9 @@
/**
* Extends {@link OnboardingPrefs} for quickstep-specific onboarding data.
*/
-public class QuickstepOnboardingPrefs extends OnboardingPrefs<BaseQuickstepLauncher> {
+public class QuickstepOnboardingPrefs extends OnboardingPrefs<QuickstepLauncher> {
- public QuickstepOnboardingPrefs(BaseQuickstepLauncher launcher, SharedPreferences sharedPrefs) {
+ public QuickstepOnboardingPrefs(QuickstepLauncher launcher, SharedPreferences sharedPrefs) {
super(launcher, sharedPrefs);
StateManager<LauncherState> stateManager = launcher.getStateManager();
diff --git a/quickstep/src/com/android/quickstep/views/AllAppsEduView.java b/quickstep/src/com/android/quickstep/views/AllAppsEduView.java
index c06dd9c..97a239c 100644
--- a/quickstep/src/com/android/quickstep/views/AllAppsEduView.java
+++ b/quickstep/src/com/android/quickstep/views/AllAppsEduView.java
@@ -105,11 +105,6 @@
}
@Override
- public void logActionCommand(int command) {
- // TODO
- }
-
- @Override
protected boolean isOfType(int type) {
return (type & TYPE_ALL_APPS_EDU) != 0;
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index a9b5bf3..982a7c4 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -110,8 +110,6 @@
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;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.DynamicResource;
@@ -142,7 +140,6 @@
import com.android.systemui.shared.recents.model.Task.TaskKey;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.shared.system.LauncherEventUtil;
import com.android.systemui.shared.system.PackageManagerWrapper;
import com.android.systemui.shared.system.TaskStackChangeListener;
@@ -673,9 +670,6 @@
public void onDigitalWellbeingToastShown() {
if (!mDwbToastShown) {
mDwbToastShown = true;
- mActivity.getUserEventDispatcher().logActionTip(
- LauncherEventUtil.VISIBLE,
- LauncherLogProto.TipType.DWB_TOAST);
}
}
@@ -1461,8 +1455,6 @@
if (taskView.getTask() != null) {
ActivityManagerWrapper.getInstance().removeTask(taskView.getTask().key.id);
ComponentKey compKey = TaskUtils.getLaunchComponentKeyForTask(taskView.getTask().key);
- mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
- endState.logAction, Direction.UP, index, compKey);
mActivity.getStatsLogManager().logger().withItemInfo(taskView.getItemInfo())
.log(LAUNCHER_TASK_DISMISS_SWIPE_UP);
}
@@ -2174,9 +2166,6 @@
tv.launchTask(false, onLaunchResult, getHandler());
Task task = tv.getTask();
if (task != null) {
- mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
- endState.logAction, Direction.DOWN, indexOfChild(tv),
- TaskUtils.getLaunchComponentKeyForTask(task.key));
mActivity.getStatsLogManager().logger().withItemInfo(tv.getItemInfo())
.log(LAUNCHER_TASK_LAUNCH_SWIPE_DOWN);
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
index 8b49f2c..656d59e 100644
--- a/quickstep/src/com/android/quickstep/views/TaskMenuView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
@@ -133,11 +133,6 @@
}
@Override
- public void logActionCommand(int command) {
- // TODO
- }
-
- @Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 3a359f0..259cd4d 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -225,10 +225,6 @@
} else {
launchTask(true /* animate */);
}
-
- mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
- Touch.TAP, Direction.NONE, getRecentsView().indexOfChild(this),
- TaskUtils.getLaunchComponentKeyForTask(getTask().key));
mActivity.getStatsLogManager().logger().withItemInfo(getItemInfo())
.log(LAUNCHER_TASK_LAUNCH_TAP);
});
diff --git a/res/layout/search_result_settings_row.xml b/res/layout/search_result_settings_row.xml
new file mode 100644
index 0000000..19daf34
--- /dev/null
+++ b/res/layout/search_result_settings_row.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2020 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.
+-->
+<com.android.launcher3.views.SearchSettingsRowView xmlns:android="http://schemas.android.com/apk/res/android"
+ style="@style/TextHeadline"
+ android:id="@+id/section_title"
+ android:background="?android:attr/selectableItemBackground"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:gravity="center_vertical"
+ android:padding="4dp"
+ android:minHeight="48dp"
+ android:textColor="?android:attr/textColorPrimary"
+ android:textSize="14sp">
+
+ <TextView
+ android:id="@+id/title"
+ style="@style/TextTitle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="4dp"
+ android:textColor="?android:attr/textColorPrimary"
+ android:textSize="16sp" />
+
+ <TextView
+ android:id="@+id/description"
+ style="@style/TextTitle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ android:textColor="?android:attr/textColorPrimary"
+ android:textSize="14sp" />
+
+ <TextView
+ android:id="@+id/breadcrumbs"
+ style="@style/TextTitle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ android:alpha=".7"
+ android:textColor="?android:attr/textColorSecondary"
+ android:textSize="14sp" />
+
+
+</com.android.launcher3.views.SearchSettingsRowView>
\ No newline at end of file
diff --git a/res/layout/search_result_slice.xml b/res/layout/search_result_slice.xml
new file mode 100644
index 0000000..ea1d49a
--- /dev/null
+++ b/res/layout/search_result_slice.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<androidx.slice.widget.SliceView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingHorizontal="4dp" />
\ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
index fe9717c..f56fbaa 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -35,9 +35,6 @@
<color name="icon_background">#E0E0E0</color> <!-- Gray 300 -->
- <color name="all_apps_section_fill">#32c0c0c0</color>
- <color name="all_apps_section_focused_item">#40c0c0c0</color>
-
<color name="gesture_tutorial_ripple_color">#A0C2F9</color> <!-- Light Blue -->
<color name="gesture_tutorial_fake_task_view_color">#6DA1FF</color> <!-- Light Blue -->
<color name="gesture_tutorial_action_button_label_color">#FFFFFFFF</color>
diff --git a/res/values/config.xml b/res/values/config.xml
index dc8bdff..fc0a5e1 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -69,7 +69,6 @@
<string name="app_launch_tracker_class" translatable="false"></string>
<string name="test_information_handler_class" translatable="false"></string>
<string name="launcher_activity_logic_class" translatable="false"></string>
- <string name="prediction_model_class" translatable="false"></string>
<string name="model_delegate_class" translatable="false"></string>
<!-- View ID to use for QSB widget -->
diff --git a/res/xml/launcher_preferences.xml b/res/xml/launcher_preferences.xml
index 3455cb8..7e72208 100644
--- a/res/xml/launcher_preferences.xml
+++ b/res/xml/launcher_preferences.xml
@@ -44,12 +44,6 @@
android:defaultValue="@bool/allow_rotation"
android:persistent="true" />
- <SwitchPreference
- android:key="pref_grid_options"
- android:title="Enable grid options"
- android:defaultValue="false"
- android:persistent="true" />
-
<androidx.preference.PreferenceScreen
android:key="pref_developer_options"
android:persistent="false"
diff --git a/src/com/android/launcher3/AbstractFloatingView.java b/src/com/android/launcher3/AbstractFloatingView.java
index 3bfe379..3c34444 100644
--- a/src/com/android/launcher3/AbstractFloatingView.java
+++ b/src/com/android/launcher3/AbstractFloatingView.java
@@ -36,8 +36,6 @@
import androidx.annotation.IntDef;
import com.android.launcher3.anim.PendingAnimation;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.launcher3.util.TouchController;
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.BaseDragLayer;
@@ -129,8 +127,7 @@
public final void close(boolean animate) {
animate &= areAnimatorsEnabled();
if (mIsOpen) {
- BaseActivity.fromContext(getContext()).getUserEventDispatcher()
- .resetElapsedContainerMillis("container closed");
+ // Add to WW logging
}
handleClose(animate);
mIsOpen = false;
@@ -145,12 +142,6 @@
public void addHintCloseAnim(
float distanceToMove, Interpolator interpolator, PendingAnimation target) { }
- public abstract void logActionCommand(int command);
-
- public int getLogContainerType() {
- return ContainerType.DEFAULT_CONTAINERTYPE;
- }
-
public final boolean isOpen() {
return mIsOpen;
}
@@ -159,7 +150,6 @@
/** @return Whether the back is consumed. If false, Launcher will handle the back as well. */
public boolean onBackPressed() {
- logActionCommand(Action.Command.BACK);
close(true);
return true;
}
diff --git a/src/com/android/launcher3/AppWidgetResizeFrame.java b/src/com/android/launcher3/AppWidgetResizeFrame.java
index 6f7b684..168d9c4 100644
--- a/src/com/android/launcher3/AppWidgetResizeFrame.java
+++ b/src/com/android/launcher3/AppWidgetResizeFrame.java
@@ -537,11 +537,6 @@
}
@Override
- public void logActionCommand(int command) {
- // TODO: Log this case.
- }
-
- @Override
protected boolean isOfType(int type) {
return (type & TYPE_WIDGET_RESIZE_FRAME) != 0;
}
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index cbc3abc..0d90602 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -193,7 +193,6 @@
getSystemService(LauncherApps.class).startMainActivity(
intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
}
- getUserEventDispatcher().logAppLaunch(v, intent, user);
if (item != null) {
InstanceId instanceId = new InstanceIdSequence().newInstanceId();
logAppLaunch(item, instanceId);
diff --git a/src/com/android/launcher3/DragSource.java b/src/com/android/launcher3/DragSource.java
index d4d7b99..ba227d4 100644
--- a/src/com/android/launcher3/DragSource.java
+++ b/src/com/android/launcher3/DragSource.java
@@ -19,12 +19,11 @@
import android.view.View;
import com.android.launcher3.DropTarget.DragObject;
-import com.android.launcher3.logging.StatsLogUtils.LogContainerProvider;
/**
* Interface defining an object that can originate a drag.
*/
-public interface DragSource extends LogContainerProvider {
+public interface DragSource {
/**
* A callback made back to the source after an item from this source has been dropped on a
diff --git a/src/com/android/launcher3/DropTarget.java b/src/com/android/launcher3/DropTarget.java
index b27abc4..fd4c30c 100644
--- a/src/com/android/launcher3/DropTarget.java
+++ b/src/com/android/launcher3/DropTarget.java
@@ -113,18 +113,6 @@
return res;
}
-
-
- /**
- * This is used to determine if an object is dropped at a different location than it was
- * dragged from
- */
- public boolean isMoved() {
- return dragInfo.cellX != originalDragInfo.cellX
- || dragInfo.cellY != originalDragInfo.cellY
- || dragInfo.screenId != originalDragInfo.screenId
- || dragInfo.container != originalDragInfo.container;
- }
}
/**
diff --git a/src/com/android/launcher3/ExtendedEditText.java b/src/com/android/launcher3/ExtendedEditText.java
index d64967b..02c6162 100644
--- a/src/com/android/launcher3/ExtendedEditText.java
+++ b/src/com/android/launcher3/ExtendedEditText.java
@@ -24,6 +24,7 @@
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.UiThreadHelper;
@@ -130,6 +131,10 @@
public void reset() {
if (!TextUtils.isEmpty(getText())) {
setText("");
+ } else {
+ if (FeatureFlags.ENABLE_DEVICE_SEARCH.get()) {
+ return;
+ }
}
if (isFocused()) {
View nextFocus = focusSearch(View.FOCUS_DOWN);
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 51a9dfe..cacd3fb 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -110,7 +110,6 @@
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.dragndrop.DragView;
-import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderGridOrganizer;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.icons.IconCache;
@@ -911,7 +910,6 @@
@CallSuper
protected void onDeferredResumed() {
logStopAndResume(Action.Command.RESUME);
- getUserEventDispatcher().startSession();
// Process any items that were added while Launcher was away.
ItemInstallQueue.INSTANCE.get(this)
@@ -929,6 +927,7 @@
protected void handlePendingActivityRequest() { }
private void logStopAndResume(int command) {
+ if (mPendingExecutor != null) return;
int pageIndex = mWorkspace.isOverlayShown() ? -1 : mWorkspace.getCurrentPage();
int containerType = mStateManager.getState().containerType;
@@ -1747,16 +1746,6 @@
}
/**
- * Called when a workspace item is converted into a folder
- */
- public void folderCreatedFromItem(Folder folder, WorkspaceItemInfo itemInfo){}
-
- /**
- * Called when a folder is converted into a workspace item
- */
- public void folderConvertedToItem(Folder folder, WorkspaceItemInfo itemInfo) {}
-
- /**
* Unbinds the view for the specified item, and removes the item and all its children.
*
* @param v the view being removed.
@@ -2193,9 +2182,6 @@
workspace.requestLayout();
}
- @Override
- public void bindPredictedItems(List<AppInfo> appInfos, IntArray ranks) { }
-
/**
* Add the views for a widget to the workspace.
*/
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 782a869..b278e81 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -33,7 +33,6 @@
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.icons.IconProvider;
import com.android.launcher3.icons.LauncherIcons;
-import com.android.launcher3.model.PredictionModel;
import com.android.launcher3.notification.NotificationListener;
import com.android.launcher3.pm.InstallSessionHelper;
import com.android.launcher3.pm.InstallSessionTracker;
@@ -58,7 +57,6 @@
private final IconCache mIconCache;
private final WidgetPreviewLoader mWidgetCache;
private final InvariantDeviceProfile mInvariantDeviceProfile;
- private final PredictionModel mPredictionModel;
private SecureSettingsObserver mNotificationDotsObserver;
private InstallSessionTracker mInstallSessionTracker;
@@ -125,7 +123,6 @@
mIconCache = new IconCache(mContext, mInvariantDeviceProfile, iconCacheFileName);
mWidgetCache = new WidgetPreviewLoader(mContext, mIconCache);
mModel = new LauncherModel(context, this, mIconCache, AppFilter.newInstance(mContext));
- mPredictionModel = PredictionModel.newInstance(mContext);
}
protected void onNotificationSettingsChanged(boolean areNotificationDotsEnabled) {
@@ -182,10 +179,6 @@
return mModel;
}
- public PredictionModel getPredictionModel() {
- return mPredictionModel;
- }
-
public WidgetPreviewLoader getWidgetCache() {
return mWidgetCache;
}
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index c51a84e..8458152 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -219,6 +219,13 @@
}
/**
+ * Called when the workspace items have drastically changed
+ */
+ public void onWorkspaceUiChanged() {
+ MODEL_EXECUTOR.execute(mModelDelegate::workspaceLoadComplete);
+ }
+
+ /**
* Called when the model is destroyed
*/
public void destroy() {
diff --git a/src/com/android/launcher3/SecondaryDropTarget.java b/src/com/android/launcher3/SecondaryDropTarget.java
index 56875bb..2df7f5a 100644
--- a/src/com/android/launcher3/SecondaryDropTarget.java
+++ b/src/com/android/launcher3/SecondaryDropTarget.java
@@ -49,7 +49,6 @@
import com.android.launcher3.util.Themes;
import java.net.URISyntaxException;
-import java.util.ArrayList;
/**
* Drop target which provides a secondary option for an item.
@@ -340,12 +339,6 @@
}
@Override
- public void fillInLogContainerData(ItemInfo childInfo, Target child,
- ArrayList<Target> parents) {
- mOriginal.fillInLogContainerData(childInfo, child, parents);
- }
-
- @Override
public void onLauncherResume() {
// We use MATCH_UNINSTALLED_PACKAGES as the app can be on SD card as well.
if (new PackageManagerHelper(mContext).getApplicationInfo(mPackageName,
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 6bfd349..8da81ac 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -28,7 +28,6 @@
import static com.android.launcher3.LauncherState.SPRING_LOADED;
import static com.android.launcher3.config.FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM;
import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_OVERLAY;
-import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SWIPELEFT;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SWIPERIGHT;
@@ -99,7 +98,6 @@
import com.android.launcher3.touch.WorkspaceTouchListener;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
import com.android.launcher3.util.Executors;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.IntSparseArrayMap;
@@ -1506,7 +1504,6 @@
.showForIcon((BubbleTextView) child);
if (popupContainer != null) {
dragOptions.preDragCondition = popupContainer.createPreDragCondition();
- mLauncher.getUserEventDispatcher().resetElapsedContainerMillis("dragging started");
}
}
@@ -1706,7 +1703,6 @@
fi.addItem(destInfo);
fi.addItem(sourceInfo);
}
- mLauncher.folderCreatedFromItem(fi.getFolder(), destInfo);
return true;
}
return false;
@@ -1723,7 +1719,7 @@
if (dropOverView instanceof FolderIcon) {
FolderIcon fi = (FolderIcon) dropOverView;
if (fi.acceptDrop(d.dragInfo)) {
- mStatsLogManager.logger().withItemInfo(fi.mInfo).withInstanceId(d.logInstanceId)
+ mStatsLogManager.logger().withItemInfo(d.dragInfo).withInstanceId(d.logInstanceId)
.log(LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED);
fi.onDrop(d, false /* itemReturnedOnFailedDrop */);
@@ -3272,24 +3268,6 @@
return getContext().getString(R.string.workspace_scroll_format, page + 1, nScreens);
}
- @Override
- public void fillInLogContainerData(ItemInfo childInfo, Target child,
- ArrayList<Target> parents) {
- if (childInfo.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT
- || childInfo.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION) {
- getHotseat().fillInLogContainerData(childInfo, child, parents);
- return;
- } else if (childInfo.container >= 0) {
- FolderIcon icon = (FolderIcon) getHomescreenIconByItemId(childInfo.container);
- icon.getFolder().fillInLogContainerData(childInfo, child, parents);
- return;
- }
- child.gridX = childInfo.cellX;
- child.gridY = childInfo.cellY;
- child.pageIndex = getCurrentPage();
- parents.add(newContainerTarget(ContainerType.WORKSPACE));
- }
-
/**
* Used as a workaround to ensure that the AppWidgetService receives the
* PACKAGE_ADDED broadcast before updating widgets.
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 99fff4d..1f51566 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -17,7 +17,6 @@
import static com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItem;
import static com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItemWithPayload;
-import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_HAS_SHORTCUT_PERMISSION;
import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_CHANGE_PERMISSION;
import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_ENABLED;
@@ -44,6 +43,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
+import androidx.core.os.BuildCompat;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -61,8 +61,6 @@
import com.android.launcher3.keyboard.FocusedItemDecorator;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
@@ -70,8 +68,6 @@
import com.android.launcher3.views.RecyclerViewFastScroller;
import com.android.launcher3.views.SpringRelativeLayout;
-import java.util.ArrayList;
-
/**
* The all apps view container.
*/
@@ -110,7 +106,7 @@
private final MultiValueAlpha mMultiValueAlpha;
- Rect mInsets = new Rect();
+ private Rect mInsets = new Rect();
public AllAppsContainerView(Context context) {
this(context, null);
@@ -206,6 +202,17 @@
mAH[AdapterHolder.WORK].applyPadding();
}
+ private void hideInput() {
+ if (!BuildCompat.isAtLeastR() || !FeatureFlags.ENABLE_DEVICE_SEARCH.get()) return;
+
+ WindowInsets insets = getRootWindowInsets();
+ if (insets == null) return;
+
+ if (insets.isVisible(WindowInsets.Type.ime())) {
+ getWindowInsetsController().hide(WindowInsets.Type.ime());
+ }
+ }
+
/**
* Returns whether the view itself will handle the touch event or not.
*/
@@ -221,9 +228,14 @@
}
if (rv.getScrollbar().getThumbOffsetY() >= 0 &&
mLauncher.getDragLayer().isEventOverView(rv.getScrollbar(), ev)) {
+ hideInput();
return false;
}
- return rv.shouldContainerScroll(ev, mLauncher.getDragLayer());
+ boolean shouldScroll = rv.shouldContainerScroll(ev, mLauncher.getDragLayer());
+ if (shouldScroll) {
+ hideInput();
+ }
+ return shouldScroll;
}
@Override
@@ -338,13 +350,6 @@
}
@Override
- public void fillInLogContainerData(ItemInfo childInfo, Target child,
- ArrayList<Target> parents) {
- parents.add(newContainerTarget(
- getApps().hasFilter() ? ContainerType.SEARCHRESULT : ContainerType.ALLAPPS));
- }
-
- @Override
public void setInsets(Rect insets) {
mInsets.set(insets);
DeviceProfile grid = mLauncher.getDeviceProfile();
diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
index c61f01f..da161ac 100644
--- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
+++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
@@ -20,6 +20,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
+import android.net.Uri;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
@@ -30,18 +31,27 @@
import android.view.accessibility.AccessibilityEvent;
import android.widget.TextView;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.view.accessibility.AccessibilityEventCompat;
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
import androidx.core.view.accessibility.AccessibilityRecordCompat;
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleOwner;
+import androidx.lifecycle.LifecycleRegistry;
+import androidx.lifecycle.LiveData;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
+import androidx.slice.Slice;
+import androidx.slice.widget.SliceLiveData;
+import androidx.slice.widget.SliceView;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.R;
import com.android.launcher3.allapps.search.AllAppsSearchBarController.PayloadResultHandler;
import com.android.launcher3.allapps.search.SearchSectionInfo;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.util.PackageManagerHelper;
@@ -50,7 +60,9 @@
/**
* The grid view adapter of all the apps.
*/
-public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.ViewHolder> {
+public class AllAppsGridAdapter extends
+ RecyclerView.Adapter<AllAppsGridAdapter.ViewHolder> implements
+ LifecycleOwner {
public static final String TAG = "AppsGridAdapter";
@@ -71,12 +83,18 @@
public static final int VIEW_TYPE_SEARCH_HERO_APP = 1 << 6;
- public static final int DETAIL_ROW_WITH_BUTTON = 1 << 7;
+ public static final int VIEW_TYPE_SEARCH_ROW_WITH_BUTTON = 1 << 7;
+
+ public static final int VIEW_TYPE_SEARCH_ROW = 1 << 8;
+
+ public static final int VIEW_TYPE_SEARCH_SLICE = 1 << 9;
// Common view type masks
public static final int VIEW_TYPE_MASK_DIVIDER = VIEW_TYPE_ALL_APPS_DIVIDER;
public static final int VIEW_TYPE_MASK_ICON = VIEW_TYPE_ICON;
+ private final LifecycleRegistry mLifecycleRegistry;
+
/**
* ViewHolder for each icon.
*/
@@ -159,12 +177,15 @@
boolean isCountedForAccessibility() {
return viewType == VIEW_TYPE_ICON
|| viewType == VIEW_TYPE_SEARCH_HERO_APP
- || viewType == DETAIL_ROW_WITH_BUTTON;
+ || viewType == VIEW_TYPE_SEARCH_ROW_WITH_BUTTON
+ || viewType == VIEW_TYPE_SEARCH_SLICE
+ || viewType == VIEW_TYPE_SEARCH_ROW;
}
}
/**
* Extension of AdapterItem that contains an extra payload specific to item
+ *
* @param <T> Play load Type
*/
public static class AdapterItemWithPayload<T> extends AdapterItem {
@@ -310,6 +331,12 @@
mOnIconClickListener = launcher.getItemOnClickListener();
setAppsPerRow(mLauncher.getDeviceProfile().inv.numAllAppsColumns);
+ if (FeatureFlags.ENABLE_DEVICE_SEARCH.get()) {
+ mLifecycleRegistry = new LifecycleRegistry(this);
+ mLifecycleRegistry.setCurrentState(Lifecycle.State.STARTED);
+ } else {
+ mLifecycleRegistry = null;
+ }
}
public void setAppsPerRow(int appsPerRow) {
@@ -390,9 +417,15 @@
case VIEW_TYPE_SEARCH_HERO_APP:
return new ViewHolder(mLayoutInflater.inflate(
R.layout.search_result_hero_app, parent, false));
- case DETAIL_ROW_WITH_BUTTON:
+ case VIEW_TYPE_SEARCH_ROW_WITH_BUTTON:
return new ViewHolder(mLayoutInflater.inflate(
R.layout.search_result_play_item, parent, false));
+ case VIEW_TYPE_SEARCH_ROW:
+ return new ViewHolder(mLayoutInflater.inflate(
+ R.layout.search_result_settings_row, parent, false));
+ case VIEW_TYPE_SEARCH_SLICE:
+ return new ViewHolder(mLayoutInflater.inflate(
+ R.layout.search_result_slice, parent, false));
default:
throw new RuntimeException("Unexpected view type");
}
@@ -421,9 +454,20 @@
searchView.setVisibility(View.GONE);
}
break;
+ case VIEW_TYPE_SEARCH_SLICE:
+ SliceView sliceView = (SliceView) holder.itemView;
+ Uri uri = ((AdapterItemWithPayload<Uri>) mApps.getAdapterItems().get(position))
+ .getPayload();
+ try {
+ LiveData<Slice> liveData = SliceLiveData.fromUri(mLauncher, uri);
+ liveData.observe(this::getLifecycle, sliceView);
+ } catch (Exception ignored) {
+ }
+ break;
case VIEW_TYPE_SEARCH_CORPUS_TITLE:
- case DETAIL_ROW_WITH_BUTTON:
+ case VIEW_TYPE_SEARCH_ROW_WITH_BUTTON:
case VIEW_TYPE_SEARCH_HERO_APP:
+ case VIEW_TYPE_SEARCH_ROW:
PayloadResultHandler payloadResultView = (PayloadResultHandler) holder.itemView;
payloadResultView.applyAdapterInfo(
(AdapterItemWithPayload) mApps.getAdapterItems().get(position));
@@ -451,4 +495,9 @@
return item.viewType;
}
+ @NonNull
+ @Override
+ public Lifecycle getLifecycle() {
+ return mLifecycleRegistry;
+ }
}
diff --git a/src/com/android/launcher3/allapps/AllAppsSectionDecorator.java b/src/com/android/launcher3/allapps/AllAppsSectionDecorator.java
index 6f29e11..0214c35 100644
--- a/src/com/android/launcher3/allapps/AllAppsSectionDecorator.java
+++ b/src/com/android/launcher3/allapps/AllAppsSectionDecorator.java
@@ -22,6 +22,7 @@
import android.view.View;
import androidx.annotation.Nullable;
+import androidx.core.graphics.ColorUtils;
import androidx.recyclerview.widget.RecyclerView;
import com.android.launcher3.R;
@@ -100,19 +101,23 @@
* Handles grouping and drawing of items in the same all apps sections.
*/
public static class SectionDecorationHandler {
+ private static final int FILL_ALPHA = (int) (.3f * 255);
+ private static final int FOCUS_ALPHA = (int) (.8f * 255);
+
protected RectF mBounds = new RectF();
private final boolean mIsFullWidth;
private final float mRadius;
- private final int mFocusColor;
- private final int mFillcolor;
+ protected int mFocusColor;
+ protected int mFillcolor;
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
public SectionDecorationHandler(Context context, boolean isFullWidth) {
mIsFullWidth = isFullWidth;
- mFillcolor = context.getColor(R.color.all_apps_section_fill);
- mFocusColor = context.getColor(R.color.all_apps_section_focused_item);
+ int endScrim = Themes.getAttrColor(context, R.attr.allAppsScrimColor);
+ mFillcolor = ColorUtils.setAlphaComponent(endScrim, FILL_ALPHA);
+ mFocusColor = ColorUtils.setAlphaComponent(endScrim, FOCUS_ALPHA);
mRadius = Themes.getDialogCornerRadius(context);
}
diff --git a/src/com/android/launcher3/allapps/DiscoveryBounce.java b/src/com/android/launcher3/allapps/DiscoveryBounce.java
index b4ff5ea..14595ca 100644
--- a/src/com/android/launcher3/allapps/DiscoveryBounce.java
+++ b/src/com/android/launcher3/allapps/DiscoveryBounce.java
@@ -116,11 +116,6 @@
}
@Override
- public void logActionCommand(int command) {
- // Since this is on-boarding popup, it is not a user controlled action.
- }
-
- @Override
protected boolean isOfType(int type) {
return (type & TYPE_DISCOVERY_BOUNCE) != 0;
}
diff --git a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
index 6f183ee..7518521 100644
--- a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
+++ b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
@@ -139,8 +139,8 @@
mApps = appsView.getApps();
mAppsView = appsView;
mSearchBarController.initialize(
- new DefaultAppSearchAlgorithm(LauncherAppState.getInstance(mLauncher)), this,
- mLauncher, this, this);
+ new DefaultAppSearchAlgorithm(mLauncher, LauncherAppState.getInstance(mLauncher)),
+ this, mLauncher, this, this);
}
@Override
diff --git a/src/com/android/launcher3/allapps/search/AppsSearchPipeline.java b/src/com/android/launcher3/allapps/search/AppsSearchPipeline.java
index fb3d953..6e9a7da 100644
--- a/src/com/android/launcher3/allapps/search/AppsSearchPipeline.java
+++ b/src/com/android/launcher3/allapps/search/AppsSearchPipeline.java
@@ -53,15 +53,16 @@
private final LauncherAppState mLauncherAppState;
private final boolean mHeroSectionSupported;
- public AppsSearchPipeline(LauncherAppState launcherAppState) {
- this(launcherAppState, true);
+ public AppsSearchPipeline(Context context, LauncherAppState launcherAppState) {
+ this(context, launcherAppState, true);
}
- public AppsSearchPipeline(LauncherAppState launcherAppState, boolean supportsHeroView) {
+ public AppsSearchPipeline(Context context, LauncherAppState launcherAppState,
+ boolean supportsHeroView) {
mLauncherAppState = launcherAppState;
mSearchSectionInfo = new SearchSectionInfo();
mSearchSectionInfo.setDecorationHandler(
- new SectionDecorationHandler(launcherAppState.getContext(), true));
+ new SectionDecorationHandler(context, true));
mHeroSectionSupported = supportsHeroView;
}
diff --git a/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java b/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java
index 470191c..d757f78 100644
--- a/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java
+++ b/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java
@@ -15,6 +15,7 @@
*/
package com.android.launcher3.allapps.search;
+import android.content.Context;
import android.os.Handler;
import com.android.launcher3.LauncherAppState;
@@ -30,9 +31,9 @@
protected final Handler mResultHandler;
private final AppsSearchPipeline mAppsSearchPipeline;
- public DefaultAppSearchAlgorithm(LauncherAppState launcherAppState) {
+ public DefaultAppSearchAlgorithm(Context context, LauncherAppState launcherAppState) {
mResultHandler = new Handler();
- mAppsSearchPipeline = new AppsSearchPipeline(launcherAppState, false);
+ mAppsSearchPipeline = new AppsSearchPipeline(context, launcherAppState, false);
}
@Override
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 37d2d40..d8fca1d 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -174,9 +174,6 @@
"SEPARATE_RECENTS_ACTIVITY", false,
"Uses a separate recents activity instead of using the integrated recents+Launcher UI");
- public static final BooleanFlag USER_EVENT_DISPATCHER = new DeviceFlag(
- "USER_EVENT_DISPATCHER", true, "User event dispatcher collects logs.");
-
public static final BooleanFlag ENABLE_MINIMAL_DEVICE = new DeviceFlag(
"ENABLE_MINIMAL_DEVICE", false,
"Allow user to toggle minimal device mode in launcher.");
diff --git a/src/com/android/launcher3/dragndrop/PinItemDragListener.java b/src/com/android/launcher3/dragndrop/PinItemDragListener.java
index bf3aa7f..6104d80 100644
--- a/src/com/android/launcher3/dragndrop/PinItemDragListener.java
+++ b/src/com/android/launcher3/dragndrop/PinItemDragListener.java
@@ -16,7 +16,6 @@
package com.android.launcher3.dragndrop;
-import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
import android.annotation.TargetApi;
import android.appwidget.AppWidgetManager;
@@ -33,15 +32,11 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppWidgetProviderInfo;
import com.android.launcher3.PendingAddItemInfo;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.widget.PendingAddShortcutInfo;
import com.android.launcher3.widget.PendingAddWidgetInfo;
import com.android.launcher3.widget.PendingItemDragHelper;
import com.android.launcher3.widget.WidgetAddFlowHandler;
-import java.util.ArrayList;
-
/**
* {@link DragSource} for handling drop from a different window. This object is initialized
* in the source window and is passed on to the Launcher activity as an Intent extra.
@@ -107,12 +102,6 @@
}
@Override
- public void fillInLogContainerData(ItemInfo childInfo, LauncherLogProto.Target child,
- ArrayList<LauncherLogProto.Target> parents) {
- parents.add(newContainerTarget(LauncherLogProto.ContainerType.PINITEM));
- }
-
- @Override
protected void postCleanup() {
super.postCleanup();
mCancelSignal.cancel();
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index b91d1c3..f1606ea 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -19,11 +19,11 @@
import static android.text.TextUtils.isEmpty;
import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY;
-import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent;
import static com.android.launcher3.config.FeatureFlags.ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS;
import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_CONVERTED_TO_ICON;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_LABEL_UPDATED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED;
@@ -1183,7 +1183,8 @@
newIcon.requestFocus();
}
if (finalItem != null) {
- mLauncher.folderConvertedToItem(mFolderIcon.getFolder(), finalItem);
+ mStatsLogManager.logger().withItemInfo(finalItem)
+ .log(LAUNCHER_FOLDER_CONVERTED_TO_ICON);
}
}
}
@@ -1481,27 +1482,6 @@
outRect.right += mScrollAreaOffset;
}
- @Override
- public void fillInLogContainerData(ItemInfo childInfo, LauncherLogProto.Target child,
- ArrayList<LauncherLogProto.Target> targets) {
- child.gridX = childInfo.cellX;
- child.gridY = childInfo.cellY;
- child.pageIndex = mContent.getCurrentPage();
-
- LauncherLogProto.Target target = newContainerTarget(LauncherLogProto.ContainerType.FOLDER);
- target.pageIndex = mInfo.screenId;
- target.gridX = mInfo.cellX;
- target.gridY = mInfo.cellY;
- targets.add(target);
-
- // continue to parent
- if (mInfo.container == CONTAINER_HOTSEAT) {
- mLauncher.getHotseat().fillInLogContainerData(mInfo, target, targets);
- } else {
- mLauncher.getWorkspace().fillInLogContainerData(mInfo, target, targets);
- }
- }
-
private class OnScrollHintListener implements OnAlarmListener {
private final DragObject mDragObject;
@@ -1589,17 +1569,6 @@
return getOpenView(launcher, TYPE_FOLDER);
}
- @Override
- public void logActionCommand(int command) {
- mLauncher.getUserEventDispatcher().logActionCommand(
- command, getFolderIcon(), getLogContainerType());
- }
-
- @Override
- public int getLogContainerType() {
- return LauncherLogProto.ContainerType.FOLDER;
- }
-
/**
* Navigation bar back key or hardware input back key has been issued.
*/
diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
index cca9836..0f1432a 100644
--- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
+++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
@@ -19,6 +19,7 @@
import static android.view.View.MeasureSpec.makeMeasureSpec;
import static android.view.View.VISIBLE;
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
import static com.android.launcher3.config.FeatureFlags.ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER;
import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems;
import static com.android.launcher3.model.ModelUtils.getMissingHotseatRanks;
@@ -72,12 +73,12 @@
import com.android.launcher3.model.AllAppsList;
import com.android.launcher3.model.BgDataModel;
import com.android.launcher3.model.BgDataModel.Callbacks;
+import com.android.launcher3.model.BgDataModel.FixedContainerItems;
import com.android.launcher3.model.LoaderResults;
import com.android.launcher3.model.LoaderTask;
import com.android.launcher3.model.ModelDelegate;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.model.WidgetsModel;
-import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
@@ -95,6 +96,7 @@
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -467,12 +469,14 @@
}
IntArray ranks = getMissingHotseatRanks(currentWorkspaceItems,
mIdp.numHotseatIcons);
- int count = Math.min(ranks.size(), workspaceResult.mCachedPredictedItems.size());
+ List<ItemInfo> predictions = workspaceResult.mHotseatPredictions == null
+ ? Collections.emptyList() : workspaceResult.mHotseatPredictions.items;
+ int count = Math.min(ranks.size(), predictions.size());
for (int i = 0; i < count; i++) {
- AppInfo appInfo = workspaceResult.mCachedPredictedItems.get(i);
int rank = ranks.get(i);
- WorkspaceItemInfo itemInfo = new WorkspaceItemInfo(appInfo);
- itemInfo.container = Favorites.CONTAINER_HOTSEAT_PREDICTION;
+ WorkspaceItemInfo itemInfo =
+ new WorkspaceItemInfo((WorkspaceItemInfo) predictions.get(i));
+ itemInfo.container = CONTAINER_HOTSEAT_PREDICTION;
itemInfo.rank = rank;
itemInfo.cellX = mHotseat.getCellXFromOrder(rank);
itemInfo.cellY = mHotseat.getCellYFromOrder(rank);
@@ -569,8 +573,7 @@
return null;
}
- return new WorkspaceResult(mBgDataModel.workspaceItems, mBgDataModel.appWidgets,
- mBgDataModel.cachedPredictedItems, mBgDataModel.widgetsModel, null);
+ return new WorkspaceResult(mBgDataModel, mBgDataModel.widgetsModel, null);
}
}
@@ -594,11 +597,10 @@
}
@Override
- public WorkspaceResult call() throws Exception {
+ public WorkspaceResult call() {
List<ShortcutInfo> allShortcuts = new ArrayList<>();
loadWorkspace(allShortcuts, LauncherSettings.Favorites.PREVIEW_CONTENT_URI);
- return new WorkspaceResult(mBgDataModel.workspaceItems, mBgDataModel.appWidgets,
- mBgDataModel.cachedPredictedItems, null, mWidgetProvidersMap);
+ return new WorkspaceResult(mBgDataModel, null, mWidgetProvidersMap);
}
}
@@ -618,17 +620,16 @@
private static class WorkspaceResult {
private final ArrayList<ItemInfo> mWorkspaceItems;
private final ArrayList<LauncherAppWidgetInfo> mAppWidgets;
- private final ArrayList<AppInfo> mCachedPredictedItems;
+ private final FixedContainerItems mHotseatPredictions;
private final WidgetsModel mWidgetsModel;
private final Map<ComponentKey, AppWidgetProviderInfo> mWidgetProvidersMap;
- private WorkspaceResult(ArrayList<ItemInfo> workspaceItems,
- ArrayList<LauncherAppWidgetInfo> appWidgets,
- ArrayList<AppInfo> cachedPredictedItems, WidgetsModel widgetsModel,
+ private WorkspaceResult(BgDataModel dataModel,
+ WidgetsModel widgetsModel,
Map<ComponentKey, AppWidgetProviderInfo> widgetProviderInfoMap) {
- mWorkspaceItems = workspaceItems;
- mAppWidgets = appWidgets;
- mCachedPredictedItems = cachedPredictedItems;
+ mWorkspaceItems = dataModel.workspaceItems;
+ mAppWidgets = dataModel.appWidgets;
+ mHotseatPredictions = dataModel.extraItems.get(CONTAINER_HOTSEAT_PREDICTION);
mWidgetsModel = widgetsModel;
mWidgetProvidersMap = widgetProviderInfoMap;
}
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index 2282339..ec1c3ef 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -316,7 +316,13 @@
LAUNCHER_NAVIGATION_MODE_GESTURE_BUTTON(625),
@UiEvent(doc = "User tapped on image content in Overview Select mode.")
- LAUNCHER_SELECT_MODE_IMAGE(627);
+ LAUNCHER_SELECT_MODE_IMAGE(627),
+
+ @UiEvent(doc = "A folder was replaced by a single item")
+ LAUNCHER_FOLDER_CONVERTED_TO_ICON(628),
+
+ @UiEvent(doc = "A hotseat prediction item was pinned")
+ LAUNCHER_HOTSEAT_PREDICTION_PINNED(629);
// ADD MORE
diff --git a/src/com/android/launcher3/logging/UserEventDispatcher.java b/src/com/android/launcher3/logging/UserEventDispatcher.java
index 31a81b8..a40cc26 100644
--- a/src/com/android/launcher3/logging/UserEventDispatcher.java
+++ b/src/com/android/launcher3/logging/UserEventDispatcher.java
@@ -19,26 +19,21 @@
import static com.android.launcher3.logging.LoggerUtils.newAction;
import static com.android.launcher3.logging.LoggerUtils.newCommandAction;
import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
-import static com.android.launcher3.logging.LoggerUtils.newControlTarget;
import static com.android.launcher3.logging.LoggerUtils.newDropTarget;
import static com.android.launcher3.logging.LoggerUtils.newItemTarget;
import static com.android.launcher3.logging.LoggerUtils.newLauncherEvent;
import static com.android.launcher3.logging.LoggerUtils.newTarget;
import static com.android.launcher3.logging.LoggerUtils.newTouchAction;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.ControlType;
import static com.android.launcher3.userevent.nano.LauncherLogProto.ItemType;
import static com.android.launcher3.userevent.nano.LauncherLogProto.TipType;
import static java.util.Optional.ofNullable;
-import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
-import android.os.Process;
import android.os.SystemClock;
-import android.os.UserHandle;
import android.util.Log;
import android.view.View;
@@ -54,7 +49,6 @@
import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
import com.android.launcher3.userevent.nano.LauncherLogProto.LauncherEvent;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
-import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.InstantAppResolver;
import com.android.launcher3.util.LogConfig;
import com.android.launcher3.util.ResourceBasedOverride;
@@ -101,7 +95,7 @@
*
* @return whether container data was added.
*/
- public boolean fillLogContainer(@Nullable View v, Target child,
+ private boolean fillLogContainer(@Nullable View v, Target child,
@Nullable ArrayList<Target> targets) {
LogContainerProvider firstParent = StatsLogUtils.getLaunchProviderRecursive(v);
if (v == null || !(v.getTag() instanceof ItemInfo) || firstParent == null) {
@@ -125,55 +119,6 @@
private boolean mAppOrTaskLaunch;
private boolean mPreviousHomeGesture;
- // APP_ICON SHORTCUT WIDGET
- // --------------------------------------------------------------
- // packageNameHash required optional required
- // componentNameHash required required
- // intentHash required
- // --------------------------------------------------------------
-
- @Deprecated
- public void logAppLaunch(View v, Intent intent, @Nullable UserHandle userHandle) {
- Target itemTarget = newItemTarget(v, mInstantAppResolver);
- Action action = newTouchAction(Action.Touch.TAP);
- ArrayList<Target> targets = makeTargetsList(itemTarget);
- if (fillLogContainer(v, itemTarget, targets)) {
- onFillInLogContainerData((ItemInfo) v.getTag(), itemTarget, targets);
- fillIntentInfo(itemTarget, intent, userHandle);
- }
- LauncherEvent event = newLauncherEvent(action, targets);
- dispatchUserEvent(event, intent);
- mAppOrTaskLaunch = true;
- }
-
- /**
- * Placeholder method.
- */
- public void logActionTip(int actionType, int viewType) {
- }
-
- @Deprecated
- public void logTaskLaunchOrDismiss(int action, int direction, int taskIndex,
- ComponentKey componentKey) {
- LauncherEvent event = newLauncherEvent(newTouchAction(action), // TAP or SWIPE or FLING
- newTarget(Target.Type.ITEM));
- if (action == Action.Touch.SWIPE || action == Action.Touch.FLING) {
- // Direction DOWN means the task was launched, UP means it was dismissed.
- event.action.dir = direction;
- }
- event.srcTarget[0].itemType = ItemType.TASK;
- event.srcTarget[0].pageIndex = taskIndex;
- fillComponentInfo(event.srcTarget[0], componentKey.componentName);
- dispatchUserEvent(event, null);
- mAppOrTaskLaunch = true;
- }
-
- protected void fillIntentInfo(Target target, Intent intent, @Nullable UserHandle userHandle) {
- target.intentHash = intent.hashCode();
- target.isWorkApp = userHandle != null && !userHandle.equals(Process.myUserHandle());
- fillComponentInfo(target, intent.getComponent());
- }
-
private void fillComponentInfo(Target target, ComponentName cn) {
if (cn != null) {
target.packageNameHash = (mUuidStr + cn.getPackageName()).hashCode();
@@ -181,22 +126,6 @@
}
}
- public void logNotificationLaunch(View v, PendingIntent intent) {
- LauncherEvent event = newLauncherEvent(newTouchAction(Action.Touch.TAP),
- newItemTarget(v, mInstantAppResolver), newTarget(Target.Type.CONTAINER));
- Target itemTarget = newItemTarget(v, mInstantAppResolver);
- ArrayList<Target> targets = makeTargetsList(itemTarget);
-
- if (fillLogContainer(v, itemTarget, targets)) {
- itemTarget.packageNameHash = (mUuidStr + intent.getCreatorPackage()).hashCode();
- }
- dispatchUserEvent(event, null);
- }
-
- public void logActionCommand(int command, Target srcTarget) {
- logActionCommand(command, srcTarget, null);
- }
-
public void logActionCommand(int command, int srcContainerType, int dstContainerType) {
logActionCommand(command, newContainerTarget(srcContainerType),
dstContainerType >= 0 ? newContainerTarget(dstContainerType) : null);
@@ -227,25 +156,6 @@
dispatchUserEvent(event, null);
}
- /**
- * TODO: Make this function work when a container view is passed as the 2nd param.
- */
- public void logActionCommand(int command, View itemView, int srcContainerType) {
- LauncherEvent event = newLauncherEvent(newCommandAction(command),
- newItemTarget(itemView, mInstantAppResolver), newTarget(Target.Type.CONTAINER));
-
- Target itemTarget = newItemTarget(itemView, mInstantAppResolver);
- ArrayList<Target> targets = makeTargetsList(itemTarget);
-
- if (fillLogContainer(itemView, itemTarget, targets)) {
- // TODO: Remove the following two lines once fillInLogContainerData can take in a
- // container view.
- itemTarget.type = Target.Type.CONTAINER;
- itemTarget.containerType = srcContainerType;
- }
- dispatchUserEvent(event, null);
- }
-
public void logActionOnControl(int action, int controlType) {
logActionOnControl(action, controlType, null);
}
@@ -332,7 +242,6 @@
event.srcTarget[0].spanX = downX;
event.srcTarget[0].spanY = downY;
dispatchUserEvent(event, null);
- resetElapsedContainerMillis("state changed");
}
public void logActionOnItem(int action, int dir, int itemType) {
@@ -386,7 +295,6 @@
ArrayList<Target> targets = makeTargetsList(child);
fillLogContainer(icon, child, targets);
dispatchUserEvent(newLauncherEvent(newTouchAction(Action.Touch.TAP), targets), null);
- resetElapsedContainerMillis("deep shortcut open");
}
public void logDragNDrop(DropTarget.DragObject dragObj, View dropTargetAsView) {
@@ -397,7 +305,7 @@
Target destChild = newItemTarget(dragObj.originalDragInfo, mInstantAppResolver);
ArrayList<Target> destTargets = makeTargetsList(destChild);
- dragObj.dragSource.fillInLogContainerData(dragObj.originalDragInfo, srcChild, srcTargets);
+ //dragObj.dragSource.fillInLogContainerData(dragObj.originalDragInfo, srcChild, srcTargets);
if (dropTargetAsView instanceof LogContainerProvider) {
((LogContainerProvider) dropTargetAsView).fillInLogContainerData(dragObj.dragInfo,
destChild, destTargets);
@@ -414,35 +322,6 @@
dispatchUserEvent(event, null);
}
- public void logActionBack(boolean completed, int downX, int downY, boolean isButton,
- boolean gestureSwipeLeft, int containerType) {
- int actionTouch = isButton ? Action.Touch.TAP : Action.Touch.SWIPE;
- Action action = newCommandAction(actionTouch);
- action.command = Action.Command.BACK;
- action.dir = isButton ? Action.Direction.NONE :
- gestureSwipeLeft ? Action.Direction.LEFT : Action.Direction.RIGHT;
- Target target = newControlTarget(isButton ? ControlType.BACK_BUTTON :
- ControlType.BACK_GESTURE);
- target.spanX = downX;
- target.spanY = downY;
- target.cardinality = completed ? 1 : 0;
- LauncherEvent event = newLauncherEvent(action, target, newContainerTarget(containerType));
-
- dispatchUserEvent(event, null);
- }
-
- /**
- * Currently logs following containers: workspace, allapps, widget tray.
- */
- public final void resetElapsedContainerMillis(String reason) {
- mElapsedContainerMillis = SystemClock.uptimeMillis();
- if (!IS_VERBOSE) {
- return;
- }
- Log.d(TAG, "resetElapsedContainerMillis reason=" + reason);
-
- }
-
public final void startSession() {
mSessionStarted = true;
mElapsedSessionMillis = SystemClock.uptimeMillis();
diff --git a/src/com/android/launcher3/model/BaseLoaderResults.java b/src/com/android/launcher3/model/BaseLoaderResults.java
index 586333f..5c85bab 100644
--- a/src/com/android/launcher3/model/BaseLoaderResults.java
+++ b/src/com/android/launcher3/model/BaseLoaderResults.java
@@ -17,7 +17,6 @@
package com.android.launcher3.model;
import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems;
-import static com.android.launcher3.model.ModelUtils.getMissingHotseatRanks;
import static com.android.launcher3.model.ModelUtils.sortWorkspaceItemsSpatially;
import android.util.Log;
@@ -206,9 +205,6 @@
mExtraItems.forEach(item ->
executeCallbacksTask(c -> c.bindExtraContainerItems(item), mainExecutor));
- // Locate available spots for prediction using currentWorkspaceItems
- IntArray gaps = getMissingHotseatRanks(currentWorkspaceItems, idp.numHotseatIcons);
- bindPredictedItems(gaps, mainExecutor);
// In case of validFirstPage, only bind the first screen, and defer binding the
// remaining screens after first onDraw (and an optional the fade animation whichever
// happens later).
@@ -261,11 +257,6 @@
}
}
- private void bindPredictedItems(IntArray ranks, final Executor executor) {
- ArrayList<AppInfo> items = new ArrayList<>(mBgDataModel.cachedPredictedItems);
- executeCallbacksTask(c -> c.bindPredictedItems(items, ranks), executor);
- }
-
protected void executeCallbacksTask(CallbackTask task, Executor executor) {
executor.execute(() -> {
if (mMyBindingId != mBgDataModel.lastBindId) {
diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java
index 7e45021..49b40ed 100644
--- a/src/com/android/launcher3/model/BgDataModel.java
+++ b/src/com/android/launcher3/model/BgDataModel.java
@@ -103,11 +103,6 @@
public final IntSparseArrayMap<FixedContainerItems> extraItems = new IntSparseArrayMap<>();
/**
- * List of all cached predicted items visible on home screen
- */
- public final ArrayList<AppInfo> cachedPredictedItems = new ArrayList<>();
-
- /**
* Maps all launcher activities to counts of their shortcuts.
*/
public final HashMap<ComponentKey, Integer> deepShortcutMap = new HashMap<>();
@@ -297,8 +292,7 @@
.filter(wi -> wi.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT)
.map(ShortcutKey::fromItemInfo),
// Pending shortcuts
- ItemInstallQueue.INSTANCE.get(context).getPendingShortcuts()
- .stream().filter(si -> si.user.equals(user)))
+ ItemInstallQueue.INSTANCE.get(context).getPendingShortcuts(user))
.collect(groupingBy(ShortcutKey::getPackageName,
mapping(ShortcutKey::getId, Collectors.toSet())));
@@ -471,10 +465,5 @@
default void bindExtraContainerItems(FixedContainerItems item) { }
void bindAllApplications(AppInfo[] apps, int flags);
-
- /**
- * Binds predicted appInfos at at available prediction slots.
- */
- void bindPredictedItems(List<AppInfo> appInfos, IntArray ranks);
}
}
diff --git a/src/com/android/launcher3/model/ItemInstallQueue.java b/src/com/android/launcher3/model/ItemInstallQueue.java
index 6238db3..5e48a0f 100644
--- a/src/com/android/launcher3/model/ItemInstallQueue.java
+++ b/src/com/android/launcher3/model/ItemInstallQueue.java
@@ -21,7 +21,6 @@
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
-import static com.android.launcher3.LauncherSettings.Favorites.PROFILE_ID;
import static com.android.launcher3.model.data.AppInfo.makeLaunchIntent;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
@@ -30,11 +29,9 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.SharedPreferences;
import android.content.pm.LauncherActivityInfo;
import android.content.pm.LauncherApps;
import android.content.pm.ShortcutInfo;
-import android.os.Process;
import android.os.UserHandle;
import android.util.Log;
import android.util.Pair;
@@ -47,27 +44,19 @@
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherAppWidgetProviderInfo;
import com.android.launcher3.LauncherSettings.Favorites;
-import com.android.launcher3.Utilities;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.pm.UserCache;
import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.shortcuts.ShortcutRequest;
import com.android.launcher3.util.MainThreadInitializedObject;
+import com.android.launcher3.util.PersistedItemArray;
import com.android.launcher3.util.Preconditions;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.json.JSONStringer;
-
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Collection;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
-import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
/**
* Class to maintain a queue of pending items to be added to the workspace.
@@ -79,7 +68,6 @@
public static final int FLAG_DRAG_AND_DROP = 4;
private static final String TAG = "InstallShortcutReceiver";
- private static final boolean DBG = false;
// The set of shortcuts that are pending install
private static final String APPS_PENDING_INSTALL = "apps_to_install";
@@ -90,24 +78,34 @@
public static MainThreadInitializedObject<ItemInstallQueue> INSTANCE =
new MainThreadInitializedObject<>(ItemInstallQueue::new);
+ private final PersistedItemArray<PendingInstallShortcutInfo> mStorage =
+ new PersistedItemArray<>(APPS_PENDING_INSTALL);
private final Context mContext;
// Determines whether to defer installing shortcuts immediately until
// processAllPendingInstalls() is called.
private int mInstallQueueDisabledFlags = 0;
+ // Only accessed on worker thread
+ private List<PendingInstallShortcutInfo> mItems;
+
private ItemInstallQueue(Context context) {
mContext = context;
}
@WorkerThread
+ private void ensureQueueLoaded() {
+ Preconditions.assertWorkerThread();
+ if (mItems == null) {
+ mItems = mStorage.read(mContext, this::decode);
+ }
+ }
+
+ @WorkerThread
private void addToQueue(PendingInstallShortcutInfo info) {
- String encoded = info.encodeToString(mContext);
- SharedPreferences prefs = Utilities.getPrefs(mContext);
- Set<String> strings = prefs.getStringSet(APPS_PENDING_INSTALL, null);
- strings = (strings != null) ? new HashSet<>(strings) : new HashSet<>(1);
- strings.add(encoded);
- prefs.edit().putStringSet(APPS_PENDING_INSTALL, strings).apply();
+ ensureQueueLoaded();
+ mItems.add(info);
+ mStorage.write(mContext, mItems);
}
@WorkerThread
@@ -117,28 +115,21 @@
// Launcher not loaded
return;
}
-
- ArrayList<Pair<ItemInfo, Object>> installQueue = new ArrayList<>();
- SharedPreferences prefs = Utilities.getPrefs(mContext);
- Set<String> strings = prefs.getStringSet(APPS_PENDING_INSTALL, null);
- if (DBG) Log.d(TAG, "Getting and clearing APPS_PENDING_INSTALL: " + strings);
- if (strings == null) {
+ ensureQueueLoaded();
+ if (mItems.isEmpty()) {
return;
}
- for (String encoded : strings) {
- PendingInstallShortcutInfo info = decode(encoded, mContext);
- if (info == null) {
- continue;
- }
+ List<Pair<ItemInfo, Object>> installQueue = mItems.stream()
+ .map(info -> info.getItemInfo(mContext))
+ .collect(Collectors.toList());
- // Generate a shortcut info to add into the model
- installQueue.add(info.getItemInfo(mContext));
- }
- prefs.edit().remove(APPS_PENDING_INSTALL).apply();
+ // Add the items and clear queue
if (!installQueue.isEmpty()) {
launcher.getModel().addAndBindAddedWorkspaceItems(installQueue);
}
+ mItems.clear();
+ mStorage.getFile(mContext).delete();
}
/**
@@ -149,33 +140,11 @@
if (packageNames.isEmpty()) {
return;
}
- Preconditions.assertWorkerThread();
-
- SharedPreferences sp = Utilities.getPrefs(mContext);
- Set<String> strings = sp.getStringSet(APPS_PENDING_INSTALL, null);
- if (DBG) {
- Log.d(TAG, "APPS_PENDING_INSTALL: " + strings
- + ", removing packages: " + packageNames);
+ ensureQueueLoaded();
+ if (mItems.removeIf(item ->
+ item.user.equals(user) && packageNames.contains(getIntentPackage(item.intent)))) {
+ mStorage.write(mContext, mItems);
}
- if (strings == null || ((Collection) strings).isEmpty()) {
- return;
- }
- Set<String> newStrings = new HashSet<>(strings);
- Iterator<String> newStringsIter = newStrings.iterator();
- while (newStringsIter.hasNext()) {
- String encoded = newStringsIter.next();
- try {
- Decoder decoder = new Decoder(encoded, mContext);
- if (packageNames.contains(getIntentPackage(decoder.intent))
- && user.equals(decoder.user)) {
- newStringsIter.remove();
- }
- } catch (JSONException | URISyntaxException e) {
- Log.d(TAG, "Exception reading shortcut to add: " + e);
- newStringsIter.remove();
- }
- }
- sp.edit().putStringSet(APPS_PENDING_INSTALL, newStrings).apply();
}
/**
@@ -200,28 +169,14 @@
}
/**
- * Returns all pending shorts in the queue
+ * Returns a stream of all pending shortcuts in the queue
*/
@WorkerThread
- public HashSet<ShortcutKey> getPendingShortcuts() {
- HashSet<ShortcutKey> result = new HashSet<>();
-
- Set<String> strings = Utilities.getPrefs(mContext).getStringSet(APPS_PENDING_INSTALL, null);
- if (strings == null || ((Collection) strings).isEmpty()) {
- return result;
- }
-
- for (String encoded : strings) {
- try {
- Decoder decoder = new Decoder(encoded, mContext);
- if (decoder.optInt(Favorites.ITEM_TYPE, -1) == ITEM_TYPE_DEEP_SHORTCUT) {
- result.add(ShortcutKey.fromIntent(decoder.intent, decoder.user));
- }
- } catch (JSONException | URISyntaxException e) {
- Log.d(TAG, "Exception reading shortcut to add: " + e);
- }
- }
- return result;
+ public Stream<ShortcutKey> getPendingShortcuts(UserHandle user) {
+ ensureQueueLoaded();
+ return mItems.stream()
+ .filter(item -> item.itemType == ITEM_TYPE_DEEP_SHORTCUT && user.equals(item.user))
+ .map(item -> ShortcutKey.fromIntent(item.intent, user));
}
private void queuePendingShortcutInfo(PendingInstallShortcutInfo info) {
@@ -293,19 +248,9 @@
providerInfo = info;
}
- public String encodeToString(Context context) {
- try {
- return new JSONStringer()
- .object()
- .key(Favorites.ITEM_TYPE).value(itemType)
- .key(Favorites.INTENT).value(intent.toUri(0))
- .key(PROFILE_ID).value(
- UserCache.INSTANCE.get(context).getSerialNumberForUser(user))
- .endObject().toString();
- } catch (JSONException e) {
- Log.d(TAG, "Exception when adding shortcut: " + e);
- return null;
- }
+ @Override
+ public Intent getIntent() {
+ return intent;
}
public Pair<ItemInfo, Object> getItemInfo(Context context) {
@@ -365,55 +310,33 @@
? intent.getPackage() : intent.getComponent().getPackageName();
}
- private static PendingInstallShortcutInfo decode(String encoded, Context context) {
- try {
- Decoder decoder = new Decoder(encoded, context);
- switch (decoder.optInt(Favorites.ITEM_TYPE, -1)) {
- case Favorites.ITEM_TYPE_APPLICATION:
- return new PendingInstallShortcutInfo(
- decoder.intent.getPackage(), decoder.user);
- case Favorites.ITEM_TYPE_DEEP_SHORTCUT: {
- List<ShortcutInfo> si = ShortcutKey.fromIntent(decoder.intent, decoder.user)
- .buildRequest(context)
- .query(ShortcutRequest.ALL);
- if (si.isEmpty()) {
- return null;
- } else {
- return new PendingInstallShortcutInfo(si.get(0));
- }
+ private PendingInstallShortcutInfo decode(int itemType, UserHandle user, Intent intent) {
+ switch (itemType) {
+ case Favorites.ITEM_TYPE_APPLICATION:
+ return new PendingInstallShortcutInfo(intent.getPackage(), user);
+ case Favorites.ITEM_TYPE_DEEP_SHORTCUT: {
+ List<ShortcutInfo> si = ShortcutKey.fromIntent(intent, user)
+ .buildRequest(mContext)
+ .query(ShortcutRequest.ALL);
+ if (si.isEmpty()) {
+ return null;
+ } else {
+ return new PendingInstallShortcutInfo(si.get(0));
}
- case Favorites.ITEM_TYPE_APPWIDGET: {
- int widgetId = decoder.intent.getIntExtra(EXTRA_APPWIDGET_ID, 0);
- AppWidgetProviderInfo info =
- AppWidgetManager.getInstance(context).getAppWidgetInfo(widgetId);
- if (info == null || !info.provider.equals(decoder.intent.getComponent())
- || !info.getProfile().equals(decoder.user)) {
- return null;
- }
- return new PendingInstallShortcutInfo(info, widgetId);
- }
- default:
- Log.e(TAG, "Unknown item type");
}
- } catch (JSONException | URISyntaxException e) {
- Log.d(TAG, "Exception reading shortcut to add: " + e);
+ case Favorites.ITEM_TYPE_APPWIDGET: {
+ int widgetId = intent.getIntExtra(EXTRA_APPWIDGET_ID, 0);
+ AppWidgetProviderInfo info =
+ AppWidgetManager.getInstance(mContext).getAppWidgetInfo(widgetId);
+ if (info == null || !info.provider.equals(intent.getComponent())
+ || !info.getProfile().equals(user)) {
+ return null;
+ }
+ return new PendingInstallShortcutInfo(info, widgetId);
+ }
+ default:
+ Log.e(TAG, "Unknown item type");
}
return null;
}
-
- private static class Decoder extends JSONObject {
- public final Intent intent;
- public final UserHandle user;
-
- private Decoder(String encoded, Context context) throws JSONException, URISyntaxException {
- super(encoded);
- intent = Intent.parseUri(getString(Favorites.INTENT), 0);
- user = has(PROFILE_ID)
- ? UserCache.INSTANCE.get(context).getUserForSerialNumber(getLong(PROFILE_ID))
- : Process.myUserHandle();
- if (user == null || intent == null) {
- throw new JSONException("Invalid data");
- }
- }
- }
}
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index 1dd8c11..983ec0c 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -48,8 +48,6 @@
import android.util.LongSparseArray;
import android.util.TimingLogger;
-import androidx.annotation.WorkerThread;
-
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel;
import com.android.launcher3.LauncherSettings;
@@ -190,13 +188,13 @@
try (LauncherModel.LoaderTransaction transaction = mApp.getModel().beginLoader(this)) {
List<ShortcutInfo> allShortcuts = new ArrayList<>();
loadWorkspace(allShortcuts);
- loadCachedPredictions();
logger.addSplit("loadWorkspace");
verifyNotStopped();
mResults.bindWorkspace();
logger.addSplit("bindWorkspace");
+ mModelDelegate.workspaceLoadComplete();
// Notify the installer packages of packages with active installs on the first screen.
sendFirstScreenActiveInstallsBroadcast();
logger.addSplit("sendFirstScreenActiveInstallsBroadcast");
@@ -839,24 +837,6 @@
}
}
- @WorkerThread
- private void loadCachedPredictions() {
- synchronized (mBgDataModel) {
- List<ComponentKey> componentKeys =
- mApp.getPredictionModel().getPredictionComponentKeys();
- List<LauncherActivityInfo> l;
- mBgDataModel.cachedPredictedItems.clear();
- for (ComponentKey key : componentKeys) {
- l = mLauncherApps.getActivityList(key.componentName.getPackageName(), key.user);
- if (l.size() == 0) continue;
- AppInfo info = new AppInfo(l.get(0), key.user,
- mUserManagerState.isUserQuiet(key.user));
- mBgDataModel.cachedPredictedItems.add(info);
- mIconCache.getTitleAndIcon(info, false);
- }
- }
- }
-
private void sanitizeData() {
Context context = mApp.getContext();
if (mItemsDeleted) {
@@ -900,14 +880,6 @@
PackageInstallInfo.fromInstallingState(info));
}
}
- for (AppInfo item : mBgDataModel.cachedPredictedItems) {
- List<LauncherActivityInfo> l = mLauncherApps.getActivityList(
- item.componentName.getPackageName(), item.user);
- for (LauncherActivityInfo info : l) {
- boolean quietMode = mUserManagerState.isUserQuiet(item.user);
- mBgAllAppsList.add(new AppInfo(info, item.user, quietMode), info);
- }
- }
mBgAllAppsList.setFlags(FLAG_QUIET_MODE_ENABLED,
mUserManagerState.isAnyProfileQuietModeEnabled());
diff --git a/src/com/android/launcher3/model/ModelDelegate.java b/src/com/android/launcher3/model/ModelDelegate.java
index 53e8a86..3ed8809 100644
--- a/src/com/android/launcher3/model/ModelDelegate.java
+++ b/src/com/android/launcher3/model/ModelDelegate.java
@@ -72,6 +72,12 @@
public void loadItems(UserManagerState ums, Map<ShortcutKey, ShortcutInfo> pinnedShortcuts) { }
/**
+ * Called during loader after workspace loading is complete
+ */
+ @WorkerThread
+ public void workspaceLoadComplete() { }
+
+ /**
* Called when the delegate is no loner needed
*/
@WorkerThread
diff --git a/src/com/android/launcher3/model/PredictionModel.java b/src/com/android/launcher3/model/PredictionModel.java
deleted file mode 100644
index cb3903d..0000000
--- a/src/com/android/launcher3/model/PredictionModel.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2020 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.launcher3.model;
-
-import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.os.UserHandle;
-
-import androidx.annotation.AnyThread;
-import androidx.annotation.WorkerThread;
-
-import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.pm.UserCache;
-import com.android.launcher3.util.ComponentKey;
-import com.android.launcher3.util.Preconditions;
-import com.android.launcher3.util.ResourceBasedOverride;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Model Helper for app predictions
- */
-public class PredictionModel implements ResourceBasedOverride {
-
- private static final String CACHED_ITEMS_KEY = "predicted_item_keys";
- private static final int MAX_CACHE_ITEMS = 5;
-
- protected Context mContext;
- private SharedPreferences mDevicePrefs;
- private UserCache mUserCache;
-
-
- /**
- * Retrieve instance of this object that can be overridden in runtime based on the build
- * variant of the application.
- */
- public static PredictionModel newInstance(Context context) {
- PredictionModel model = Overrides.getObject(PredictionModel.class, context,
- R.string.prediction_model_class);
- model.init(context);
- return model;
- }
-
- protected void init(Context context) {
- mContext = context;
- mDevicePrefs = Utilities.getDevicePrefs(mContext);
- mUserCache = UserCache.INSTANCE.get(mContext);
-
- }
-
- /**
- * Formats and stores a list of component key in device preferences.
- */
- @AnyThread
- public void cachePredictionComponentKeys(List<ComponentKey> componentKeys) {
- MODEL_EXECUTOR.execute(() -> {
- LauncherAppState appState = LauncherAppState.getInstance(mContext);
- StringBuilder builder = new StringBuilder();
- int count = Math.min(componentKeys.size(), MAX_CACHE_ITEMS);
- for (int i = 0; i < count; i++) {
- builder.append(serializeComponentKeyToString(componentKeys.get(i)));
- builder.append("\n");
- }
- if (componentKeys.isEmpty() /* should invalidate loader items */) {
- appState.getModel().enqueueModelUpdateTask(new BaseModelUpdateTask() {
- @Override
- public void execute(LauncherAppState app, BgDataModel model, AllAppsList apps) {
- model.cachedPredictedItems.clear();
- }
- });
- }
- mDevicePrefs.edit().putString(CACHED_ITEMS_KEY, builder.toString()).apply();
- });
- }
-
- /**
- * parses and returns ComponentKeys saved by
- * {@link PredictionModel#cachePredictionComponentKeys(List)}
- */
- @WorkerThread
- public List<ComponentKey> getPredictionComponentKeys() {
- Preconditions.assertWorkerThread();
- ArrayList<ComponentKey> items = new ArrayList<>();
- String cachedBlob = mDevicePrefs.getString(CACHED_ITEMS_KEY, "");
- for (String line : cachedBlob.split("\n")) {
- ComponentKey key = getComponentKeyFromSerializedString(line);
- if (key != null) {
- items.add(key);
- }
-
- }
- return items;
- }
-
- private String serializeComponentKeyToString(ComponentKey componentKey) {
- long userSerialNumber = mUserCache.getSerialNumberForUser(componentKey.user);
- return componentKey.componentName.flattenToString() + "#" + userSerialNumber;
- }
-
- private ComponentKey getComponentKeyFromSerializedString(String str) {
- int sep = str.indexOf('#');
- if (sep < 0 || (sep + 1) >= str.length()) {
- return null;
- }
- ComponentName componentName = ComponentName.unflattenFromString(str.substring(0, sep));
- if (componentName == null) {
- return null;
- }
- try {
- long serialNumber = Long.parseLong(str.substring(sep + 1));
- UserHandle userHandle = mUserCache.getUserForSerialNumber(serialNumber);
- return userHandle != null ? new ComponentKey(componentName, userHandle) : null;
- } catch (NumberFormatException ex) {
- return null;
- }
- }
-}
diff --git a/src/com/android/launcher3/notification/NotificationInfo.java b/src/com/android/launcher3/notification/NotificationInfo.java
index 835f72d..80eeb22 100644
--- a/src/com/android/launcher3/notification/NotificationInfo.java
+++ b/src/com/android/launcher3/notification/NotificationInfo.java
@@ -106,7 +106,6 @@
view, 0, 0, view.getWidth(), view.getHeight()).toBundle();
try {
intent.send(null, 0, null, null, null, null, activityOptions);
- launcher.getUserEventDispatcher().logNotificationLaunch(view, intent);
launcher.getStatsLogManager().logger().withItemInfo(mItemInfo)
.log(LAUNCHER_NOTIFICATION_LAUNCH_TAP);
} catch (PendingIntent.CanceledException e) {
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index 896fb18..26b32b8 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -20,12 +20,9 @@
import static com.android.launcher3.Utilities.squaredHypot;
import static com.android.launcher3.Utilities.squaredTouchSlop;
import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
-import static com.android.launcher3.notification.NotificationMainView.NOTIFICATION_ITEM_INFO;
import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS;
import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS_IF_NOTIFICATIONS;
import static com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.ItemType;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.Target;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
import android.animation.AnimatorSet;
@@ -147,17 +144,6 @@
return (type & TYPE_ACTION_POPUP) != 0;
}
- @Override
- public void logActionCommand(int command) {
- mLauncher.getUserEventDispatcher().logActionCommand(
- command, mOriginalIcon, getLogContainerType());
- }
-
- @Override
- public int getLogContainerType() {
- return ContainerType.DEEPSHORTCUTS;
- }
-
public OnClickListener getItemClickListener() {
return (view) -> {
mLauncher.getItemOnClickListener().onClick(view);
@@ -496,18 +482,6 @@
}
@Override
- public void fillInLogContainerData(ItemInfo childInfo, Target child,
- ArrayList<Target> parents) {
- if (childInfo == NOTIFICATION_ITEM_INFO) {
- child.itemType = ItemType.NOTIFICATION;
- } else {
- child.itemType = ItemType.DEEPSHORTCUT;
- child.rank = childInfo.rank;
- }
- parents.add(newContainerTarget(ContainerType.DEEPSHORTCUTS));
- }
-
- @Override
protected void onCreateCloseAnimation(AnimatorSet anim) {
// Animate original icon's text back in.
anim.play(mOriginalIcon.createTextAlphaAnimator(true /* fadeIn */));
diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
index 31c3014..2b04365 100644
--- a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
+++ b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
@@ -197,9 +197,6 @@
public void bindItems(List<ItemInfo> shortcuts, boolean forceAnimateIcons) { }
@Override
- public void bindPredictedItems(List<AppInfo> appInfos, IntArray ranks) { }
-
- @Override
public void bindScreens(IntArray orderedScreenIds) { }
@Override
diff --git a/src/com/android/launcher3/settings/SettingsActivity.java b/src/com/android/launcher3/settings/SettingsActivity.java
index ec3a467..922425f 100644
--- a/src/com/android/launcher3/settings/SettingsActivity.java
+++ b/src/com/android/launcher3/settings/SettingsActivity.java
@@ -44,6 +44,7 @@
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.model.WidgetsModel;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.util.SecureSettingsObserver;
@@ -171,6 +172,10 @@
protected boolean initPreference(Preference preference) {
switch (preference.getKey()) {
case NOTIFICATION_DOTS_PREFERENCE_KEY:
+ if (WidgetsModel.GO_DISABLE_NOTIFICATION_DOTS) {
+ return false;
+ }
+
// Listen to system notification dot settings while this UI is active.
mNotificationDotsObserver = newNotificationSettingsObserver(
getActivity(), (NotificationDotsPreference) preference);
diff --git a/src/com/android/launcher3/util/DisplayController.java b/src/com/android/launcher3/util/DisplayController.java
index e5c8441..355c949 100644
--- a/src/com/android/launcher3/util/DisplayController.java
+++ b/src/com/android/launcher3/util/DisplayController.java
@@ -50,7 +50,7 @@
private final ArrayList<DisplayListChangeListener> mListListeners = new ArrayList<>();
private DisplayController(Context context) {
- mDefaultDisplay = new DisplayHolder(context, DEFAULT_DISPLAY);
+ mDefaultDisplay = DisplayHolder.create(context, DEFAULT_DISPLAY);
DisplayManager dm = context.getSystemService(DisplayManager.class);
dm.registerDisplayListener(this, UI_HELPER_EXECUTOR.getHandler());
@@ -58,7 +58,11 @@
@Override
public final void onDisplayAdded(int displayId) {
- DisplayHolder holder = new DisplayHolder(mDefaultDisplay.mDisplayContext, displayId);
+ DisplayHolder holder = DisplayHolder.create(mDefaultDisplay.mDisplayContext, displayId);
+ if (holder == null) {
+ // Display is already removed by the time we dot this.
+ return;
+ }
synchronized (mOtherDisplays) {
mOtherDisplays.put(displayId, holder);
}
@@ -153,12 +157,8 @@
private final ArrayList<DisplayInfoChangeListener> mListeners = new ArrayList<>();
private DisplayController.Info mInfo;
- public DisplayHolder(Context context, int id) {
- DisplayManager dm = context.getSystemService(DisplayManager.class);
- // Use application context to create display context so that it can have its own
- // Resources.
- mDisplayContext = context.getApplicationContext()
- .createDisplayContext(dm.getDisplay(id));
+ private DisplayHolder(Context displayContext) {
+ mDisplayContext = displayContext;
// Note that the Display object must be obtained from DisplayManager which is
// associated to the display context, so the Display is isolated from Activity and
// Application to provide the actual state of device that excludes the additional
@@ -207,6 +207,17 @@
}
}
+ private static DisplayHolder create(Context context, int id) {
+ DisplayManager dm = context.getSystemService(DisplayManager.class);
+ Display display = dm.getDisplay(id);
+ if (display == null) {
+ return null;
+ }
+ // Use application context to create display context so that it can have its own
+ // Resources.
+ Context displayContext = context.getApplicationContext().createDisplayContext(display);
+ return new DisplayHolder(displayContext);
+ }
}
public static class Info {
diff --git a/src/com/android/launcher3/util/OnboardingPrefs.java b/src/com/android/launcher3/util/OnboardingPrefs.java
index 6e5e7d9..1b33197 100644
--- a/src/com/android/launcher3/util/OnboardingPrefs.java
+++ b/src/com/android/launcher3/util/OnboardingPrefs.java
@@ -44,7 +44,8 @@
*/
@StringDef(value = {
HOME_BOUNCE_SEEN,
- SHELF_BOUNCE_SEEN
+ SHELF_BOUNCE_SEEN,
+ HOTSEAT_LONGPRESS_TIP_SEEN
})
@Retention(RetentionPolicy.SOURCE)
public @interface EventBoolKey {}
diff --git a/src/com/android/launcher3/util/PersistedItemArray.java b/src/com/android/launcher3/util/PersistedItemArray.java
index ae20638..7ff2abb 100644
--- a/src/com/android/launcher3/util/PersistedItemArray.java
+++ b/src/com/android/launcher3/util/PersistedItemArray.java
@@ -68,8 +68,7 @@
*/
@WorkerThread
public void write(Context context, List<T> items) {
- AtomicFile file = new AtomicFile(context.getFileStreamPath(mFileName));
-
+ AtomicFile file = getFile(context);
FileOutputStream fos;
try {
fos = file.startWrite();
@@ -124,9 +123,7 @@
@WorkerThread
public List<T> read(Context context, ItemFactory<T> factory, LongFunction<UserHandle> userFn) {
List<T> result = new ArrayList<>();
- AtomicFile file = new AtomicFile(context.getFileStreamPath(mFileName));
-
- try (FileInputStream fis = file.openRead()) {
+ try (FileInputStream fis = getFile(context).openRead()) {
XmlPullParser parser = Xml.newPullParser();
parser.setInput(new InputStreamReader(fis, StandardCharsets.UTF_8));
@@ -167,6 +164,13 @@
}
/**
+ * Returns the underlying file used for persisting data
+ */
+ public AtomicFile getFile(Context context) {
+ return new AtomicFile(context.getFileStreamPath(mFileName));
+ }
+
+ /**
* Interface to create an ItemInfo during parsing
*/
public interface ItemFactory<T extends ItemInfo> {
diff --git a/src/com/android/launcher3/views/ArrowTipView.java b/src/com/android/launcher3/views/ArrowTipView.java
index b4a6b14..1f12a2f 100644
--- a/src/com/android/launcher3/views/ArrowTipView.java
+++ b/src/com/android/launcher3/views/ArrowTipView.java
@@ -87,10 +87,6 @@
}
@Override
- public void logActionCommand(int command) {
- }
-
- @Override
protected boolean isOfType(int type) {
return (type & TYPE_ON_BOARD_POPUP) != 0;
}
diff --git a/src/com/android/launcher3/views/FloatingSurfaceView.java b/src/com/android/launcher3/views/FloatingSurfaceView.java
index 9582232..011f6de 100644
--- a/src/com/android/launcher3/views/FloatingSurfaceView.java
+++ b/src/com/android/launcher3/views/FloatingSurfaceView.java
@@ -122,9 +122,6 @@
}
@Override
- public void logActionCommand(int command) { }
-
- @Override
protected boolean isOfType(int type) {
return (type & TYPE_ICON_SURFACE) != 0;
}
diff --git a/src/com/android/launcher3/views/HeroSearchResultView.java b/src/com/android/launcher3/views/HeroSearchResultView.java
index 10f3c41..7b2df80 100644
--- a/src/com/android/launcher3/views/HeroSearchResultView.java
+++ b/src/com/android/launcher3/views/HeroSearchResultView.java
@@ -40,9 +40,7 @@
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider;
import com.android.launcher3.touch.ItemLongClickListener;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
-import java.util.ArrayList;
import java.util.List;
/**
@@ -118,12 +116,6 @@
mBubbleTextView.setIconVisible(true);
}
- @Override
- public void fillInLogContainerData(ItemInfo childInfo, LauncherLogProto.Target child,
- ArrayList<LauncherLogProto.Target> parents) {
-
- }
-
private void setWillDrawIcon(boolean willDraw) {
mIconView.setVisibility(willDraw ? View.VISIBLE : View.INVISIBLE);
}
diff --git a/src/com/android/launcher3/views/ListenerView.java b/src/com/android/launcher3/views/ListenerView.java
index 3ef778b..6e3f0ce 100644
--- a/src/com/android/launcher3/views/ListenerView.java
+++ b/src/com/android/launcher3/views/ListenerView.java
@@ -85,11 +85,6 @@
}
@Override
- public void logActionCommand(int command) {
- // Users do not interact with FloatingIconView, so there is nothing to log here.
- }
-
- @Override
protected boolean isOfType(int type) {
return (type & TYPE_LISTENER) != 0;
}
diff --git a/src/com/android/launcher3/views/OptionsPopupView.java b/src/com/android/launcher3/views/OptionsPopupView.java
index 9ad2331..3ec20d5 100644
--- a/src/com/android/launcher3/views/OptionsPopupView.java
+++ b/src/com/android/launcher3/views/OptionsPopupView.java
@@ -108,11 +108,6 @@
}
@Override
- public void logActionCommand(int command) {
- // TODO:
- }
-
- @Override
protected boolean isOfType(int type) {
return (type & TYPE_OPTIONS_POPUP) != 0;
}
diff --git a/src/com/android/launcher3/views/ScrimView.java b/src/com/android/launcher3/views/ScrimView.java
index 7f0765b..77cec80 100644
--- a/src/com/android/launcher3/views/ScrimView.java
+++ b/src/com/android/launcher3/views/ScrimView.java
@@ -32,6 +32,7 @@
import com.android.launcher3.Insettable;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.uioverrides.WallpaperColorInfo;
import com.android.launcher3.uioverrides.WallpaperColorInfo.OnChangeListener;
import com.android.launcher3.util.Themes;
@@ -41,6 +42,7 @@
*/
public class ScrimView<T extends Launcher> extends View implements Insettable, OnChangeListener {
+ private static final float SCRIM_ALPHA = .75f;
protected final T mLauncher;
private final WallpaperColorInfo mWallpaperColorInfo;
protected final int mEndScrim;
@@ -59,7 +61,11 @@
super(context, attrs);
mLauncher = Launcher.cast(Launcher.getLauncher(context));
mWallpaperColorInfo = WallpaperColorInfo.INSTANCE.get(context);
- mEndScrim = Themes.getAttrColor(context, R.attr.allAppsScrimColor);
+ int endScrim = Themes.getAttrColor(context, R.attr.allAppsScrimColor);
+ if (FeatureFlags.ENABLE_DEVICE_SEARCH.get()) {
+ endScrim = ColorUtils.setAlphaComponent(endScrim, (int) (255 * SCRIM_ALPHA));
+ }
+ mEndScrim = endScrim;
mIsScrimDark = ColorUtils.calculateLuminance(mEndScrim) < 0.5f;
mMaxScrimAlpha = 0.7f;
diff --git a/src/com/android/launcher3/views/SearchSettingsRowView.java b/src/com/android/launcher3/views/SearchSettingsRowView.java
new file mode 100644
index 0000000..08c78ff
--- /dev/null
+++ b/src/com/android/launcher3/views/SearchSettingsRowView.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2020 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.launcher3.views;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.R;
+import com.android.launcher3.allapps.AllAppsGridAdapter;
+import com.android.launcher3.allapps.search.AllAppsSearchBarController;
+
+import java.util.ArrayList;
+
+/**
+ * A row of tappable TextViews with a breadcrumb for settings search.
+ */
+public class SearchSettingsRowView extends LinearLayout implements
+ View.OnClickListener, AllAppsSearchBarController.PayloadResultHandler<Bundle> {
+
+ private TextView mTitleView;
+ private TextView mDescriptionView;
+ private TextView mBreadcrumbsView;
+ private Intent mIntent;
+
+ public SearchSettingsRowView(@NonNull Context context) {
+ super(context);
+ }
+
+ public SearchSettingsRowView(@NonNull Context context,
+ @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public SearchSettingsRowView(@NonNull Context context, @Nullable AttributeSet attrs,
+ int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mTitleView = findViewById(R.id.title);
+ mDescriptionView = findViewById(R.id.description);
+ mBreadcrumbsView = findViewById(R.id.breadcrumbs);
+ setOnClickListener(this);
+ }
+
+ @Override
+ public void applyAdapterInfo(
+ AllAppsGridAdapter.AdapterItemWithPayload<Bundle> adapterItemWithPayload) {
+ Bundle bundle = adapterItemWithPayload.getPayload();
+ mIntent = bundle.getParcelable("intent");
+ showIfAvailable(mTitleView, bundle.getString("title"));
+ showIfAvailable(mDescriptionView, bundle.getString("description"));
+ ArrayList<String> breadcrumbs = bundle.getStringArrayList("breadcrumbs");
+ //TODO: implement RTL friendly breadcrumbs view
+ showIfAvailable(mBreadcrumbsView, breadcrumbs != null
+ ? String.join(" > ", breadcrumbs) : null);
+ adapterItemWithPayload.setSelectionHandler(() -> onClick(this));
+ }
+
+ private void showIfAvailable(TextView view, @Nullable String string) {
+ if (TextUtils.isEmpty(string)) {
+ view.setVisibility(GONE);
+ } else {
+ view.setVisibility(VISIBLE);
+ view.setText(string);
+ }
+ }
+
+ @Override
+ public void onClick(View view) {
+ if (mIntent == null) return;
+ // TODO: create ItemInfo object and then use it to call startActivityForResult for proper
+ // WW logging
+ Launcher launcher = Launcher.getLauncher(view.getContext());
+ launcher.startActivityForResult(mIntent, 0);
+ }
+}
diff --git a/src/com/android/launcher3/views/Snackbar.java b/src/com/android/launcher3/views/Snackbar.java
index 513ce59..49fcd2e 100644
--- a/src/com/android/launcher3/views/Snackbar.java
+++ b/src/com/android/launcher3/views/Snackbar.java
@@ -167,11 +167,6 @@
}
@Override
- public void logActionCommand(int command) {
- // TODO
- }
-
- @Override
protected boolean isOfType(int type) {
return (type & TYPE_SNACKBAR) != 0;
}
diff --git a/src/com/android/launcher3/views/WorkEduView.java b/src/com/android/launcher3/views/WorkEduView.java
index d35a38f..d6737db 100644
--- a/src/com/android/launcher3/views/WorkEduView.java
+++ b/src/com/android/launcher3/views/WorkEduView.java
@@ -38,7 +38,6 @@
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.statemanager.StateManager.StateListener;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
/**
* On boarding flow for users right after setting up work profile
@@ -89,16 +88,6 @@
}
@Override
- public void logActionCommand(int command) {
- // Since this is on-boarding popup, it is not a user controlled action.
- }
-
- @Override
- public int getLogContainerType() {
- return LauncherLogProto.ContainerType.TIP;
- }
-
- @Override
protected boolean isOfType(int type) {
return (type & TYPE_ON_BOARD_POPUP) != 0;
}
diff --git a/src/com/android/launcher3/widget/BaseWidgetSheet.java b/src/com/android/launcher3/widget/BaseWidgetSheet.java
index 3e5113a..01af96c 100644
--- a/src/com/android/launcher3/widget/BaseWidgetSheet.java
+++ b/src/com/android/launcher3/widget/BaseWidgetSheet.java
@@ -16,7 +16,6 @@
package com.android.launcher3.widget;
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
-import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
import android.content.Context;
import android.graphics.Point;
@@ -31,20 +30,15 @@
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.dragndrop.DragOptions;
-import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.popup.PopupDataProvider;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.touch.ItemLongClickListener;
import com.android.launcher3.uioverrides.WallpaperColorInfo;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.AbstractSlideInView;
-import java.util.ArrayList;
-
/**
* Base class for various widgets popup
*/
@@ -149,28 +143,6 @@
isSheetDark ? SystemUiController.FLAG_DARK_NAV : SystemUiController.FLAG_LIGHT_NAV);
}
- @Override
- public void fillInLogContainerData(ItemInfo childInfo, Target child,
- ArrayList<Target> parents) {
- Target target = newContainerTarget(ContainerType.WIDGETS);
- target.cardinality = getElementsRowCount();
- parents.add(target);
- }
-
- @Override
- public final void logActionCommand(int command) {
- Target target = newContainerTarget(getLogContainerType());
- target.cardinality = getElementsRowCount();
- mLauncher.getUserEventDispatcher().logActionCommand(command, target);
- }
-
- @Override
- public int getLogContainerType() {
- return ContainerType.WIDGETS;
- }
-
- protected abstract int getElementsRowCount();
-
protected SystemUiController getSystemUiController() {
return mLauncher.getSystemUiController();
}
diff --git a/src/com/android/launcher3/widget/WidgetsBottomSheet.java b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
index 30be7a6..3585a18 100644
--- a/src/com/android/launcher3/widget/WidgetsBottomSheet.java
+++ b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
@@ -180,11 +180,6 @@
}
@Override
- protected int getElementsRowCount() {
- return 1;
- }
-
- @Override
protected Pair<View, String> getAccessibilityTarget() {
return Pair.create(findViewById(R.id.title), getContext().getString(
mIsOpen ? R.string.widgets_list : R.string.widgets_list_closed));
diff --git a/src/com/android/launcher3/widget/WidgetsFullSheet.java b/src/com/android/launcher3/widget/WidgetsFullSheet.java
index 68a3ec5..4c8c339 100644
--- a/src/com/android/launcher3/widget/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/WidgetsFullSheet.java
@@ -243,11 +243,6 @@
}
@Override
- protected int getElementsRowCount() {
- return mAdapter.getItemCount();
- }
-
- @Override
public void addHintCloseAnim(
float distanceToMove, Interpolator interpolator, PendingAnimation target) {
target.setFloat(mRecyclerView, VIEW_TRANSLATE_Y, -distanceToMove, interpolator);
diff --git a/src_plugins/com/android/systemui/plugins/UserEventPlugin.java b/src_plugins/com/android/systemui/plugins/UserEventPlugin.java
deleted file mode 100644
index 0e3664a..0000000
--- a/src_plugins/com/android/systemui/plugins/UserEventPlugin.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.systemui.plugins;
-
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-
-/**
- * Implement this plugin interface to access user event log on the device for prototype purpose.
- * NOTE: plugin is for internal prototype only and is not visible in production environment.
- */
-@ProvidesInterface(action = UserEventPlugin.ACTION, version = UserEventPlugin.VERSION)
-public interface UserEventPlugin extends Plugin {
- String ACTION = "com.android.launcher3.action.PLUGIN_USER_EVENT_LOG";
- int VERSION = 1;
-
- /**
- * Callback to be triggered whenever an user event occurs.
- */
- void onUserEvent(Object event);
-}
diff --git a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
index 9d87788..a64df62 100644
--- a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
+++ b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
@@ -51,6 +51,7 @@
// True is the widget support is disabled.
public static final boolean GO_DISABLE_WIDGETS = false;
+ public static final boolean GO_DISABLE_NOTIFICATION_DOTS = false;
private static final String TAG = "WidgetsModel";
private static final boolean DEBUG = false;