Merge "Refactor LauncherAppTransitionManager & polish for new app transitions." into ub-launcher3-master
diff --git a/res/layout/predictions_view.xml b/quickstep/res/values/config.xml
similarity index 64%
rename from res/layout/predictions_view.xml
rename to quickstep/res/values/config.xml
index 280290c..94211c6 100644
--- a/res/layout/predictions_view.xml
+++ b/quickstep/res/values/config.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- 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
+ 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,
@@ -13,7 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.launcher3.allapps.PredictionRowView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
\ No newline at end of file
+<resources>
+ <string name="task_overlay_factory_class" translatable="false"></string>
+
+</resources>
diff --git a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
new file mode 100644
index 0000000..c2fb7be
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
@@ -0,0 +1,55 @@
+/*
+ * 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;
+
+import android.content.Context;
+import android.graphics.Matrix;
+import android.view.View;
+
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.util.Preconditions;
+import com.android.systemui.shared.recents.model.ThumbnailData;
+
+/**
+ * Factory class to create and add an overlays on the TaskView
+ */
+public class TaskOverlayFactory {
+
+ private static TaskOverlayFactory sInstance;
+
+ public static TaskOverlayFactory get(Context context) {
+ Preconditions.assertUIThread();
+ if (sInstance == null) {
+ sInstance = Utilities.getOverrideObject(TaskOverlayFactory.class,
+ context.getApplicationContext(), R.string.task_overlay_factory_class);
+ }
+ return sInstance;
+ }
+
+ public TaskOverlay createOverlay(View thumbnailView) {
+ return new TaskOverlay();
+ }
+
+ public static class TaskOverlay {
+
+ public void setTaskInfo(ThumbnailData thumbnail, Matrix matrix) { }
+
+ public void reset() { }
+
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/TaskThumbnailView.java
index eeaef09..36a0601 100644
--- a/quickstep/src/com/android/quickstep/TaskThumbnailView.java
+++ b/quickstep/src/com/android/quickstep/TaskThumbnailView.java
@@ -28,7 +28,6 @@
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
-import android.graphics.Rect;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.View;
@@ -36,6 +35,7 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
+import com.android.quickstep.TaskOverlayFactory.TaskOverlay;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -49,6 +49,7 @@
private final float mCornerRadius;
private final float mFadeLength;
+ private final TaskOverlay mOverlay;
private final Paint mPaint = new Paint();
private final Matrix mMatrix = new Matrix();
@@ -70,6 +71,11 @@
super(context, attrs, defStyleAttr);
mCornerRadius = getResources().getDimension(R.dimen.task_corner_radius);
mFadeLength = getResources().getDimension(R.dimen.task_fade_length);
+ mOverlay = TaskOverlayFactory.get(context).createOverlay(this);
+ }
+
+ public void bind() {
+ mOverlay.reset();
}
/**
@@ -89,6 +95,7 @@
mBitmapShader = null;
mThumbnailData = null;
mPaint.setShader(null);
+ mOverlay.reset();
}
updateThumbnailPaintFilter();
}
@@ -173,6 +180,8 @@
}
mPaint.setShader(shader);
}
+
+ mOverlay.setTaskInfo(mThumbnailData, mMatrix);
invalidate();
}
diff --git a/quickstep/src/com/android/quickstep/TaskView.java b/quickstep/src/com/android/quickstep/TaskView.java
index 0e999f8..46fcc72 100644
--- a/quickstep/src/com/android/quickstep/TaskView.java
+++ b/quickstep/src/com/android/quickstep/TaskView.java
@@ -36,6 +36,7 @@
import com.android.launcher3.R;
import com.android.quickstep.RecentsView.PageCallbacks;
import com.android.quickstep.RecentsView.ScrollState;
+import com.android.quickstep.TaskOverlayFactory.TaskOverlay;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.Task.TaskCallbacks;
import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -113,6 +114,7 @@
mTask.removeCallback(this);
}
mTask = task;
+ mSnapshotView.bind();
task.addCallback(this);
}
diff --git a/res/layout/all_apps.xml b/res/layout/all_apps.xml
index 8cf32bd..2ce6b8c 100644
--- a/res/layout/all_apps.xml
+++ b/res/layout/all_apps.xml
@@ -31,48 +31,7 @@
<include layout="@layout/all_apps_fast_scroller" />
- <com.android.launcher3.allapps.FloatingHeaderView
- android:id="@+id/all_apps_header"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingTop="@dimen/all_apps_header_top_padding"
- android:clipToPadding="false"
- android:layout_below="@id/search_container_all_apps" >
-
- <include layout="@layout/predictions_view" android:id="@+id/header_content" />
-
- <com.android.launcher3.allapps.PersonalWorkSlidingTabStrip
- android:id="@+id/tabs"
- android:layout_width="match_parent"
- android:layout_height="@dimen/all_apps_header_tab_height"
- android:layout_marginLeft="@dimen/all_apps_tabs_side_padding"
- android:layout_marginRight="@dimen/all_apps_tabs_side_padding"
- android:layout_below="@id/header_content"
- android:orientation="horizontal">
- <Button
- android:id="@+id/tab_personal"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:background="?android:attr/selectableItemBackground"
- android:fontFamily="sans-serif-medium"
- android:text="@string/all_apps_personal_tab"
- android:textAllCaps="true"
- android:textColor="@color/all_apps_tab_text"
- android:textSize="14sp"/>
- <Button
- android:id="@+id/tab_work"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:background="?android:attr/selectableItemBackground"
- android:fontFamily="sans-serif-medium"
- android:text="@string/all_apps_work_tab"
- android:textAllCaps="true"
- android:textColor="@color/all_apps_work_tab_text"
- android:textSize="14sp"/>
- </com.android.launcher3.allapps.PersonalWorkSlidingTabStrip>
- </com.android.launcher3.allapps.FloatingHeaderView>
+ <include layout="@layout/all_apps_floating_header" />
<!-- Note: we are reusing/repurposing a system attribute for search layout, because of a
platform bug, which prevents using custom attributes in <include> tag -->
diff --git a/res/layout/all_apps_floating_header.xml b/res/layout/all_apps_floating_header.xml
new file mode 100644
index 0000000..166725d
--- /dev/null
+++ b/res/layout/all_apps_floating_header.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<com.android.launcher3.allapps.FloatingHeaderView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/all_apps_header"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/search_container_all_apps"
+ android:clipToPadding="false"
+ android:paddingTop="@dimen/all_apps_header_top_padding"
+ android:orientation="vertical" >
+
+ <com.android.launcher3.allapps.PersonalWorkSlidingTabStrip
+ android:id="@+id/tabs"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/all_apps_header_tab_height"
+ android:layout_marginLeft="@dimen/all_apps_tabs_side_padding"
+ android:layout_marginRight="@dimen/all_apps_tabs_side_padding"
+ android:orientation="horizontal">
+
+ <Button
+ android:id="@+id/tab_personal"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:background="?android:attr/selectableItemBackground"
+ android:fontFamily="sans-serif-medium"
+ android:text="@string/all_apps_personal_tab"
+ android:textAllCaps="true"
+ android:textColor="@color/all_apps_tab_text"
+ android:textSize="14sp" />
+
+ <Button
+ android:id="@+id/tab_work"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:background="?android:attr/selectableItemBackground"
+ android:fontFamily="sans-serif-medium"
+ android:text="@string/all_apps_work_tab"
+ android:textAllCaps="true"
+ android:textColor="@color/all_apps_work_tab_text"
+ android:textSize="14sp" />
+ </com.android.launcher3.allapps.PersonalWorkSlidingTabStrip>
+</com.android.launcher3.allapps.FloatingHeaderView>
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index a5ca3ee..957a5e5 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -118,8 +118,7 @@
mIconDpi = inv.fillResIconDpi;
mIconDb = new IconDB(context, inv.iconBitmapSize);
- mIconProvider = Utilities.getOverrideObject(
- IconProvider.class, context, R.string.icon_provider_class);
+ mIconProvider = IconProvider.newInstance(context);
mWorkerHandler = new Handler(LauncherModel.getWorkerLooper());
mLowResOptions = new BitmapFactory.Options();
@@ -254,7 +253,7 @@
// Remove all active icon update tasks.
mWorkerHandler.removeCallbacksAndMessages(ICON_UPDATE_TOKEN);
- mIconProvider.updateSystemStateString();
+ mIconProvider.updateSystemStateString(mContext);
for (UserHandle user : mUserManager.getUserProfiles()) {
// Query for the set of apps
final List<LauncherActivityInfo> apps = mLauncherApps.getActivityList(null, user);
diff --git a/src/com/android/launcher3/IconProvider.java b/src/com/android/launcher3/IconProvider.java
index 4dee2b5..b469a8f 100644
--- a/src/com/android/launcher3/IconProvider.java
+++ b/src/com/android/launcher3/IconProvider.java
@@ -1,5 +1,6 @@
package com.android.launcher3;
+import android.content.Context;
import android.content.pm.LauncherActivityInfo;
import android.graphics.drawable.Drawable;
import android.os.Build;
@@ -8,17 +9,26 @@
public class IconProvider {
- private static final boolean DBG = false;
- private static final String TAG = "IconProvider";
-
protected String mSystemState;
- public IconProvider() {
- updateSystemStateString();
+ public static IconProvider newInstance(Context context) {
+ IconProvider provider = Utilities.getOverrideObject(
+ IconProvider.class, context, R.string.icon_provider_class);
+ provider.updateSystemStateString(context);
+ return provider;
}
- public void updateSystemStateString() {
- mSystemState = Locale.getDefault().toString() + "," + Build.VERSION.SDK_INT;
+ public IconProvider() { }
+
+ public void updateSystemStateString(Context context) {
+ final String locale;
+ if (Utilities.ATLEAST_NOUGAT) {
+ locale = context.getResources().getConfiguration().getLocales().toLanguageTags();
+ } else {
+ locale = Locale.getDefault().toString();
+ }
+
+ mSystemState = locale + "," + Build.VERSION.SDK_INT;
}
public String getIconSystemState(String packageName) {
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 2e544ec..dc3de18 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -55,13 +55,11 @@
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.keyboard.FocusedItemDecorator;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
-import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.ComponentKeyMapper;
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.views.BottomUserEducationView;
-import java.util.HashMap;
import java.util.List;
import java.util.Set;
@@ -76,6 +74,7 @@
private final ClickShadowView mTouchFeedbackView;
private final ItemInfoMatcher mPersonalMatcher = ItemInfoMatcher.ofUser(Process.myUserHandle());
private final ItemInfoMatcher mWorkMatcher = ItemInfoMatcher.not(mPersonalMatcher);
+ private final AllAppsStore mAllAppsStore = new AllAppsStore();
private SearchUiManager mSearchUiManager;
private View mSearchContainer;
@@ -92,8 +91,6 @@
private boolean mHasPredictions = false;
private boolean mSearchModeWhileUsingTabs = false;
- private final HashMap<ComponentKey, AppInfo> mComponentToAppMap = new HashMap<>();
-
public AllAppsContainerView(Context context) {
this(context, null);
}
@@ -132,6 +129,10 @@
// TODO: Reimplement once fast scroller is fixed.
}
+ public AllAppsStore getAppsStore() {
+ return mAllAppsStore;
+ }
+
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
@@ -149,64 +150,29 @@
public void setApps(List<AppInfo> apps) {
boolean hasWorkProfileApp = hasWorkProfileApp(apps);
rebindAdapters(hasWorkProfileApp);
- mComponentToAppMap.clear();
- addOrUpdateApps(apps);
+ mAllAppsStore.setApps(apps);
}
/**
* Adds or updates existing apps in the list
*/
public void addOrUpdateApps(List<AppInfo> apps) {
- for (AppInfo app : apps) {
- mComponentToAppMap.put(app.toComponentKey(), app);
- }
- onAppsUpdated();
- mSearchUiManager.refreshSearchResult();
- mHeader.onAppsUpdated();
+ mAllAppsStore.addOrUpdateApps(apps);
}
/**
* Removes some apps from the list.
*/
public void removeApps(List<AppInfo> apps) {
- for (AppInfo app : apps) {
- mComponentToAppMap.remove(app.toComponentKey());
- }
- onAppsUpdated();
- mSearchUiManager.refreshSearchResult();
- }
-
- private void onAppsUpdated() {
- for (int i = 0; i < getNumOfAdapters(); i++) {
- mAH[i].appsList.onAppsUpdated();
- }
- }
-
- private int getNumOfAdapters() {
- return mUsingTabs ? mAH.length : 1;
+ mAllAppsStore.removeApps(apps);
}
public void updatePromiseAppProgress(PromiseAppInfo app) {
- for (int i = 0; i < mAH.length; i++) {
- updatePromiseAppProgress(app, mAH[i].recyclerView);
- }
- if (isHeaderVisible()) {
- updatePromiseAppProgress(app, mHeader.getPredictionRow());
- }
- }
-
- private void updatePromiseAppProgress(PromiseAppInfo app, ViewGroup parent) {
- if (parent == null) {
- return;
- }
- int childCount = parent.getChildCount();
- for (int i = 0; i < childCount; i++) {
- View child = parent.getChildAt(i);
- if (child instanceof BubbleTextView && child.getTag() == app) {
- BubbleTextView bubbleTextView = (BubbleTextView) child;
- bubbleTextView.applyProgressLevel(app.level);
+ mAllAppsStore.updateAllIcons((child) -> {
+ if (child.getTag() == app) {
+ child.applyProgressLevel(app.level);
}
- }
+ });
}
/**
@@ -358,34 +324,15 @@
}
public void updateIconBadges(Set<PackageUserKey> updatedBadges) {
- final PackageUserKey packageUserKey = new PackageUserKey(null, null);
- for (int j = 0; j < mAH.length; j++) {
- updateIconBadges(updatedBadges, packageUserKey, mAH[j].recyclerView);
- }
- if (mHeader != null) {
- updateIconBadges(updatedBadges, packageUserKey, mHeader.getPredictionRow());
- }
- }
-
- private void updateIconBadges(Set<PackageUserKey> updatedBadges, PackageUserKey packageUserKey,
- ViewGroup parent) {
- if (parent == null) {
- return;
- }
- final int n = parent.getChildCount();
- for (int i = 0; i < n; i++) {
- View child = parent.getChildAt(i);
- if (child instanceof PredictionRowView) {
- updateIconBadges(updatedBadges, packageUserKey, (PredictionRowView) child);
+ PackageUserKey tempKey = new PackageUserKey(null, null);
+ mAllAppsStore.updateAllIcons((child) -> {
+ if (child.getTag() instanceof ItemInfo) {
+ ItemInfo info = (ItemInfo) child.getTag();
+ if (tempKey.updateFromItemInfo(info) && updatedBadges.contains(tempKey)) {
+ child.applyBadgeState(info, true /* animate */);
+ }
}
- if (!(child instanceof BubbleTextView) || !(child.getTag() instanceof ItemInfo)) {
- continue;
- }
- ItemInfo info = (ItemInfo) child.getTag();
- if (packageUserKey.updateFromItemInfo(info) && updatedBadges.contains(packageUserKey)) {
- ((BubbleTextView) child).applyBadgeState(info, true /* animate */);
- }
- }
+ });
}
public SpringAnimationHandler getSpringAnimationHandler() {
@@ -403,6 +350,9 @@
replaceRVContainer(showTabs);
mUsingTabs = showTabs;
+ mAllAppsStore.unregisterIconContainer(mAH[AdapterHolder.MAIN].recyclerView);
+ mAllAppsStore.unregisterIconContainer(mAH[AdapterHolder.WORK].recyclerView);
+
if (mUsingTabs) {
mAH[AdapterHolder.MAIN].setup(mViewPager.getChildAt(0), mPersonalMatcher);
mAH[AdapterHolder.WORK].setup(mViewPager.getChildAt(1), mWorkMatcher);
@@ -419,6 +369,9 @@
}
}
+ mAllAppsStore.registerIconContainer(mAH[AdapterHolder.MAIN].recyclerView);
+ mAllAppsStore.registerIconContainer(mAH[AdapterHolder.WORK].recyclerView);
+
applyTouchDelegate();
}
@@ -492,9 +445,6 @@
}
public void setPredictedApps(List<ComponentKeyMapper<AppInfo>> apps) {
- if (isHeaderVisible()) {
- mHeader.getPredictionRow().setPredictedApps(apps);
- }
mAH[AdapterHolder.MAIN].appsList.setPredictedApps(apps);
boolean hasPredictions = !apps.isEmpty();
if (mHasPredictions != hasPredictions) {
@@ -506,7 +456,7 @@
}
public AppInfo findApp(ComponentKeyMapper<AppInfo> mapper) {
- return mapper.getItem(mComponentToAppMap);
+ return mAllAppsStore.getApp(mapper);
}
public AlphabeticalAppsList getApps() {
@@ -526,9 +476,9 @@
return;
}
mHeader.setVisibility(View.VISIBLE);
- mHeader.setup(mAH, mComponentToAppMap, mNumPredictedAppsPerRow);
+ mHeader.setup(mAH, mAH[AllAppsContainerView.AdapterHolder.WORK].recyclerView == null);
- int padding = mHeader.getPredictionRow().getExpectedHeight();
+ int padding = mHeader.getMaxTranslation();
if (mHasPredictions && !mUsingTabs) {
padding += mHeader.getPaddingTop() + mHeader.getPaddingBottom();
}
@@ -582,14 +532,6 @@
}
}
- public List<AppInfo> getPredictedApps() {
- if (isHeaderVisible()) {
- return mHeader.getPredictionRow().getPredictedApps();
- } else {
- return mAH[AdapterHolder.MAIN].appsList.getPredictedApps();
- }
- }
-
public boolean isHeaderVisible() {
return mHeader != null && mHeader.getVisibility() == View.VISIBLE;
}
@@ -604,7 +546,7 @@
public static final int MAIN = 0;
public static final int WORK = 1;
- final AllAppsGridAdapter adapter;
+ public final AllAppsGridAdapter adapter;
final LinearLayoutManager layoutManager;
final SpringAnimationHandler animationHandler;
final AlphabeticalAppsList appsList;
@@ -614,7 +556,7 @@
boolean verticalFadingEdge;
AdapterHolder(boolean isWork) {
- appsList = new AlphabeticalAppsList(mLauncher, mComponentToAppMap, isWork);
+ appsList = new AlphabeticalAppsList(mLauncher, mAllAppsStore, isWork);
adapter = new AllAppsGridAdapter(mLauncher, appsList, mLauncher,
AllAppsContainerView.this, true);
appsList.setAdapter(adapter);
@@ -649,11 +591,6 @@
? paddingTopForTabs : padding.top;
recyclerView.setPadding(padding.left, paddingTop, padding.right, padding.bottom);
}
- if (isHeaderVisible()) {
- PredictionRowView prv = mHeader.getPredictionRow();
- prv.setPadding(padding.left, prv.getPaddingTop() , padding.right,
- prv.getPaddingBottom());
- }
}
void applyNumsPerRow() {
@@ -663,10 +600,6 @@
}
adapter.setNumAppsPerRow(mNumAppsPerRow);
appsList.setNumAppsPerRow(mNumAppsPerRow, mNumPredictedAppsPerRow);
- if (isHeaderVisible()) {
- mHeader.getPredictionRow()
- .setNumAppsPerRow(mNumPredictedAppsPerRow);
- }
}
}
diff --git a/src/com/android/launcher3/allapps/AllAppsStore.java b/src/com/android/launcher3/allapps/AllAppsStore.java
new file mode 100644
index 0000000..17f1c89
--- /dev/null
+++ b/src/com/android/launcher3/allapps/AllAppsStore.java
@@ -0,0 +1,127 @@
+/*
+ * 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.launcher3.allapps;
+
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.launcher3.AppInfo;
+import com.android.launcher3.BubbleTextView;
+import com.android.launcher3.util.ComponentKey;
+import com.android.launcher3.util.ComponentKeyMapper;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * A utility class to maintain the collection of all apps.
+ */
+public class AllAppsStore {
+
+ private final HashMap<ComponentKey, AppInfo> mComponentToAppMap = new HashMap<>();
+ private final List<OnUpdateListener> mUpdateListeners = new ArrayList<>();
+ private final ArrayList<ViewGroup> mIconContainers = new ArrayList<>();
+
+ public Collection<AppInfo> getApps() {
+ return mComponentToAppMap.values();
+ }
+
+ /**
+ * Sets the current set of apps.
+ */
+ public void setApps(List<AppInfo> apps) {
+ mComponentToAppMap.clear();
+ addOrUpdateApps(apps);
+ }
+
+ public AppInfo getApp(ComponentKey key) {
+ return mComponentToAppMap.get(key);
+ }
+
+ public AppInfo getApp(ComponentKeyMapper<AppInfo> mapper) {
+ return mapper.getItem(mComponentToAppMap);
+ }
+
+ /**
+ * Adds or updates existing apps in the list
+ */
+ public void addOrUpdateApps(List<AppInfo> apps) {
+ for (AppInfo app : apps) {
+ mComponentToAppMap.put(app.toComponentKey(), app);
+ }
+ notifyUpdate();
+ }
+
+ /**
+ * Removes some apps from the list.
+ */
+ public void removeApps(List<AppInfo> apps) {
+ for (AppInfo app : apps) {
+ mComponentToAppMap.remove(app.toComponentKey());
+ }
+ notifyUpdate();
+ }
+
+
+ private void notifyUpdate() {
+ int count = mUpdateListeners.size();
+ for (int i = 0; i < count; i++) {
+ mUpdateListeners.get(i).onAppsUpdated();
+ }
+ }
+
+ public void addUpdateListener(OnUpdateListener listener) {
+ mUpdateListeners.add(listener);
+ }
+
+ public void removeUpdateListener(OnUpdateListener listener) {
+ mUpdateListeners.remove(listener);
+ }
+
+ public void registerIconContainer(ViewGroup container) {
+ if (container != null) {
+ mIconContainers.add(container);
+ }
+ }
+
+ public void unregisterIconContainer(ViewGroup container) {
+ mIconContainers.remove(container);
+ }
+
+ public void updateAllIcons(IconAction action) {
+ for (int i = mIconContainers.size() - 1; i >= 0; i--) {
+ ViewGroup parent = mIconContainers.get(i);
+ int childCount = parent.getChildCount();
+
+ for (int j = 0; j < childCount; j++) {
+ View child = parent.getChildAt(j);
+ if (child instanceof BubbleTextView) {
+ action.apply((BubbleTextView) child);
+ }
+ }
+ }
+ }
+
+ public interface OnUpdateListener {
+ void onAppsUpdated();
+ }
+
+ public interface IconAction {
+ void apply(BubbleTextView icon);
+ }
+}
diff --git a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
index 76828de..29b32b0 100644
--- a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
+++ b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
@@ -44,7 +44,7 @@
/**
* The alphabetically sorted list of applications.
*/
-public class AlphabeticalAppsList {
+public class AlphabeticalAppsList implements AllAppsStore.OnUpdateListener {
public static final String TAG = "AlphabeticalAppsList";
private static final boolean DEBUG = false;
@@ -153,7 +153,7 @@
// The set of apps from the system not including predictions
private final List<AppInfo> mApps = new ArrayList<>();
- private final HashMap<ComponentKey, AppInfo> mComponentToAppMap;
+ private final AllAppsStore mAllAppsStore;
// The set of filtered apps with the current filter
private final List<AppInfo> mFilteredApps = new ArrayList<>();
@@ -179,16 +179,13 @@
private int mNumAppRowsInAdapter;
private ItemInfoMatcher mItemFilter;
- public AlphabeticalAppsList(
- Context context,
- HashMap<ComponentKey,
- AppInfo> componentToAppMap,
- boolean isWork) {
- mComponentToAppMap = componentToAppMap;
+ public AlphabeticalAppsList(Context context, AllAppsStore appsStore, boolean isWork) {
+ mAllAppsStore = appsStore;
mLauncher = Launcher.getLauncher(context);
mIndexer = new AlphabeticIndexCompat(context);
mAppNameComparator = new AppInfoComparator(context);
mIsWork = isWork;
+ mAllAppsStore.addUpdateListener(this);
}
public void updateItemFilter(ItemInfoMatcher itemFilter) {
@@ -283,14 +280,14 @@
}
private List<AppInfo> processPredictedAppComponents(List<ComponentKeyMapper<AppInfo>> components) {
- if (mComponentToAppMap.isEmpty()) {
+ if (mAllAppsStore.getApps().isEmpty()) {
// Apps have not been bound yet.
return Collections.emptyList();
}
List<AppInfo> predictedApps = new ArrayList<>();
for (ComponentKeyMapper<AppInfo> mapper : components) {
- AppInfo info = mapper.getItem(mComponentToAppMap);
+ AppInfo info = mAllAppsStore.getApp(mapper);
if (info != null) {
predictedApps.add(info);
} else {
@@ -359,11 +356,12 @@
/**
* Updates internals when the set of apps are updated.
*/
- void onAppsUpdated() {
+ @Override
+ public void onAppsUpdated() {
// Sort the list of apps
mApps.clear();
- for (AppInfo app : mComponentToAppMap.values()) {
+ for (AppInfo app : mAllAppsStore.getApps()) {
if (mItemFilter == null || mItemFilter.matches(app, null) || hasFilter()) {
mApps.add(app);
}
@@ -580,7 +578,7 @@
}
ArrayList<AppInfo> result = new ArrayList<>();
for (ComponentKey key : mSearchResults) {
- AppInfo match = mComponentToAppMap.get(key);
+ AppInfo match = mAllAppsStore.getApp(key);
if (match != null) {
result.add(match);
}
diff --git a/src/com/android/launcher3/allapps/FloatingHeaderView.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java
index 2391768..d8a9f63 100644
--- a/src/com/android/launcher3/allapps/FloatingHeaderView.java
+++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java
@@ -15,7 +15,6 @@
*/
package com.android.launcher3.allapps;
-
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Point;
@@ -27,18 +26,14 @@
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.LinearLayout;
import android.widget.RelativeLayout;
-import com.android.launcher3.AppInfo;
import com.android.launcher3.R;
-import com.android.launcher3.util.ComponentKey;
-import java.util.HashMap;
-
-public class FloatingHeaderView extends RelativeLayout implements
+public class FloatingHeaderView extends LinearLayout implements
ValueAnimator.AnimatorUpdateListener {
-
private final Rect mClip = new Rect(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE);
private final ValueAnimator mAnimator = ValueAnimator.ofInt(0, 0);
private final Point mTempOffset = new Point();
@@ -63,19 +58,18 @@
}
};
- private PredictionRowView mPredictionRow;
private ViewGroup mTabLayout;
private AllAppsRecyclerView mMainRV;
private AllAppsRecyclerView mWorkRV;
private AllAppsRecyclerView mCurrentRV;
private ViewGroup mParent;
- private boolean mTabsHidden;
private boolean mHeaderCollapsed;
- private int mMaxTranslation;
private int mSnappedScrolledY;
private int mTranslationY;
private boolean mForwardToRecyclerView;
+ protected int mMaxTranslation;
+
public FloatingHeaderView(@NonNull Context context) {
this(context, null);
}
@@ -88,17 +82,10 @@
protected void onFinishInflate() {
super.onFinishInflate();
mTabLayout = findViewById(R.id.tabs);
- mPredictionRow = findViewById(R.id.header_content);
}
- public void setup(AllAppsContainerView.AdapterHolder[] mAH,
- HashMap<ComponentKey, AppInfo> componentToAppMap, int numPredictedAppsPerRow) {
- mTabsHidden = mAH[AllAppsContainerView.AdapterHolder.WORK].recyclerView == null;
- mTabLayout.setVisibility(mTabsHidden ? View.GONE : View.VISIBLE);
- mPredictionRow.setup(mAH[AllAppsContainerView.AdapterHolder.MAIN].adapter,
- componentToAppMap, numPredictedAppsPerRow);
- mPredictionRow.setShowDivider(mTabsHidden);
- mMaxTranslation = mPredictionRow.getExpectedHeight();
+ public void setup(AllAppsContainerView.AdapterHolder[] mAH, boolean tabsHidden) {
+ mTabLayout.setVisibility(tabsHidden ? View.GONE : View.VISIBLE);
mMainRV = setupRV(mMainRV, mAH[AllAppsContainerView.AdapterHolder.MAIN].recyclerView);
mWorkRV = setupRV(mWorkRV, mAH[AllAppsContainerView.AdapterHolder.WORK].recyclerView);
mParent = (ViewGroup) mMainRV.getParent();
@@ -117,12 +104,12 @@
mCurrentRV = active ? mMainRV : mWorkRV;
}
- public PredictionRowView getPredictionRow() {
- return mPredictionRow;
+ public int getMaxTranslation() {
+ return mMaxTranslation;
}
private boolean canSnapAt(int currentScrollY) {
- return Math.abs(currentScrollY) <= mPredictionRow.getHeight();
+ return Math.abs(currentScrollY) <= mMaxTranslation;
}
private void moved(final int currentScrollY) {
@@ -149,16 +136,12 @@
}
}
- private void apply() {
+ protected void applyScroll(int uncappedY, int currentY) { }
+
+ protected void apply() {
int uncappedTranslationY = mTranslationY;
mTranslationY = Math.max(mTranslationY, -mMaxTranslation);
- if (mTranslationY != uncappedTranslationY) {
- // we hide it completely if already capped (for opening search anim)
- mPredictionRow.setVisibility(View.INVISIBLE);
- } else {
- mPredictionRow.setVisibility(View.VISIBLE);
- mPredictionRow.setTranslationY(uncappedTranslationY);
- }
+ applyScroll(uncappedTranslationY, mTranslationY);
mTabLayout.setTranslationY(mTranslationY);
mClip.top = mMaxTranslation + mTranslationY;
// clipping on a draw might cause additional redraw
@@ -218,10 +201,6 @@
p.x = getLeft() - mCurrentRV.getLeft() - mParent.getLeft();
p.y = getTop() - mCurrentRV.getTop() - mParent.getTop();
}
-
- public void onAppsUpdated() {
- mPredictionRow.onAppsUpdated();
- }
}
diff --git a/src/com/android/launcher3/allapps/PredictionRowView.java b/src/com/android/launcher3/allapps/PredictionRowView.java
deleted file mode 100644
index 267ef3c..0000000
--- a/src/com/android/launcher3/allapps/PredictionRowView.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2017 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.allapps;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.View;
-import android.widget.LinearLayout;
-
-import com.android.launcher3.AppInfo;
-import com.android.launcher3.BubbleTextView;
-import com.android.launcher3.ItemInfo;
-import com.android.launcher3.Launcher;
-import com.android.launcher3.R;
-import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.logging.UserEventDispatcher;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
-import com.android.launcher3.util.ComponentKey;
-import com.android.launcher3.util.ComponentKeyMapper;
-import com.android.launcher3.util.Themes;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-
-public class PredictionRowView extends LinearLayout implements
- UserEventDispatcher.LogContainerProvider {
-
- private static final String TAG = "PredictionRowView";
-
- private HashMap<ComponentKey, AppInfo> mComponentToAppMap;
- private int mNumPredictedAppsPerRow;
- // The set of predicted app component names
- private final List<ComponentKeyMapper<AppInfo>> mPredictedAppComponents = new ArrayList<>();
- // The set of predicted apps resolved from the component names and the current set of apps
- private final ArrayList<AppInfo> mPredictedApps = new ArrayList<>();
- private final Paint mPaint;
- // This adapter is only used to create an identical item w/ same behavior as in the all apps RV
- private AllAppsGridAdapter mAdapter;
- private boolean mShowDivider;
-
- public PredictionRowView(@NonNull Context context) {
- this(context, null);
- }
-
- public PredictionRowView(@NonNull Context context, @Nullable AttributeSet attrs) {
- super(context, attrs);
- setOrientation(LinearLayout.HORIZONTAL);
- setWillNotDraw(false);
- mPaint = new Paint();
- mPaint.setColor(Themes.getAttrColor(context, android.R.attr.colorControlHighlight));
- mPaint.setStrokeWidth(getResources().getDimensionPixelSize(R.dimen.all_apps_divider_height));
- }
-
- public void setup(AllAppsGridAdapter adapter, HashMap<ComponentKey, AppInfo> componentToAppMap,
- int numPredictedAppsPerRow) {
- mAdapter = adapter;
- mComponentToAppMap = componentToAppMap;
- mNumPredictedAppsPerRow = numPredictedAppsPerRow;
- setVisibility(mPredictedAppComponents.isEmpty() ? View.GONE : View.VISIBLE);
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(getExpectedHeight(),
- MeasureSpec.EXACTLY));
- }
-
- public int getExpectedHeight() {
- int height = 0;
- if (!mPredictedAppComponents.isEmpty()) {
- height += Launcher.getLauncher(getContext())
- .getDeviceProfile().allAppsCellHeightPx;
- height += getPaddingTop() + getPaddingBottom();
- }
- return height;
- }
-
- public void setShowDivider(boolean showDivider) {
- mShowDivider = showDivider;
- int paddingBottom = showDivider ? getResources()
- .getDimensionPixelSize(R.dimen.all_apps_prediction_row_divider_height) : 0;
- setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), paddingBottom);
- }
-
- /**
- * Sets the number of apps per row.
- */
- public void setNumAppsPerRow(int numPredictedAppsPerRow) {
- if (mNumPredictedAppsPerRow != numPredictedAppsPerRow) {
- mNumPredictedAppsPerRow = numPredictedAppsPerRow;
- onPredictionsUpdated();
- }
- }
-
- /**
- * Returns the predicted apps.
- */
- public List<AppInfo> getPredictedApps() {
- return mPredictedApps;
- }
-
- /**
- * Sets the current set of predicted apps.
- *
- * This can be called before we get the full set of applications, we should merge the results
- * only in onPredictionsUpdated() which is idempotent.
- *
- * If the number of predicted apps is the same as the previous list of predicted apps,
- * we can optimize by swapping them in place.
- */
- public void setPredictedApps(List<ComponentKeyMapper<AppInfo>> apps) {
- mPredictedAppComponents.clear();
- mPredictedAppComponents.addAll(apps);
- mPredictedApps.clear();
- mPredictedApps.addAll(processPredictedAppComponents(mPredictedAppComponents));
- onPredictionsUpdated();
- }
-
- private void onPredictionsUpdated() {
- int childCountBefore = getChildCount();
- if (getChildCount() != mNumPredictedAppsPerRow) {
- while (getChildCount() > mNumPredictedAppsPerRow) {
- removeViewAt(0);
- }
- while (getChildCount() < mNumPredictedAppsPerRow) {
- AllAppsGridAdapter.ViewHolder holder = mAdapter
- .onCreateViewHolder(this, AllAppsGridAdapter.VIEW_TYPE_ICON);
- BubbleTextView icon = (BubbleTextView) holder.itemView;
- LinearLayout.LayoutParams params =
- new LayoutParams(0, icon.getLayoutParams().height);
- params.weight = 1;
- icon.setLayoutParams(params);
- addView(icon);
- }
- }
-
- for (int i = 0; i < getChildCount(); i++) {
- BubbleTextView icon = (BubbleTextView) getChildAt(i);
- icon.reset();
- if (mPredictedApps.size() > i) {
- icon.setVisibility(View.VISIBLE);
- icon.applyFromApplicationInfo(mPredictedApps.get(i));
- } else {
- icon.setVisibility(View.INVISIBLE);
- }
- }
-
- if (getChildCount() > 0 && childCountBefore == 0
- || getChildCount() == 0 && childCountBefore > 0) {
- // setting up header to adjust the height
- // only necessary if childcount switches from/to 0
- Launcher.getLauncher(getContext()).getAppsView().setupHeader();
- }
- }
-
- /**
- * Refreshes the app icons in the row view, while preserving the same set of predictions.
- */
- public void onAppsUpdated() {
- for (int i = 0; i < getChildCount(); i++) {
- View child = getChildAt(i);
- if (!(child instanceof BubbleTextView)) {
- continue;
- }
- if (i >= mPredictedApps.size()) {
- break;
- }
- BubbleTextView icon = (BubbleTextView) getChildAt(i);
- icon.reset();
- icon.applyFromApplicationInfo(mPredictedApps.get(i));
- }
- }
-
- private List<AppInfo> processPredictedAppComponents(
- List<ComponentKeyMapper<AppInfo>> components) {
- if (mComponentToAppMap.isEmpty()) {
- // Apps have not been bound yet.
- return Collections.emptyList();
- }
-
- List<AppInfo> predictedApps = new ArrayList<>();
- for (ComponentKeyMapper<AppInfo> mapper : components) {
- AppInfo info = mapper.getItem(mComponentToAppMap);
- if (info != null) {
- predictedApps.add(info);
- } else {
- if (FeatureFlags.IS_DOGFOOD_BUILD) {
- Log.e(TAG, "Predicted app not found: " + mapper);
- }
- }
- // Stop at the number of predicted apps
- if (predictedApps.size() == mNumPredictedAppsPerRow) {
- break;
- }
- }
- return predictedApps;
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
-
- if (mShowDivider) {
- int side = getResources().getDimensionPixelSize(R.dimen.dynamic_grid_edge_margin);
- int y = getHeight() - (getPaddingBottom() / 2);
- int x1 = getPaddingLeft() + side;
- int x2 = getWidth() - getPaddingRight() - side;
- canvas.drawLine(x1, y, x2, y, mPaint);
- }
- }
-
- @Override
- public void fillInLogContainerData(View v, ItemInfo info, LauncherLogProto.Target target,
- LauncherLogProto.Target targetParent) {
- for (int i = 0; i < mPredictedApps.size(); i++) {
- AppInfo appInfo = mPredictedApps.get(i);
- if (appInfo == info) {
- targetParent.containerType = LauncherLogProto.ContainerType.PREDICTION;
- target.predictedRank = i;
- break;
- }
- }
- }
-}
diff --git a/src/com/android/launcher3/allapps/SearchUiManager.java b/src/com/android/launcher3/allapps/SearchUiManager.java
index f562b6a..bb17ed5 100644
--- a/src/com/android/launcher3/allapps/SearchUiManager.java
+++ b/src/com/android/launcher3/allapps/SearchUiManager.java
@@ -35,12 +35,6 @@
@NonNull SpringAnimation getSpringForFling();
/**
- * Notifies the search manager that the apps-list has changed and the search UI should be
- * updated accordingly.
- */
- void refreshSearchResult();
-
- /**
* Notifies the search manager to close any active search session.
*/
void reset();
diff --git a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
index 6f07eeb..fca3e47 100644
--- a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
+++ b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
@@ -37,6 +37,7 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.allapps.AllAppsContainerView;
+import com.android.launcher3.allapps.AllAppsStore;
import com.android.launcher3.allapps.AlphabeticalAppsList;
import com.android.launcher3.allapps.SearchUiManager;
import com.android.launcher3.graphics.TintedDrawableSpan;
@@ -48,7 +49,8 @@
* Layout to contain the All-apps search UI.
*/
public class AppsSearchContainerLayout extends FrameLayout
- implements SearchUiManager, AllAppsSearchBarController.Callbacks {
+ implements SearchUiManager, AllAppsSearchBarController.Callbacks,
+ AllAppsStore.OnUpdateListener {
private final Launcher mLauncher;
private final int mMinHeight;
@@ -111,6 +113,18 @@
}
@Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ mLauncher.getAppsView().getAppsStore().addUpdateListener(this);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ mLauncher.getAppsView().getAppsStore().removeUpdateListener(this);
+ }
+
+ @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (!mLauncher.getDeviceProfile().isVerticalBarLayout()) {
getLayoutParams().height = mLauncher.getDragLayer().getInsets().top + mMinHeight;
@@ -134,7 +148,7 @@
}
@Override
- public void refreshSearchResult() {
+ public void onAppsUpdated() {
mSearchBarController.refreshSearchResult();
}
diff --git a/src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java b/src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java
index f3b0d61..4cbf673 100644
--- a/src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java
+++ b/src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java
@@ -22,6 +22,7 @@
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewConfiguration;
+import android.view.accessibility.AccessibilityManager;
import android.widget.FrameLayout;
import com.android.launcher3.DeviceProfile;
@@ -55,6 +56,7 @@
private final Handler mDelayedLineFadeHandler = new Handler(Looper.getMainLooper());
private final Launcher mLauncher;
+ private final AccessibilityManager mAccessibilityManager;
private boolean mShouldAutoHide = true;
@@ -136,6 +138,8 @@
boolean darkText = WallpaperColorInfo.getInstance(context).supportsDarkText();
mActiveAlpha = darkText ? BLACK_ALPHA : WHITE_ALPHA;
mLinePaint.setColor(darkText ? Color.BLACK : Color.WHITE);
+ mAccessibilityManager = (AccessibilityManager)
+ getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
}
@Override
@@ -274,7 +278,7 @@
setBackgroundResource(0);
setOnFocusChangeListener(null);
- setOnClickListener(null);
+ setOnClickListener(mAccessibilityManager.isTouchExplorationEnabled() ? this : null);
}
setLayoutParams(lp);
diff --git a/src/com/android/launcher3/util/ComponentKeyMapper.java b/src/com/android/launcher3/util/ComponentKeyMapper.java
index 916176a..a7f0d76 100644
--- a/src/com/android/launcher3/util/ComponentKeyMapper.java
+++ b/src/com/android/launcher3/util/ComponentKeyMapper.java
@@ -18,8 +18,6 @@
import android.support.annotation.Nullable;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Map;
public class ComponentKeyMapper<T> {