callbacks) {
+ super(app, dataModel, allAppsList, pageToBindFirst, callbacks);
+ }
+
+ @Override
+ public void bindDeepShortcuts() {
+ }
+
+ @Override
+ public void bindWidgets() {
+ }
+}
diff --git a/go/src/com/android/launcher3/model/WidgetsModel.java b/go/src/com/android/launcher3/model/WidgetsModel.java
new file mode 100644
index 0000000000..18f3f9d91c
--- /dev/null
+++ b/go/src/com/android/launcher3/model/WidgetsModel.java
@@ -0,0 +1,67 @@
+/*
+ * 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.model;
+
+import android.content.Context;
+import android.os.UserHandle;
+
+import com.android.launcher3.icons.ComponentWithLabel;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.util.PackageUserKey;
+import com.android.launcher3.widget.WidgetListRowEntry;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import androidx.annotation.Nullable;
+
+/**
+ * Widgets data model that is used by the adapters of the widget views and controllers.
+ *
+ * The widgets and shortcuts are organized using package name as its index.
+ */
+public class WidgetsModel {
+ private static final ArrayList EMPTY_WIDGET_LIST = new ArrayList<>();
+
+ /**
+ * Returns a list of {@link WidgetListRowEntry}. All {@link WidgetItem} in a single row
+ * are sorted (based on label and user), but the overall list of {@link WidgetListRowEntry}s
+ * is not sorted. This list is sorted at the UI when using
+ * {@link com.android.launcher3.widget.WidgetsDiffReporter}
+ *
+ * @see com.android.launcher3.widget.WidgetsListAdapter#setWidgets(ArrayList)
+ */
+ public synchronized ArrayList getWidgetsList(Context context) {
+ return EMPTY_WIDGET_LIST;
+ }
+
+ /**
+ * @param packageUser If null, all widgets and shortcuts are updated and returned, otherwise
+ * only widgets and shortcuts associated with the package/user are.
+ */
+ public List update(LauncherAppState app,
+ @Nullable PackageUserKey packageUser) {
+ return Collections.emptyList();
+ }
+
+
+ public void onPackageIconsUpdated(Set packageNames, UserHandle user,
+ LauncherAppState app) {
+ }
+}
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000000..b299cfe516
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,13 @@
+# Until all the dependencies move to android X
+android.useAndroidX = true
+android.enableJetifier = true
+
+ANDROID_X_VERSION=1.0.0-beta01
+
+GRADLE_CLASS_PATH=com.android.tools.build:gradle:3.2.0-rc03
+
+PROTOBUF_CLASS_PATH=com.google.protobuf:protobuf-gradle-plugin:0.8.6
+PROTOBUF_DEPENDENCY=com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-7
+
+BUILD_TOOLS_VERSION=28.0.3
+COMPILE_SDK=28
\ No newline at end of file
diff --git a/iconloaderlib/Android.bp b/iconloaderlib/Android.bp
new file mode 100644
index 0000000000..8a71f94ed8
--- /dev/null
+++ b/iconloaderlib/Android.bp
@@ -0,0 +1,28 @@
+// 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.
+
+android_library {
+ name: "iconloader",
+ sdk_version: "28",
+ min_sdk_version: "21",
+ static_libs: [
+ "androidx.core_core",
+ ],
+ resource_dirs: [
+ "res",
+ ],
+ srcs: [
+ "src/**/*.java",
+ ],
+}
diff --git a/res/layout/hotseat.xml b/iconloaderlib/AndroidManifest.xml
similarity index 51%
rename from res/layout/hotseat.xml
rename to iconloaderlib/AndroidManifest.xml
index 00f0b5ff8a..b30258da2a 100644
--- a/res/layout/hotseat.xml
+++ b/iconloaderlib/AndroidManifest.xml
@@ -1,5 +1,6 @@
-
-
-
-
+
+
diff --git a/iconloaderlib/build.gradle b/iconloaderlib/build.gradle
new file mode 100644
index 0000000000..d08029386a
--- /dev/null
+++ b/iconloaderlib/build.gradle
@@ -0,0 +1,50 @@
+buildscript {
+ repositories {
+ mavenCentral()
+ google()
+ }
+ dependencies {
+ classpath GRADLE_CLASS_PATH
+ }
+}
+
+apply plugin: 'com.android.library'
+
+android {
+ compileSdkVersion COMPILE_SDK.toInteger()
+ buildToolsVersion BUILD_TOOLS_VERSION
+ publishNonDefault true
+
+ defaultConfig {
+ minSdkVersion 21
+ targetSdkVersion 28
+ versionCode 1
+ versionName "1.0"
+ }
+
+ sourceSets {
+ main {
+ java.srcDirs = ['src']
+ manifest.srcFile 'AndroidManifest.xml'
+ res.srcDirs = ['res']
+ }
+ }
+
+ lintOptions {
+ abortOnError false
+ }
+
+ tasks.withType(JavaCompile) {
+ options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
+ }
+}
+
+
+repositories {
+ mavenCentral()
+ google()
+}
+
+dependencies {
+ implementation "androidx.core:core:${ANDROID_X_VERSION}"
+}
diff --git a/res/drawable-v26/adaptive_icon_drawable_wrapper.xml b/iconloaderlib/res/drawable-v26/adaptive_icon_drawable_wrapper.xml
similarity index 100%
rename from res/drawable-v26/adaptive_icon_drawable_wrapper.xml
rename to iconloaderlib/res/drawable-v26/adaptive_icon_drawable_wrapper.xml
diff --git a/res/drawable/ic_instant_app_badge.xml b/iconloaderlib/res/drawable/ic_instant_app_badge.xml
similarity index 93%
rename from res/drawable/ic_instant_app_badge.xml
rename to iconloaderlib/res/drawable/ic_instant_app_badge.xml
index cc532309c9..b74317e5f2 100644
--- a/res/drawable/ic_instant_app_badge.xml
+++ b/iconloaderlib/res/drawable/ic_instant_app_badge.xml
@@ -21,23 +21,19 @@
-
\ No newline at end of file
+
diff --git a/iconloaderlib/res/values/colors.xml b/iconloaderlib/res/values/colors.xml
new file mode 100644
index 0000000000..873b2fc5fb
--- /dev/null
+++ b/iconloaderlib/res/values/colors.xml
@@ -0,0 +1,21 @@
+
+
+
+ #FFFFFF
+
diff --git a/iconloaderlib/res/values/dimens.xml b/iconloaderlib/res/values/dimens.xml
new file mode 100644
index 0000000000..e8c0c44f72
--- /dev/null
+++ b/iconloaderlib/res/values/dimens.xml
@@ -0,0 +1,19 @@
+
+
+
+
+ 24dp
+
diff --git a/src/com/android/launcher3/icons/BaseIconFactory.java b/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java
similarity index 98%
rename from src/com/android/launcher3/icons/BaseIconFactory.java
rename to iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java
index cd60de55a8..243903cc8c 100644
--- a/src/com/android/launcher3/icons/BaseIconFactory.java
+++ b/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java
@@ -18,8 +18,6 @@ import android.os.Build;
import android.os.Process;
import android.os.UserHandle;
-import com.android.launcher3.R;
-
import static android.graphics.Paint.DITHER_FLAG;
import static android.graphics.Paint.FILTER_BITMAP_FLAG;
import static com.android.launcher3.icons.ShadowGenerator.BLUR_FACTOR;
@@ -81,6 +79,7 @@ public class BaseIconFactory {
return mNormalizer;
}
+ @SuppressWarnings("deprecation")
public BitmapInfo createIconBitmap(Intent.ShortcutIconResource iconRes) {
try {
Resources resources = mPm.getResourcesForApplication(iconRes.packageName);
@@ -184,8 +183,7 @@ public class BaseIconFactory {
RectF outIconBounds, float[] outScale) {
float scale = 1f;
- if (shrinkNonAdaptiveIcons) {
- boolean[] outShape = new boolean[1];
+ if (shrinkNonAdaptiveIcons && ATLEAST_OREO) {
if (mWrapperIcon == null) {
mWrapperIcon = mContext.getDrawable(R.drawable.adaptive_icon_drawable_wrapper)
.mutate();
@@ -193,7 +191,7 @@ public class BaseIconFactory {
AdaptiveIconDrawable dr = (AdaptiveIconDrawable) mWrapperIcon;
dr.setBounds(0, 0, 1, 1);
scale = getNormalizer().getScale(icon, outIconBounds);
- if (ATLEAST_OREO && !(icon instanceof AdaptiveIconDrawable)) {
+ if (!(icon instanceof AdaptiveIconDrawable)) {
FixedScaleDrawable fsd = ((FixedScaleDrawable) dr.getForeground());
fsd.setDrawable(icon);
fsd.setScale(scale);
diff --git a/src/com/android/launcher3/icons/BitmapInfo.java b/iconloaderlib/src/com/android/launcher3/icons/BitmapInfo.java
similarity index 100%
rename from src/com/android/launcher3/icons/BitmapInfo.java
rename to iconloaderlib/src/com/android/launcher3/icons/BitmapInfo.java
diff --git a/src/com/android/launcher3/icons/ColorExtractor.java b/iconloaderlib/src/com/android/launcher3/icons/ColorExtractor.java
similarity index 100%
rename from src/com/android/launcher3/icons/ColorExtractor.java
rename to iconloaderlib/src/com/android/launcher3/icons/ColorExtractor.java
diff --git a/src/com/android/launcher3/icons/FixedScaleDrawable.java b/iconloaderlib/src/com/android/launcher3/icons/FixedScaleDrawable.java
similarity index 100%
rename from src/com/android/launcher3/icons/FixedScaleDrawable.java
rename to iconloaderlib/src/com/android/launcher3/icons/FixedScaleDrawable.java
diff --git a/iconloaderlib/src/com/android/launcher3/icons/GraphicsUtils.java b/iconloaderlib/src/com/android/launcher3/icons/GraphicsUtils.java
new file mode 100644
index 0000000000..b096cecb5c
--- /dev/null
+++ b/iconloaderlib/src/com/android/launcher3/icons/GraphicsUtils.java
@@ -0,0 +1,36 @@
+/*
+ * 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.icons;
+
+import androidx.annotation.ColorInt;
+
+public class GraphicsUtils {
+
+ /**
+ * Set the alpha component of {@code color} to be {@code alpha}. Unlike the support lib version,
+ * it bounds the alpha in valid range instead of throwing an exception to allow for safer
+ * interpolation of color animations
+ */
+ @ColorInt
+ public static int setColorAlphaBound(int color, int alpha) {
+ if (alpha < 0) {
+ alpha = 0;
+ } else if (alpha > 255) {
+ alpha = 255;
+ }
+ return (color & 0x00ffffff) | (alpha << 24);
+ }
+}
diff --git a/src/com/android/launcher3/icons/IconNormalizer.java b/iconloaderlib/src/com/android/launcher3/icons/IconNormalizer.java
similarity index 98%
rename from src/com/android/launcher3/icons/IconNormalizer.java
rename to iconloaderlib/src/com/android/launcher3/icons/IconNormalizer.java
index 8eb82524e8..05908df99b 100644
--- a/src/com/android/launcher3/icons/IconNormalizer.java
+++ b/iconloaderlib/src/com/android/launcher3/icons/IconNormalizer.java
@@ -20,9 +20,6 @@ import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.AdaptiveIconDrawable;
diff --git a/src/com/android/launcher3/icons/ShadowGenerator.java b/iconloaderlib/src/com/android/launcher3/icons/ShadowGenerator.java
similarity index 96%
rename from src/com/android/launcher3/icons/ShadowGenerator.java
rename to iconloaderlib/src/com/android/launcher3/icons/ShadowGenerator.java
index 6491b7ec15..455c58c91b 100644
--- a/src/com/android/launcher3/icons/ShadowGenerator.java
+++ b/iconloaderlib/src/com/android/launcher3/icons/ShadowGenerator.java
@@ -16,6 +16,8 @@
package com.android.launcher3.icons;
+import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
+
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BlurMaskFilter;
@@ -27,8 +29,6 @@ import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
-import androidx.core.graphics.ColorUtils;
-
/**
* Utility class to add shadows to bitmaps.
*/
@@ -142,12 +142,12 @@ public class ShadowGenerator {
// Key shadow
p.setShadowLayer(shadowBlur, 0, keyShadowDistance,
- ColorUtils.setAlphaComponent(Color.BLACK, keyShadowAlpha));
+ setColorAlphaBound(Color.BLACK, keyShadowAlpha));
c.drawRoundRect(bounds, radius, radius, p);
// Ambient shadow
p.setShadowLayer(shadowBlur, 0, 0,
- ColorUtils.setAlphaComponent(Color.BLACK, ambientShadowAlpha));
+ setColorAlphaBound(Color.BLACK, ambientShadowAlpha));
c.drawRoundRect(bounds, radius, radius, p);
if (Color.alpha(color) < 255) {
diff --git a/libs/README.txt b/libs/README.txt
new file mode 100644
index 0000000000..9109592561
--- /dev/null
+++ b/libs/README.txt
@@ -0,0 +1,8 @@
+These jar are compiled in the frameworks/base of the platform tree.
+
+launcher_protos.jar is defined as launcherprotosnano in the following file:
+frameworks/base/core/protos/android/stats/launcher/Android.bp
+
+plugin_core.jar is defined as PluginCoreLib in the following file:
+frameworks/base/packages/SystemUI/plugin/Android.bp
+
diff --git a/libs/launcher_protos.jar b/libs/launcher_protos.jar
new file mode 100644
index 0000000000..c0439363b8
Binary files /dev/null and b/libs/launcher_protos.jar differ
diff --git a/quickstep/libs/sysui_shared.jar b/quickstep/libs/sysui_shared.jar
index 6f3fa4be55..a1b3476a64 100644
Binary files a/quickstep/libs/sysui_shared.jar and b/quickstep/libs/sysui_shared.jar differ
diff --git a/quickstep/res/values/config.xml b/quickstep/res/values/config.xml
index d8ca1c47c1..3fbfcdd6c4 100644
--- a/quickstep/res/values/config.xml
+++ b/quickstep/res/values/config.xml
@@ -20,6 +20,8 @@
com.android.quickstep.logging.UserEventDispatcherExtension
+ com.android.quickstep.logging.StatsLogCompatManager
+
3
diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
index d7bbfe06e1..9e85469363 100644
--- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -420,7 +420,10 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
mLauncher.getWorkspace().getPageIndicator().pauseAnimations();
mDragLayer.setLayerType(View.LAYER_TYPE_HARDWARE, null);
- endListener = this::resetContentView;
+ endListener = () -> {
+ resetContentView();
+ mDragLayer.getScrim().hideSysUiScrim(false);
+ };
}
return new Pair<>(launcherAnimator, endListener);
}
@@ -794,8 +797,6 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
workspaceAnimator.setDuration(333);
workspaceAnimator.setInterpolator(Interpolators.DEACCEL_1_7);
- mDragLayer.getScrim().hideSysUiScrim(true);
-
// Pause page indicator animations as they lead to layer trashing.
mLauncher.getWorkspace().getPageIndicator().pauseAnimations();
mDragLayer.setLayerType(View.LAYER_TYPE_HARDWARE, null);
@@ -815,7 +816,6 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
mDragLayerAlpha.setValue(1f);
mDragLayer.setLayerType(View.LAYER_TYPE_NONE, null);
mDragLayer.setTranslationY(0f);
- mDragLayer.getScrim().hideSysUiScrim(false);
}
private boolean hasControlRemoteAppTransitionPermission() {
diff --git a/quickstep/src/com/android/quickstep/TaskUtils.java b/quickstep/src/com/android/quickstep/TaskUtils.java
index 5cae2b9199..4b86a7fa88 100644
--- a/quickstep/src/com/android/quickstep/TaskUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskUtils.java
@@ -59,7 +59,6 @@ public class TaskUtils {
*/
public static CharSequence getTitle(Context context, Task task) {
LauncherAppsCompat launcherAppsCompat = LauncherAppsCompat.getInstance(context);
- UserManagerCompat userManagerCompat = UserManagerCompat.getInstance(context);
PackageManager packageManager = context.getPackageManager();
UserHandle user = UserHandle.of(task.key.userId);
ApplicationInfo applicationInfo = launcherAppsCompat.getApplicationInfo(
@@ -68,7 +67,7 @@ public class TaskUtils {
Log.e(TAG, "Failed to get title for task " + task);
return "";
}
- return userManagerCompat.getBadgedLabelForUser(
+ return packageManager.getUserBadgedLabel(
applicationInfo.loadLabel(packageManager), user);
}
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
new file mode 100644
index 0000000000..2f411efc7b
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -0,0 +1,105 @@
+/*
+ * 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.content.Intent;
+import android.stats.launcher.nano.LauncherExtension;
+import android.stats.launcher.nano.LauncherTarget;
+
+import static android.stats.launcher.nano.Launcher.ALLAPPS;
+import static android.stats.launcher.nano.Launcher.HOME;
+import static android.stats.launcher.nano.Launcher.LAUNCH_APP;
+import static android.stats.launcher.nano.Launcher.LAUNCH_TASK;
+import static android.stats.launcher.nano.Launcher.BACKGROUND;
+import static android.stats.launcher.nano.Launcher.OVERVIEW;
+
+import android.view.View;
+
+import com.android.launcher3.ItemInfo;
+import com.android.launcher3.logging.StatsLogManager;
+import com.android.launcher3.logging.StatsLogUtils;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
+import com.android.launcher3.util.ComponentKey;
+import com.android.systemui.shared.system.StatsLogCompat;
+import com.google.protobuf.nano.MessageNano;
+
+import androidx.annotation.Nullable;
+
+/**
+ * This method calls the StatsLog hidden method until they are made available public.
+ *
+ * To see if the logs are properly sent to statsd, execute following command.
+ * $ adb root && adb shell statsd
+ * $ adb shell cmd stats print-logs
+ * $ adb logcat | grep statsd OR $ adb logcat -b stats
+ */
+public class StatsLogCompatManager extends StatsLogManager {
+
+ private static final int SUPPORTED_TARGET_DEPTH = 2;
+
+ public StatsLogCompatManager(Context context) { }
+
+ @Override
+ public void logAppLaunch(View v, Intent intent) {
+ LauncherExtension ext = new LauncherExtension();
+ ext.srcTarget = new LauncherTarget[SUPPORTED_TARGET_DEPTH];
+ int srcState = mStateProvider.getCurrentState();
+ fillInLauncherExtension(v, ext);
+ StatsLogCompat.write(LAUNCH_APP, srcState, BACKGROUND /* dstState */,
+ MessageNano.toByteArray(ext), true);
+ }
+
+ @Override
+ public void logTaskLaunch(View v, ComponentKey componentKey) {
+ LauncherExtension ext = new LauncherExtension();
+ ext.srcTarget = new LauncherTarget[SUPPORTED_TARGET_DEPTH];
+ int srcState = OVERVIEW;
+ fillInLauncherExtension(v, ext);
+ StatsLogCompat.write(LAUNCH_TASK, srcState, BACKGROUND /* dstState */,
+ MessageNano.toByteArray(ext), true);
+ }
+
+ public static boolean fillInLauncherExtension(View v, LauncherExtension extension) {
+ StatsLogUtils.LogContainerProvider provider = StatsLogUtils.getLaunchProviderRecursive(v);
+ if (v == null || !(v.getTag() instanceof ItemInfo) || provider == null) {
+ return false;
+ }
+ ItemInfo itemInfo = (ItemInfo) v.getTag();
+ Target child = new Target();
+ Target parent = new Target();
+ provider.fillInLogContainerData(v, itemInfo, child, parent);
+ copy(child, extension.srcTarget[0]);
+ copy(parent, extension.srcTarget[1]);
+ return true;
+ }
+
+ private static void copy(Target src, LauncherTarget dst) {
+ // fill in
+ }
+
+ @Override
+ public void verify() {
+ if(!(StatsLogUtils.LAUNCHER_STATE_ALLAPPS == ALLAPPS &&
+ StatsLogUtils.LAUNCHER_STATE_BACKGROUND == BACKGROUND &&
+ StatsLogUtils.LAUNCHER_STATE_OVERVIEW == OVERVIEW &&
+ StatsLogUtils.LAUNCHER_STATE_HOME == HOME)) {
+ throw new IllegalStateException(
+ "StatsLogUtil constants doesn't match enums in launcher.proto");
+ }
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/logging/UserEventDispatcherExtension.java b/quickstep/src/com/android/quickstep/logging/UserEventDispatcherExtension.java
index 6dff187ea5..4392851c0e 100644
--- a/quickstep/src/com/android/quickstep/logging/UserEventDispatcherExtension.java
+++ b/quickstep/src/com/android/quickstep/logging/UserEventDispatcherExtension.java
@@ -34,6 +34,7 @@ import com.android.systemui.shared.system.MetricsLoggerCompat;
* quickstep interactions.
*/
@SuppressWarnings("unused")
+@Deprecated
public class UserEventDispatcherExtension extends UserEventDispatcher {
private static final String TAG = "UserEventDispatcher";
diff --git a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
index 896557550a..d2b3bcc170 100644
--- a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
+++ b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
@@ -18,8 +18,7 @@ package com.android.quickstep.views;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.anim.Interpolators.ACCEL;
import static com.android.launcher3.anim.Interpolators.LINEAR;
-
-import static androidx.core.graphics.ColorUtils.setAlphaComponent;
+import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
import android.content.Context;
import android.graphics.Canvas;
@@ -141,7 +140,7 @@ public class ShelfScrimView extends ScrimView {
int alpha = Math.round(Utilities.mapToRange(
mProgress, mMidProgress, 1, mMidAlpha, 0, ACCEL));
- mShelfColor = setAlphaComponent(mEndScrim, alpha);
+ mShelfColor = setColorAlphaBound(mEndScrim, alpha);
} else {
mDragHandleOffset += mShiftRange * (mMidProgress - mProgress);
@@ -149,12 +148,12 @@ public class ShelfScrimView extends ScrimView {
int alpha = Math.round(
Utilities.mapToRange(mProgress, (float) 0, mMidProgress, (float) mEndAlpha,
(float) mMidAlpha, Interpolators.clampToProgress(ACCEL, 0.5f, 1f)));
- mShelfColor = setAlphaComponent(mEndScrim, alpha);
+ mShelfColor = setColorAlphaBound(mEndScrim, alpha);
int remainingScrimAlpha = Math.round(
Utilities.mapToRange(mProgress, (float) 0, mMidProgress, mMaxScrimAlpha,
(float) 0, LINEAR));
- mRemainingScreenColor = setAlphaComponent(mScrimColor, remainingScrimAlpha);
+ mRemainingScreenColor = setColorAlphaBound(mScrimColor, remainingScrimAlpha);
}
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 31aaab0607..301b08a3f7 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -167,9 +167,12 @@ public class TaskView extends FrameLayout implements PageCallbacks {
return;
}
launchTask(true /* animate */);
+
fromContext(context).getUserEventDispatcher().logTaskLaunchOrDismiss(
Touch.TAP, Direction.NONE, getRecentsView().indexOfChild(this),
TaskUtils.getLaunchComponentKeyForTask(getTask().key));
+ fromContext(context).getStatsLogManager().logTaskLaunch(getRecentsView(),
+ TaskUtils.getLaunchComponentKeyForTask(getTask().key));
});
setOutlineProvider(new TaskOutlineProvider(getResources()));
}
diff --git a/res/layout/all_apps.xml b/res/layout/all_apps.xml
index 02d793e1c0..b1e6f2efd7 100644
--- a/res/layout/all_apps.xml
+++ b/res/layout/all_apps.xml
@@ -26,7 +26,9 @@
android:focusable="false"
android:saveEnabled="false" >
-
+
diff --git a/res/layout/launcher.xml b/res/layout/launcher.xml
index 304d012d24..87078b93e3 100644
--- a/res/layout/launcher.xml
+++ b/res/layout/launcher.xml
@@ -56,22 +56,25 @@
android:id="@+id/drop_target_bar"
layout="@layout/drop_target_bar" />
-
+ android:layout_height="match_parent" />
-
+ android:layout_height="match_parent"
+ android:theme="@style/HomeScreenElementTheme"
+ android:importantForAccessibility="no"
+ launcher:containerType="hotseat" />
+
diff --git a/res/values/colors.xml b/res/values/colors.xml
index eb207af1eb..3c8fe1e253 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -34,7 +34,6 @@
#757575
#E0E0E0
- #FFFFFF
#E5E5E5
#9AA0A6
diff --git a/res/values/config.xml b/res/values/config.xml
index 5e83ab7666..b33cfa113e 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -84,6 +84,7 @@
+
@@ -130,7 +131,6 @@
-
diff --git a/tests/src/com/android/launcher3/logging/FileLogTest.java b/robolectric_tests/src/com/android/launcher3/logging/FileLogTest.java
similarity index 89%
rename from tests/src/com/android/launcher3/logging/FileLogTest.java
rename to robolectric_tests/src/com/android/launcher3/logging/FileLogTest.java
index e031f1d34a..096db57f90 100644
--- a/tests/src/com/android/launcher3/logging/FileLogTest.java
+++ b/robolectric_tests/src/com/android/launcher3/logging/FileLogTest.java
@@ -1,13 +1,11 @@
package com.android.launcher3.logging;
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
import java.io.File;
import java.io.PrintWriter;
@@ -20,8 +18,7 @@ import static org.junit.Assert.assertTrue;
/**
* Tests for {@link FileLog}
*/
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
public class FileLogTest {
private File mTempDir;
@@ -30,9 +27,9 @@ public class FileLogTest {
public void setUp() throws Exception {
int count = 0;
do {
- mTempDir = new File(InstrumentationRegistry.getTargetContext().getCacheDir(),
+ mTempDir = new File(RuntimeEnvironment.application.getCacheDir(),
"log-test-" + (count++));
- } while(!mTempDir.mkdir());
+ } while (!mTempDir.mkdir());
FileLog.setDir(mTempDir);
}
diff --git a/tests/src/com/android/launcher3/util/GridOccupancyTest.java b/robolectric_tests/src/com/android/launcher3/util/GridOccupancyTest.java
similarity index 92%
rename from tests/src/com/android/launcher3/util/GridOccupancyTest.java
rename to robolectric_tests/src/com/android/launcher3/util/GridOccupancyTest.java
index cbf30b1788..aa51ad20c6 100644
--- a/tests/src/com/android/launcher3/util/GridOccupancyTest.java
+++ b/robolectric_tests/src/com/android/launcher3/util/GridOccupancyTest.java
@@ -1,10 +1,8 @@
package com.android.launcher3.util;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -13,8 +11,7 @@ import static org.junit.Assert.assertTrue;
/**
* Unit tests for {@link GridOccupancy}
*/
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
public class GridOccupancyTest {
@Test
@@ -24,7 +21,7 @@ public class GridOccupancyTest {
0, 0, 1, 1, 0,
0, 0, 0, 0, 0,
1, 1, 0, 0, 0
- );
+ );
int[] vacant = new int[2];
assertTrue(grid.findVacantCell(vacant, 2, 2));
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000000..b52bd4f784
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,2 @@
+include ':IconLoader'
+project(':IconLoader').projectDir = new File(rootDir, 'iconloaderlib')
diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java
index 7b565273f2..77b6010c26 100644
--- a/src/com/android/launcher3/BaseActivity.java
+++ b/src/com/android/launcher3/BaseActivity.java
@@ -28,6 +28,9 @@ import android.view.ContextThemeWrapper;
import android.view.View.AccessibilityDelegate;
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
+import com.android.launcher3.logging.StatsLogManager;
+import com.android.launcher3.logging.StatsLogUtils;
+import com.android.launcher3.logging.StatsLogUtils.LogStateProvider;
import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.logging.UserEventDispatcher.UserEventDelegate;
import com.android.launcher3.uioverrides.UiFactory;
@@ -41,7 +44,7 @@ import java.util.ArrayList;
import androidx.annotation.IntDef;
-public abstract class BaseActivity extends Activity implements UserEventDelegate{
+public abstract class BaseActivity extends Activity implements UserEventDelegate, LogStateProvider{
public static final int INVISIBLE_BY_STATE_HANDLER = 1 << 0;
public static final int INVISIBLE_BY_APP_TRANSITIONS = 1 << 1;
@@ -72,6 +75,7 @@ public abstract class BaseActivity extends Activity implements UserEventDelegate
protected DeviceProfile mDeviceProfile;
protected UserEventDispatcher mUserEventDispatcher;
+ protected StatsLogManager mStatsLogManager;
protected SystemUiController mSystemUiController;
private static final int ACTIVITY_STATE_STARTED = 1 << 0;
@@ -104,8 +108,17 @@ public abstract class BaseActivity extends Activity implements UserEventDelegate
return null;
}
+ public int getCurrentState() { return StatsLogUtils.LAUNCHER_STATE_BACKGROUND; }
+
public void modifyUserEvent(LauncherLogProto.LauncherEvent event) {}
+ public final StatsLogManager getStatsLogManager() {
+ if (mStatsLogManager == null) {
+ mStatsLogManager = StatsLogManager.newInstance(this, this);
+ }
+ return mStatsLogManager;
+ }
+
public final UserEventDispatcher getUserEventDispatcher() {
if (mUserEventDispatcher == null) {
mUserEventDispatcher = UserEventDispatcher.newInstance(this, this);
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index f5fbf80dcd..152dc84d01 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -200,6 +200,7 @@ public abstract class BaseDraggingActivity extends BaseActivity
intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
}
getUserEventDispatcher().logAppLaunch(v, intent);
+ getStatsLogManager().logAppLaunch(v, intent);
return true;
} catch (ActivityNotFoundException|SecurityException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 8513d63a78..455fd1866d 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -16,6 +16,8 @@
package com.android.launcher3;
+import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
@@ -53,8 +55,6 @@ import com.android.launcher3.model.PackageItemInfo;
import java.text.NumberFormat;
-import androidx.core.graphics.ColorUtils;
-
/**
* TextView that draws a bubble behind the text. We cannot use a LineBackgroundSpan
* because we want to make the bubble taller than the text and TextView's clip is
@@ -473,8 +473,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
// Special case to prevent text shadows in high contrast mode
return Color.TRANSPARENT;
}
- return ColorUtils.setAlphaComponent(
- mTextColor, Math.round(Color.alpha(mTextColor) * mTextAlpha));
+ return setColorAlphaBound(mTextColor, Math.round(Color.alpha(mTextColor) * mTextAlpha));
}
/**
diff --git a/src/com/android/launcher3/DragSource.java b/src/com/android/launcher3/DragSource.java
index 93f865c9f9..d4d7b99fd4 100644
--- a/src/com/android/launcher3/DragSource.java
+++ b/src/com/android/launcher3/DragSource.java
@@ -19,7 +19,7 @@ package com.android.launcher3;
import android.view.View;
import com.android.launcher3.DropTarget.DragObject;
-import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider;
+import com.android.launcher3.logging.StatsLogUtils.LogContainerProvider;
/**
* Interface defining an object that can originate a drag.
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 15a9f2e06b..6b5db307bc 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -26,14 +26,13 @@ import android.view.ViewDebug;
import android.view.ViewGroup;
import android.widget.FrameLayout;
-import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
+import com.android.launcher3.logging.StatsLogUtils.LogContainerProvider;
+import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
-public class Hotseat extends FrameLayout implements LogContainerProvider, Insettable {
+public class Hotseat extends CellLayout implements LogContainerProvider, Insettable {
private final Launcher mLauncher;
- private CellLayout mContent;
@ViewDebug.ExportedProperty(category = "launcher")
private boolean mHasVerticalHotseat;
@@ -51,38 +50,23 @@ public class Hotseat extends FrameLayout implements LogContainerProvider, Insett
mLauncher = Launcher.getLauncher(context);
}
- public CellLayout getLayout() {
- return mContent;
- }
-
- /* Get the orientation invariant order of the item in the hotseat for persistence. */
- int getOrderInHotseat(int x, int y) {
- return mHasVerticalHotseat ? (mContent.getCountY() - y - 1) : x;
- }
-
/* Get the orientation specific coordinates given an invariant order in the hotseat. */
int getCellXFromOrder(int rank) {
return mHasVerticalHotseat ? 0 : rank;
}
int getCellYFromOrder(int rank) {
- return mHasVerticalHotseat ? (mContent.getCountY() - (rank + 1)) : 0;
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mContent = findViewById(R.id.layout);
+ return mHasVerticalHotseat ? (getCountY() - (rank + 1)) : 0;
}
void resetLayout(boolean hasVerticalHotseat) {
- mContent.removeAllViewsInLayout();
+ removeAllViewsInLayout();
mHasVerticalHotseat = hasVerticalHotseat;
InvariantDeviceProfile idp = mLauncher.getDeviceProfile().inv;
if (hasVerticalHotseat) {
- mContent.setGridSize(1, idp.numHotseatIcons);
+ setGridSize(1, idp.numHotseatIcons);
} else {
- mContent.setGridSize(idp.numHotseatIcons, 1);
+ setGridSize(idp.numHotseatIcons, 1);
}
}
@@ -90,15 +74,16 @@ public class Hotseat extends FrameLayout implements LogContainerProvider, Insett
public boolean onInterceptTouchEvent(MotionEvent ev) {
// We don't want any clicks to go through to the hotseat unless the workspace is in
// the normal state or an accessible drag is in progress.
- return !mLauncher.getWorkspace().workspaceIconsCanBeDragged() &&
- !mLauncher.getAccessibilityDelegate().isInAccessibleDrag();
+ return (!mLauncher.getWorkspace().workspaceIconsCanBeDragged()
+ && !mLauncher.getAccessibilityDelegate().isInAccessibleDrag())
+ || super.onInterceptTouchEvent(ev);
}
@Override
public void fillInLogContainerData(View v, ItemInfo info, Target target, Target targetParent) {
target.gridX = info.cellX;
target.gridY = info.cellY;
- targetParent.containerType = ContainerType.HOTSEAT;
+ targetParent.containerType = LauncherLogProto.ContainerType.HOTSEAT;
}
@Override
@@ -121,7 +106,7 @@ public class Hotseat extends FrameLayout implements LogContainerProvider, Insett
lp.height = grid.hotseatBarSizePx + insets.bottom;
}
Rect padding = grid.getHotseatLayoutPadding();
- getLayout().setPadding(padding.left, padding.top, padding.right, padding.bottom);
+ setPadding(padding.left, padding.top, padding.right, padding.bottom);
setLayoutParams(lp);
InsettableFrameLayout.dispatchInsets(this, insets);
diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java
index 851454b77b..73c999a923 100644
--- a/src/com/android/launcher3/InstallShortcutReceiver.java
+++ b/src/com/android/launcher3/InstallShortcutReceiver.java
@@ -659,8 +659,8 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
info.applyFrom(iconInfo);
info.title = Utilities.trim(name);
- info.contentDescription = UserManagerCompat.getInstance(app.getContext())
- .getBadgedLabelForUser(info.title, info.user);
+ info.contentDescription = app.getContext().getPackageManager()
+ .getUserBadgedLabel(info.title, info.user);
info.intent = intent;
return info;
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 3ae9a49e70..36967cd4e5 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -91,6 +91,7 @@ import com.android.launcher3.icons.IconCache;
import com.android.launcher3.keyboard.CustomActionsPopup;
import com.android.launcher3.keyboard.ViewGroupFocusHelper;
import com.android.launcher3.logging.FileLog;
+import com.android.launcher3.logging.StatsLogUtils;
import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.logging.UserEventDispatcher.UserEventDelegate;
import com.android.launcher3.model.ModelWriter;
@@ -206,7 +207,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
private final int[] mTmpAddItemCellCoordinates = new int[2];
@Thunk Hotseat mHotseat;
- @Nullable private View mHotseatSearchBox;
private DropTargetBar mDropTargetBar;
@@ -913,7 +913,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
mWorkspace.initParentViews(mDragLayer);
mOverviewPanel = findViewById(R.id.overview_panel);
mHotseat = findViewById(R.id.hotseat);
- mHotseatSearchBox = findViewById(R.id.search_container_hotseat);
mLauncherView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
@@ -1158,10 +1157,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
return mHotseat;
}
- public View getHotseatSearchBox() {
- return mHotseatSearchBox;
- }
-
public T getOverviewPanel() {
return (T) mOverviewPanel;
}
@@ -1609,6 +1604,16 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
}
}
+ @Override
+ public int getCurrentState() {
+ if(mStateManager.getState() == LauncherState.ALL_APPS) {
+ return StatsLogUtils.LAUNCHER_STATE_ALLAPPS;
+ } else if (mStateManager.getState() == LauncherState.OVERVIEW) {
+ return StatsLogUtils.LAUNCHER_STATE_OVERVIEW;
+ }
+ return StatsLogUtils.LAUNCHER_STATE_HOME;
+ }
+
@Override
public void modifyUserEvent(LauncherLogProto.LauncherEvent event) {
if (event.srcTarget != null && event.srcTarget.length > 0 &&
@@ -1643,23 +1648,15 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
boolean isHotseatLayout(View layout) {
// TODO: Remove this method
- return mHotseat != null && layout != null &&
- (layout instanceof CellLayout) && (layout == mHotseat.getLayout());
+ return mHotseat != null && (layout == mHotseat);
}
/**
* Returns the CellLayout of the specified container at the specified screen.
*/
public CellLayout getCellLayout(int container, int screenId) {
- if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
- if (mHotseat != null) {
- return mHotseat.getLayout();
- } else {
- return null;
- }
- } else {
- return mWorkspace.getScreenWithId(screenId);
- }
+ return (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT)
+ ? mHotseat : mWorkspace.getScreenWithId(screenId);
}
@Override
@@ -2270,7 +2267,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
}
writer.println(prefix + " Hotseat");
- ViewGroup layout = mHotseat.getLayout().getShortcutsAndWidgets();
+ ViewGroup layout = mHotseat.getShortcutsAndWidgets();
for (int j = 0; j < layout.getChildCount(); j++) {
Object tag = layout.getChildAt(j).getTag();
if (tag != null) {
diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java
index 7717d91883..19c647fd74 100644
--- a/src/com/android/launcher3/ShortcutInfo.java
+++ b/src/com/android/launcher3/ShortcutInfo.java
@@ -24,7 +24,6 @@ import android.os.Build;
import android.text.TextUtils;
import com.android.launcher3.LauncherSettings.Favorites;
-import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.shortcuts.ShortcutInfoCompat;
import com.android.launcher3.util.ContentWriter;
@@ -172,8 +171,7 @@ public class ShortcutInfo extends ItemInfoWithIcon {
if (TextUtils.isEmpty(label)) {
label = shortcutInfo.getShortLabel();
}
- contentDescription = UserManagerCompat.getInstance(context)
- .getBadgedLabelForUser(label, user);
+ contentDescription = context.getPackageManager().getUserBadgedLabel(label, user);
if (shortcutInfo.isEnabled()) {
runtimeStatusFlags &= ~FLAG_DISABLED_BY_PUBLISHER;
} else {
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 3f7d68d12f..7a8d984d74 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -85,8 +85,8 @@ 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.IntArray;
-import com.android.launcher3.util.IntSparseArrayMap;
import com.android.launcher3.util.IntSet;
+import com.android.launcher3.util.IntSparseArrayMap;
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.Thunk;
@@ -880,7 +880,7 @@ public class Workspace extends PagedView
final CellLayout layout;
if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
- layout = mLauncher.getHotseat().getLayout();
+ layout = mLauncher.getHotseat();
// Hide folder title in the hotseat
if (child instanceof FolderIcon) {
@@ -1517,7 +1517,7 @@ public class Workspace extends PagedView
@Override
protected void enableAccessibleDrag(boolean enable) {
super.enableAccessibleDrag(enable);
- setEnableForLayout(mLauncher.getHotseat().getLayout(),enable);
+ setEnableForLayout(mLauncher.getHotseat(),enable);
}
});
}
@@ -1625,11 +1625,7 @@ public class Workspace extends PagedView
mDragViewVisualCenter = d.getVisualCenter(mDragViewVisualCenter);
// We want the point to be mapped to the dragTarget.
- if (mLauncher.isHotseatLayout(dropTargetLayout)) {
- mapPointFromSelfToHotseatLayout(mLauncher.getHotseat(), mDragViewVisualCenter);
- } else {
- mapPointFromSelfToChild(dropTargetLayout, mDragViewVisualCenter);
- }
+ mapPointFromDropLayout(mLauncher.getHotseat(), mDragViewVisualCenter);
int spanX;
int spanY;
@@ -1831,11 +1827,7 @@ public class Workspace extends PagedView
// We want the point to be mapped to the dragTarget.
if (dropTargetLayout != null) {
- if (mLauncher.isHotseatLayout(dropTargetLayout)) {
- mapPointFromSelfToHotseatLayout(mLauncher.getHotseat(), mDragViewVisualCenter);
- } else {
- mapPointFromSelfToChild(dropTargetLayout, mDragViewVisualCenter);
- }
+ mapPointFromDropLayout(mLauncher.getHotseat(), mDragViewVisualCenter);
}
boolean droppedOnOriginalCell = false;
@@ -2195,7 +2187,7 @@ public class Workspace extends PagedView
* Convert the 2D coordinate xy from the parent View's coordinate space to this CellLayout's
* coordinate space. The argument xy is modified with the return result.
*/
- void mapPointFromSelfToChild(View v, float[] xy) {
+ private void mapPointFromSelfToChild(View v, float[] xy) {
xy[0] = xy[0] - v.getLeft();
xy[1] = xy[1] - v.getTop();
}
@@ -2211,14 +2203,23 @@ public class Workspace extends PagedView
mTempXY[1] <= hotseat.getBottom();
}
- void mapPointFromSelfToHotseatLayout(Hotseat hotseat, float[] xy) {
- mTempXY[0] = (int) xy[0];
- mTempXY[1] = (int) xy[1];
- mLauncher.getDragLayer().getDescendantCoordRelativeToSelf(this, mTempXY, true);
- mLauncher.getDragLayer().mapCoordInSelfToDescendant(hotseat.getLayout(), mTempXY);
+ /**
+ * Updates the point in {@param xy} to point to the co-ordinate space of {@param layout}
+ * @param layout either hotseat of a page in workspace
+ * @param xy the point location in workspace co-ordinate space
+ */
+ private void mapPointFromDropLayout(CellLayout layout, float[] xy) {
+ if (mLauncher.isHotseatLayout(layout)) {
+ mTempXY[0] = (int) xy[0];
+ mTempXY[1] = (int) xy[1];
+ mLauncher.getDragLayer().getDescendantCoordRelativeToSelf(this, mTempXY, true);
+ mLauncher.getDragLayer().mapCoordInSelfToDescendant(layout, mTempXY);
- xy[0] = mTempXY[0];
- xy[1] = mTempXY[1];
+ xy[0] = mTempXY[0];
+ xy[1] = mTempXY[1];
+ } else {
+ mapPointFromSelfToChild(layout, xy);
+ }
}
private boolean isDragWidget(DragObject d) {
@@ -2254,11 +2255,7 @@ public class Workspace extends PagedView
// Handle the drag over
if (mDragTargetLayout != null) {
// We want the point to be mapped to the dragTarget.
- if (mLauncher.isHotseatLayout(mDragTargetLayout)) {
- mapPointFromSelfToHotseatLayout(mLauncher.getHotseat(), mDragViewVisualCenter);
- } else {
- mapPointFromSelfToChild(mDragTargetLayout, mDragViewVisualCenter);
- }
+ mapPointFromDropLayout(mLauncher.getHotseat(), mDragViewVisualCenter);
int minSpanX = item.spanX;
int minSpanY = item.spanY;
@@ -2329,7 +2326,7 @@ public class Workspace extends PagedView
// Test to see if we are over the hotseat first
if (mLauncher.getHotseat() != null && !isDragWidget(d)) {
if (isPointInSelfOverHotseat(d.x, d.y)) {
- layout = mLauncher.getHotseat().getLayout();
+ layout = mLauncher.getHotseat();
}
}
@@ -2967,8 +2964,7 @@ public class Workspace extends PagedView
* Returns a specific CellLayout
*/
CellLayout getParentCellLayoutForView(View v) {
- ArrayList layouts = getWorkspaceAndHotseatCellLayouts();
- for (CellLayout layout : layouts) {
+ for (CellLayout layout : getWorkspaceAndHotseatCellLayouts()) {
if (layout.getShortcutsAndWidgets().indexOfChild(v) > -1) {
return layout;
}
@@ -2977,56 +2973,31 @@ public class Workspace extends PagedView
}
/**
- * Returns a list of all the CellLayouts in the workspace.
+ * Returns a list of all the CellLayouts on the Homescreen.
*/
- ArrayList getWorkspaceAndHotseatCellLayouts() {
- ArrayList layouts = new ArrayList<>();
+ private CellLayout[] getWorkspaceAndHotseatCellLayouts() {
int screenCount = getChildCount();
- for (int screen = 0; screen < screenCount; screen++) {
- layouts.add(((CellLayout) getChildAt(screen)));
- }
+ final CellLayout[] layouts;
if (mLauncher.getHotseat() != null) {
- layouts.add(mLauncher.getHotseat().getLayout());
+ layouts = new CellLayout[screenCount + 1];
+ layouts[screenCount] = mLauncher.getHotseat();
+ } else {
+ layouts = new CellLayout[screenCount];
+ }
+ for (int screen = 0; screen < screenCount; screen++) {
+ layouts[screen] = (CellLayout) getChildAt(screen);
}
return layouts;
}
- /**
- * We should only use this to search for specific children. Do not use this method to modify
- * ShortcutsAndWidgetsContainer directly. Includes ShortcutAndWidgetContainers from
- * the hotseat and workspace pages
- */
- ArrayList getAllShortcutAndWidgetContainers() {
- ArrayList childrenLayouts = new ArrayList<>();
- int screenCount = getChildCount();
- for (int screen = 0; screen < screenCount; screen++) {
- childrenLayouts.add(((CellLayout) getChildAt(screen)).getShortcutsAndWidgets());
- }
- if (mLauncher.getHotseat() != null) {
- childrenLayouts.add(mLauncher.getHotseat().getLayout().getShortcutsAndWidgets());
- }
- return childrenLayouts;
- }
-
public View getHomescreenIconByItemId(final int id) {
- return getFirstMatch(new ItemOperator() {
-
- @Override
- public boolean evaluate(ItemInfo info, View v) {
- return info != null && info.id == id;
- }
- });
+ return getFirstMatch((info, v) -> info != null && info.id == id);
}
public LauncherAppWidgetHostView getWidgetForAppWidgetId(final int appWidgetId) {
- return (LauncherAppWidgetHostView) getFirstMatch(new ItemOperator() {
-
- @Override
- public boolean evaluate(ItemInfo info, View v) {
- return (info instanceof LauncherAppWidgetInfo) &&
- ((LauncherAppWidgetInfo) info).appWidgetId == appWidgetId;
- }
- });
+ return (LauncherAppWidgetHostView) getFirstMatch((info, v) ->
+ (info instanceof LauncherAppWidgetInfo) &&
+ ((LauncherAppWidgetInfo) info).appWidgetId == appWidgetId);
}
public View getFirstMatch(final ItemOperator operator) {
@@ -3063,8 +3034,7 @@ public class Workspace extends PagedView
* shortcuts are not removed.
*/
public void removeItemsByMatcher(final ItemInfoMatcher matcher) {
- ArrayList cellLayouts = getWorkspaceAndHotseatCellLayouts();
- for (final CellLayout layoutParent: cellLayouts) {
+ for (final CellLayout layoutParent: getWorkspaceAndHotseatCellLayouts()) {
final ViewGroup layout = layoutParent.getShortcutsAndWidgets();
IntSparseArrayMap idToViewMap = new IntSparseArrayMap<>();
@@ -3122,10 +3092,8 @@ public class Workspace extends PagedView
* @param op the operator to map over the shortcuts
*/
public void mapOverItems(boolean recurse, ItemOperator op) {
- ArrayList containers = getAllShortcutAndWidgetContainers();
- final int containerCount = containers.size();
- for (int containerIdx = 0; containerIdx < containerCount; containerIdx++) {
- ShortcutAndWidgetContainer container = containers.get(containerIdx);
+ for (CellLayout layout : getWorkspaceAndHotseatCellLayouts()) {
+ ShortcutAndWidgetContainer container = layout.getShortcutsAndWidgets();
// map over all the shortcuts on the workspace
final int itemCount = container.getChildCount();
for (int itemIdx = 0; itemIdx < itemCount; itemIdx++) {
diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
index e734e70533..3e094935d9 100644
--- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
+++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
@@ -88,7 +88,7 @@ public class WorkspaceStateTransitionAnimation {
Interpolator scaleInterpolator = builder.getInterpolator(ANIM_WORKSPACE_SCALE, ZOOM_OUT);
propertySetter.setFloat(mWorkspace, SCALE_PROPERTY, mNewScale, scaleInterpolator);
float hotseatIconsAlpha = (elements & HOTSEAT_ICONS) != 0 ? 1 : 0;
- propertySetter.setViewAlpha(mLauncher.getHotseat().getLayout(), hotseatIconsAlpha,
+ propertySetter.setViewAlpha(mLauncher.getHotseat(), hotseatIconsAlpha,
fadeInterpolator);
propertySetter.setViewAlpha(mLauncher.getWorkspace().getPageIndicator(),
hotseatIconsAlpha, fadeInterpolator);
@@ -105,9 +105,6 @@ public class WorkspaceStateTransitionAnimation {
propertySetter.setFloat(mWorkspace, View.TRANSLATION_Y,
scaleAndTranslation[2], translationInterpolator);
- propertySetter.setViewAlpha(mLauncher.getHotseatSearchBox(),
- (elements & HOTSEAT_SEARCH_BOX) != 0 ? 1 : 0, fadeInterpolator);
-
// Set scrim
WorkspaceAndHotseatScrim scrim = mLauncher.getDragLayer().getScrim();
propertySetter.setFloat(scrim, SCRIM_PROGRESS, state.getWorkspaceScrimAlpha(mLauncher),
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index fa07d4d75c..180ca48166 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -33,7 +33,7 @@ import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.graphics.DrawableFactory;
-import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider;
+import com.android.launcher3.logging.StatsLogUtils.LogContainerProvider;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
import com.android.launcher3.views.RecyclerViewFastScroller;
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index e7313e8411..2d6be7b08c 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -91,11 +91,6 @@ public class AllAppsTransitionController implements StateHandler, OnDeviceProfil
return mShiftRange;
}
- private void onProgressAnimationStart() {
- // Initialize values that should not change until #onDragEnd
- mAppsView.setVisibility(View.VISIBLE);
- }
-
@Override
public void onDeviceProfileChanged(DeviceProfile dp) {
mIsVerticalLayout = dp.isVerticalBarLayout();
@@ -195,16 +190,15 @@ public class AllAppsTransitionController implements StateHandler, OnDeviceProfil
PropertySetter setter = config == null ? NO_ANIM_PROPERTY_SETTER
: config.getPropertySetter(builder);
int visibleElements = toState.getVisibleElements(mLauncher);
- boolean hasHeader = (visibleElements & ALL_APPS_HEADER) != 0;
boolean hasHeaderExtra = (visibleElements & ALL_APPS_HEADER_EXTRA) != 0;
boolean hasContent = (visibleElements & ALL_APPS_CONTENT) != 0;
Interpolator allAppsFade = builder.getInterpolator(ANIM_ALL_APPS_FADE, LINEAR);
- setter.setViewAlpha(mAppsView.getSearchView(), hasHeader ? 1 : 0, allAppsFade);
setter.setViewAlpha(mAppsView.getContentView(), hasContent ? 1 : 0, allAppsFade);
setter.setViewAlpha(mAppsView.getScrollBar(), hasContent ? 1 : 0, allAppsFade);
mAppsView.getFloatingHeaderView().setContentVisibility(hasHeaderExtra, hasContent, setter,
allAppsFade);
+ mAppsView.getSearchUiManager().setContentVisibility(visibleElements, setter, allAppsFade);
setter.setInt(mScrimView, ScrimView.DRAG_HANDLE_ALPHA,
(visibleElements & VERTICAL_SWIPE_INDICATOR) != 0 ? 255 : 0, LINEAR);
@@ -216,11 +210,6 @@ public class AllAppsTransitionController implements StateHandler, OnDeviceProfil
public void onAnimationSuccess(Animator animator) {
onProgressAnimationEnd();
}
-
- @Override
- public void onAnimationStart(Animator animation) {
- onProgressAnimationStart();
- }
};
}
@@ -247,13 +236,9 @@ public class AllAppsTransitionController implements StateHandler, OnDeviceProfil
*/
private void onProgressAnimationEnd() {
if (Float.compare(mProgress, 1f) == 0) {
- mAppsView.setVisibility(View.INVISIBLE);
mAppsView.reset(false /* animate */);
} else if (isAllAppsExpanded()) {
- mAppsView.setVisibility(View.VISIBLE);
mAppsView.onScrollUpEnd();
- } else {
- mAppsView.setVisibility(View.VISIBLE);
}
}
diff --git a/src/com/android/launcher3/allapps/SearchUiManager.java b/src/com/android/launcher3/allapps/SearchUiManager.java
index 68193f5c1c..51b90f71eb 100644
--- a/src/com/android/launcher3/allapps/SearchUiManager.java
+++ b/src/com/android/launcher3/allapps/SearchUiManager.java
@@ -16,6 +16,9 @@
package com.android.launcher3.allapps;
import android.view.KeyEvent;
+import android.view.animation.Interpolator;
+
+import com.android.launcher3.anim.PropertySetter;
/**
* Interface for controlling the Apps search UI.
@@ -37,4 +40,10 @@ public interface SearchUiManager {
* some UI beforehand.
*/
void preDispatchKeyEvent(KeyEvent keyEvent);
+
+ /**
+ * Called as part of state transition to update the content UI
+ */
+ void setContentVisibility(int visibleElements, PropertySetter setter,
+ Interpolator interpolator);
}
diff --git a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
index 15cc2caae6..b1e23d4e22 100644
--- a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
+++ b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
@@ -19,6 +19,7 @@ import static android.view.View.MeasureSpec.EXACTLY;
import static android.view.View.MeasureSpec.getSize;
import static android.view.View.MeasureSpec.makeMeasureSpec;
+import static com.android.launcher3.LauncherState.ALL_APPS_HEADER;
import static com.android.launcher3.icons.IconNormalizer.ICON_VISIBLE_AREA_FACTOR;
import android.content.Context;
@@ -32,6 +33,7 @@ import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup.MarginLayoutParams;
+import android.view.animation.Interpolator;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.ExtendedEditText;
@@ -42,6 +44,7 @@ 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.anim.PropertySetter;
import com.android.launcher3.graphics.TintedDrawableSpan;
import com.android.launcher3.util.ComponentKey;
@@ -214,4 +217,10 @@ public class AppsSearchContainerLayout extends ExtendedEditText
insets.bottom + mlp.topMargin + mFixedTranslationY);
}
}
+
+ @Override
+ public void setContentVisibility(int visibleElements, PropertySetter setter,
+ Interpolator interpolator) {
+ setter.setViewAlpha(this, (visibleElements & ALL_APPS_HEADER) != 0 ? 1 : 0, interpolator);
+ }
}
diff --git a/src/com/android/launcher3/compat/UserManagerCompat.java b/src/com/android/launcher3/compat/UserManagerCompat.java
index ad5147734e..e13d2a6e17 100644
--- a/src/com/android/launcher3/compat/UserManagerCompat.java
+++ b/src/com/android/launcher3/compat/UserManagerCompat.java
@@ -57,7 +57,6 @@ public abstract class UserManagerCompat {
public abstract List getUserProfiles();
public abstract long getSerialNumberForUser(UserHandle user);
public abstract UserHandle getUserForSerialNumber(long serialNumber);
- public abstract CharSequence getBadgedLabelForUser(CharSequence label, UserHandle user);
public abstract boolean isQuietModeEnabled(UserHandle user);
public abstract boolean isUserUnlocked(UserHandle user);
diff --git a/src/com/android/launcher3/compat/UserManagerCompatVL.java b/src/com/android/launcher3/compat/UserManagerCompatVL.java
index ef7284226b..4688052830 100644
--- a/src/com/android/launcher3/compat/UserManagerCompatVL.java
+++ b/src/com/android/launcher3/compat/UserManagerCompatVL.java
@@ -17,7 +17,6 @@
package com.android.launcher3.compat;
import android.content.Context;
-import android.content.pm.PackageManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.ArrayMap;
@@ -30,7 +29,6 @@ import java.util.List;
public class UserManagerCompatVL extends UserManagerCompat {
protected final UserManager mUserManager;
- private final PackageManager mPm;
protected LongSparseArray mUsers;
// Create a separate reverse map as LongSparseArray.indexOfValue checks if objects are same
@@ -39,7 +37,6 @@ public class UserManagerCompatVL extends UserManagerCompat {
UserManagerCompatVL(Context context) {
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
- mPm = context.getPackageManager();
}
@Override
@@ -125,13 +122,5 @@ public class UserManagerCompatVL extends UserManagerCompat {
}
return getUserProfiles().size() > 1;
}
-
- @Override
- public CharSequence getBadgedLabelForUser(CharSequence label, UserHandle user) {
- if (user == null) {
- return label;
- }
- return mPm.getUserBadgedLabel(label, user);
- }
}
diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java
index fa890b99df..2461e284dc 100644
--- a/src/com/android/launcher3/folder/FolderAnimationManager.java
+++ b/src/com/android/launcher3/folder/FolderAnimationManager.java
@@ -20,6 +20,7 @@ import static com.android.launcher3.BubbleTextView.TEXT_ALPHA_PROPERTY;
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.MAX_NUM_ITEMS_IN_PREVIEW;
import static com.android.launcher3.folder.FolderShape.getShape;
+import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -46,8 +47,6 @@ import com.android.launcher3.util.Themes;
import java.util.List;
-import androidx.core.graphics.ColorUtils;
-
/**
* Manages the opening and closing animations for a {@link Folder}.
*
@@ -153,8 +152,8 @@ public class FolderAnimationManager {
// Set up the Folder background.
final int finalColor = Themes.getAttrColor(mContext, android.R.attr.colorPrimary);
- final int initialColor =
- ColorUtils.setAlphaComponent(finalColor, mPreviewBackground.getBackgroundAlpha());
+ final int initialColor = setColorAlphaBound(
+ finalColor, mPreviewBackground.getBackgroundAlpha());
mFolderBackground.mutate();
mFolderBackground.setColor(mIsOpening ? initialColor : finalColor);
diff --git a/src/com/android/launcher3/folder/PreviewBackground.java b/src/com/android/launcher3/folder/PreviewBackground.java
index 8443953bd9..f2683a5f9a 100644
--- a/src/com/android/launcher3/folder/PreviewBackground.java
+++ b/src/com/android/launcher3/folder/PreviewBackground.java
@@ -17,6 +17,7 @@
package com.android.launcher3.folder;
import static com.android.launcher3.folder.FolderShape.getShape;
+import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -41,8 +42,6 @@ import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.util.Themes;
-import androidx.core.graphics.ColorUtils;
-
/**
* This object represents a FolderIcon preview background. It stores drawing / measurement
* information, handles drawing, and animation (accept state <--> rest state).
@@ -189,7 +188,7 @@ public class PreviewBackground {
public int getBgColor() {
int alpha = (int) Math.min(MAX_BG_OPACITY, BG_OPACITY * mColorMultiplier);
- return ColorUtils.setAlphaComponent(mBgColor, alpha);
+ return setColorAlphaBound(mBgColor, alpha);
}
public int getBadgeColor() {
@@ -275,7 +274,7 @@ public class PreviewBackground {
}
public void drawBackgroundStroke(Canvas canvas) {
- mPaint.setColor(ColorUtils.setAlphaComponent(mBgColor, mStrokeAlpha));
+ mPaint.setColor(setColorAlphaBound(mBgColor, mStrokeAlpha));
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(mStrokeWidth);
diff --git a/src/com/android/launcher3/graphics/IconPalette.java b/src/com/android/launcher3/graphics/IconPalette.java
index cda07c31a2..3d4a1001a2 100644
--- a/src/com/android/launcher3/graphics/IconPalette.java
+++ b/src/com/android/launcher3/graphics/IconPalette.java
@@ -16,6 +16,8 @@
package com.android.launcher3.graphics;
+import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
+
import android.app.Notification;
import android.content.Context;
import android.graphics.Color;
@@ -147,7 +149,7 @@ public class IconPalette {
}
public static int getMutedColor(int color, float whiteScrimAlpha) {
- int whiteScrim = ColorUtils.setAlphaComponent(Color.WHITE, (int) (255 * whiteScrimAlpha));
+ int whiteScrim = setColorAlphaBound(Color.WHITE, (int) (255 * whiteScrimAlpha));
return ColorUtils.compositeColors(whiteScrim, color);
}
}
diff --git a/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java b/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java
index 00cc1a7e2c..66f9dbfcdc 100644
--- a/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java
+++ b/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java
@@ -19,6 +19,8 @@ package com.android.launcher3.graphics;
import static android.content.Intent.ACTION_SCREEN_OFF;
import static android.content.Intent.ACTION_USER_PRESENT;
+import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
+
import android.animation.ObjectAnimator;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -121,7 +123,6 @@ public class WorkspaceAndHotseatScrim implements
private Workspace mWorkspace;
- private final boolean mHasSysUiScrim;
private boolean mDrawTopScrim, mDrawBottomScrim;
private final RectF mFinalMaskRect = new RectF();
@@ -149,15 +150,9 @@ public class WorkspaceAndHotseatScrim implements
mMaskHeight = Utilities.pxFromDp(ALPHA_MASK_BITMAP_DP,
view.getResources().getDisplayMetrics());
-
- mHasSysUiScrim = !mWallpaperColorInfo.supportsDarkText();
- if (mHasSysUiScrim) {
- mTopScrim = Themes.getAttrDrawable(view.getContext(), R.attr.workspaceStatusBarScrim);
- mBottomMask = createDitheredAlphaMask();
- } else {
- mTopScrim = null;
- mBottomMask = null;
- }
+ mTopScrim = Themes.getAttrDrawable(view.getContext(), R.attr.workspaceStatusBarScrim);
+ mBottomMask = mTopScrim == null ? null : createDitheredAlphaMask();
+ mHideSysUiScrim = mTopScrim == null;
view.addOnAttachStateChangeListener(this);
onExtractedColorsChanged(mWallpaperColorInfo);
@@ -174,18 +169,18 @@ public class WorkspaceAndHotseatScrim implements
mWorkspace.computeScrollWithoutInvalidation();
CellLayout currCellLayout = mWorkspace.getCurrentDragOverlappingLayout();
canvas.save();
- if (currCellLayout != null && currCellLayout != mLauncher.getHotseat().getLayout()) {
+ if (currCellLayout != null && currCellLayout != mLauncher.getHotseat()) {
// Cut a hole in the darkening scrim on the page that should be highlighted, if any.
mLauncher.getDragLayer()
.getDescendantRectRelativeToSelf(currCellLayout, mHighlightRect);
canvas.clipRect(mHighlightRect, Region.Op.DIFFERENCE);
}
- canvas.drawColor(ColorUtils.setAlphaComponent(mFullScrimColor, mScrimAlpha));
+ canvas.drawColor(setColorAlphaBound(mFullScrimColor, mScrimAlpha));
canvas.restore();
}
- if (!mHideSysUiScrim && mHasSysUiScrim) {
+ if (!mHideSysUiScrim) {
if (mSysUiProgress <= 0) {
mAnimateScrimOnNextDraw = false;
return;
@@ -213,8 +208,9 @@ public class WorkspaceAndHotseatScrim implements
}
public void onInsetsChanged(Rect insets) {
- mDrawTopScrim = insets.top > 0;
- mDrawBottomScrim = !mLauncher.getDeviceProfile().isVerticalBarLayout();
+ mDrawTopScrim = mTopScrim != null && insets.top > 0;
+ mDrawBottomScrim = mBottomMask != null &&
+ !mLauncher.getDeviceProfile().isVerticalBarLayout();
}
private void setScrimProgress(float progress) {
@@ -230,7 +226,7 @@ public class WorkspaceAndHotseatScrim implements
mWallpaperColorInfo.addOnChangeListener(this);
onExtractedColorsChanged(mWallpaperColorInfo);
- if (mHasSysUiScrim) {
+ if (mTopScrim != null) {
IntentFilter filter = new IntentFilter(ACTION_SCREEN_OFF);
filter.addAction(ACTION_USER_PRESENT); // When the device wakes up + keyguard is gone
mRoot.getContext().registerReceiver(mReceiver, filter);
@@ -240,7 +236,7 @@ public class WorkspaceAndHotseatScrim implements
@Override
public void onViewDetachedFromWindow(View view) {
mWallpaperColorInfo.removeOnChangeListener(this);
- if (mHasSysUiScrim) {
+ if (mTopScrim != null) {
mRoot.getContext().unregisterReceiver(mReceiver);
}
}
@@ -259,14 +255,14 @@ public class WorkspaceAndHotseatScrim implements
}
public void setSize(int w, int h) {
- if (mHasSysUiScrim) {
+ if (mTopScrim != null) {
mTopScrim.setBounds(0, 0, w, h);
mFinalMaskRect.set(0, h - mMaskHeight, w, h);
}
}
public void hideSysUiScrim(boolean hideSysUiScrim) {
- mHideSysUiScrim = hideSysUiScrim;
+ mHideSysUiScrim = hideSysUiScrim || (mTopScrim == null);
if (!hideSysUiScrim) {
mAnimateScrimOnNextDraw = true;
}
@@ -281,18 +277,18 @@ public class WorkspaceAndHotseatScrim implements
}
private void reapplySysUiAlpha() {
- if (mHasSysUiScrim) {
- reapplySysUiAlphaNoInvalidate();
- if (!mHideSysUiScrim) {
- invalidate();
- }
+ reapplySysUiAlphaNoInvalidate();
+ if (!mHideSysUiScrim) {
+ invalidate();
}
}
private void reapplySysUiAlphaNoInvalidate() {
float factor = mSysUiProgress * mSysUiAnimMultiplier;
mBottomMaskPaint.setAlpha(Math.round(MAX_HOTSEAT_SCRIM_ALPHA * factor));
- mTopScrim.setAlpha(Math.round(255 * factor));
+ if (mTopScrim != null) {
+ mTopScrim.setAlpha(Math.round(255 * factor));
+ }
}
public void invalidate() {
@@ -309,7 +305,7 @@ public class WorkspaceAndHotseatScrim implements
LinearGradient lg = new LinearGradient(0, 0, 0, gradientHeight,
new int[]{
0x00FFFFFF,
- ColorUtils.setAlphaComponent(Color.WHITE, (int) (0xFF * 0.95)),
+ setColorAlphaBound(Color.WHITE, (int) (0xFF * 0.95)),
0xFFFFFFFF},
new float[]{0f, 0.8f, 1f},
Shader.TileMode.CLAMP);
diff --git a/src/com/android/launcher3/icons/BaseIconCache.java b/src/com/android/launcher3/icons/BaseIconCache.java
index 2afe7139fd..1f810b39f1 100644
--- a/src/com/android/launcher3/icons/BaseIconCache.java
+++ b/src/com/android/launcher3/icons/BaseIconCache.java
@@ -16,13 +16,13 @@
package com.android.launcher3.icons;
import static com.android.launcher3.icons.BitmapInfo.LOW_RES_ICON;
+import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
-import android.content.pm.LauncherActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -33,6 +33,7 @@ import android.database.sqlite.SQLiteException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
+import android.os.Build;
import android.os.Build.VERSION;
import android.os.Handler;
import android.os.Process;
@@ -41,15 +42,11 @@ import android.text.TextUtils;
import android.util.Log;
import com.android.launcher3.IconProvider;
-import com.android.launcher3.ItemInfoWithIcon;
import com.android.launcher3.LauncherFiles;
import com.android.launcher3.LauncherModel;
-import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.Utilities;
-import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.graphics.BitmapRenderer;
-import com.android.launcher3.model.PackageItemInfo;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.InstantAppResolver;
import com.android.launcher3.util.Preconditions;
@@ -60,7 +57,6 @@ import java.util.HashMap;
import java.util.HashSet;
import androidx.annotation.NonNull;
-import androidx.core.graphics.ColorUtils;
public class BaseIconCache {
@@ -80,12 +76,10 @@ public class BaseIconCache {
private final HashMap mDefaultIcons = new HashMap<>();
- final MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor();
final Context mContext;
final PackageManager mPackageManager;
final IconProvider mIconProvider;
final UserManagerCompat mUserManager;
- final LauncherAppsCompat mLauncherApps;
private final HashMap mCache =
new HashMap<>(INITIAL_ICON_CACHE_CAPACITY);
@@ -101,13 +95,12 @@ public class BaseIconCache {
mContext = context;
mPackageManager = context.getPackageManager();
mUserManager = UserManagerCompat.getInstance(mContext);
- mLauncherApps = LauncherAppsCompat.getInstance(mContext);
mInstantAppResolver = InstantAppResolver.newInstance(mContext);
mIconProvider = IconProvider.newInstance(context);
mWorkerHandler = new Handler(LauncherModel.getWorkerLooper());
- if (BitmapRenderer.USE_HARDWARE_BITMAP) {
+ if (BitmapRenderer.USE_HARDWARE_BITMAP && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mDecodeOptions = new BitmapFactory.Options();
mDecodeOptions.inPreferredConfig = Bitmap.Config.HARDWARE;
} else {
@@ -161,14 +154,6 @@ public class BaseIconCache {
return getFullResDefaultActivityIcon();
}
- public Drawable getFullResIcon(LauncherActivityInfo info) {
- return getFullResIcon(info, true);
- }
-
- public Drawable getFullResIcon(LauncherActivityInfo info, boolean flattenDrawable) {
- return mIconProvider.getIcon(info, mIconDpi, flattenDrawable);
- }
-
protected BitmapInfo makeDefaultIcon(UserHandle user) {
try (LauncherIcons li = LauncherIcons.obtain(mContext)) {
return li.createBadgedIconBitmap(
@@ -238,10 +223,10 @@ public class BaseIconCache {
}
if (entry == null) {
entry = new CacheEntry();
- cachingLogic.loadIcon(mContext, this, object, entry);
+ cachingLogic.loadIcon(mContext, object, entry);
}
- entry.title = cachingLogic.getLabel(object, mPackageManager);
- entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, user);
+ entry.title = cachingLogic.getLabel(object);
+ entry.contentDescription = mPackageManager.getUserBadgedLabel(entry.title, user);
mCache.put(key, entry);
ContentValues values = newContentValues(entry, entry.title.toString(),
@@ -262,22 +247,6 @@ public class BaseIconCache {
mIconDb.insertOrReplace(values);
}
- /**
- * Fill in {@param infoInOut} with the corresponding icon and label.
- */
- public synchronized void getTitleAndIconForApp(
- PackageItemInfo infoInOut, boolean useLowResIcon) {
- CacheEntry entry = getEntryForPackageLocked(
- infoInOut.packageName, infoInOut.user, useLowResIcon);
- applyCacheEntry(entry, infoInOut);
- }
-
- protected void applyCacheEntry(CacheEntry entry, ItemInfoWithIcon info) {
- info.title = Utilities.trim(entry.title);
- info.contentDescription = entry.contentDescription;
- info.applyFrom((entry.icon == null) ? getDefaultIcon(info.user) : entry);
- }
-
public synchronized BitmapInfo getDefaultIcon(UserHandle user) {
if (!mDefaultIcons.containsKey(user)) {
mDefaultIcons.put(user, makeDefaultIcon(user));
@@ -323,7 +292,7 @@ public class BaseIconCache {
providerFetchedOnce = true;
if (object != null) {
- cachingLogic.loadIcon(mContext, this, object, entry);
+ cachingLogic.loadIcon(mContext, object, entry);
} else {
if (usePackageIcon) {
CacheEntry packageEntry = getEntryForPackageLocked(
@@ -350,8 +319,8 @@ public class BaseIconCache {
providerFetchedOnce = true;
}
if (object != null) {
- entry.title = cachingLogic.getLabel(object, mPackageManager);
- entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, user);
+ entry.title = cachingLogic.getLabel(object);
+ entry.contentDescription = mPackageManager.getUserBadgedLabel(entry.title, user);
}
}
}
@@ -400,7 +369,7 @@ public class BaseIconCache {
* Gets an entry for the package, which can be used as a fallback entry for various components.
* This method is not thread safe, it must be called from a synchronized method.
*/
- private CacheEntry getEntryForPackageLocked(String packageName, UserHandle user,
+ protected CacheEntry getEntryForPackageLocked(String packageName, UserHandle user,
boolean useLowResIcon) {
Preconditions.assertWorkerThread();
ComponentKey cacheKey = getPackageKey(packageName, user);
@@ -430,7 +399,7 @@ public class BaseIconCache {
li.recycle();
entry.title = appInfo.loadLabel(mPackageManager);
- entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, user);
+ entry.contentDescription = mPackageManager.getUserBadgedLabel(entry.title, user);
entry.icon = useLowResIcon ? LOW_RES_ICON : iconInfo.icon;
entry.color = iconInfo.color;
@@ -466,13 +435,13 @@ public class BaseIconCache {
Long.toString(mUserManager.getSerialNumberForUser(cacheKey.user))});
if (c.moveToNext()) {
// Set the alpha to be 255, so that we never have a wrong color
- entry.color = ColorUtils.setAlphaComponent(c.getInt(0), 255);
+ entry.color = setColorAlphaBound(c.getInt(0), 255);
entry.title = c.getString(1);
if (entry.title == null) {
entry.title = "";
entry.contentDescription = "";
} else {
- entry.contentDescription = mUserManager.getBadgedLabelForUser(
+ entry.contentDescription = mPackageManager.getUserBadgedLabel(
entry.title, cacheKey.user);
}
diff --git a/src/com/android/launcher3/icons/CachingLogic.java b/src/com/android/launcher3/icons/CachingLogic.java
index 24186ef990..0a3da04d78 100644
--- a/src/com/android/launcher3/icons/CachingLogic.java
+++ b/src/com/android/launcher3/icons/CachingLogic.java
@@ -17,8 +17,6 @@ package com.android.launcher3.icons;
import android.content.ComponentName;
import android.content.Context;
-import android.content.pm.LauncherActivityInfo;
-import android.content.pm.PackageManager;
import android.os.UserHandle;
public interface CachingLogic {
@@ -27,61 +25,7 @@ public interface CachingLogic {
UserHandle getUser(T object);
- CharSequence getLabel(T object, PackageManager pm);
+ CharSequence getLabel(T object);
- void loadIcon(Context context, BaseIconCache cache, T object, BitmapInfo target);
-
- CachingLogic LAUNCHER_ACTIVITY_INFO =
- new CachingLogic() {
-
- @Override
- public ComponentName getComponent(LauncherActivityInfo object) {
- return object.getComponentName();
- }
-
- @Override
- public UserHandle getUser(LauncherActivityInfo object) {
- return object.getUser();
- }
-
- @Override
- public CharSequence getLabel(LauncherActivityInfo object, PackageManager pm) {
- return object.getLabel();
- }
-
- @Override
- public void loadIcon(Context context, BaseIconCache cache, LauncherActivityInfo object,
- BitmapInfo target) {
- LauncherIcons li = LauncherIcons.obtain(context);
- li.createBadgedIconBitmap(cache.getFullResIcon(object), object.getUser(),
- object.getApplicationInfo().targetSdkVersion).applyTo(target);
- li.recycle();
- }
- };
-
- CachingLogic COMPONENT_WITH_LABEL =
- new CachingLogic() {
-
- @Override
- public ComponentName getComponent(ComponentWithLabel object) {
- return object.getComponent();
- }
-
- @Override
- public UserHandle getUser(ComponentWithLabel object) {
- return object.getUser();
- }
-
- @Override
- public CharSequence getLabel(ComponentWithLabel object, PackageManager pm) {
- return object.getLabel(pm);
- }
-
- @Override
- public void loadIcon(Context context, BaseIconCache cache,
- ComponentWithLabel object, BitmapInfo target) {
- // Do not load icon.
- target.icon = BitmapInfo.LOW_RES_ICON;
- }
- };
+ void loadIcon(Context context, T object, BitmapInfo target);
}
diff --git a/src/com/android/launcher3/icons/ComponentWithLabel.java b/src/com/android/launcher3/icons/ComponentWithLabel.java
index 2badb4c373..7bb8832eed 100644
--- a/src/com/android/launcher3/icons/ComponentWithLabel.java
+++ b/src/com/android/launcher3/icons/ComponentWithLabel.java
@@ -16,6 +16,7 @@
package com.android.launcher3.icons;
import android.content.ComponentName;
+import android.content.Context;
import android.content.pm.PackageManager;
import android.os.UserHandle;
@@ -26,4 +27,36 @@ public interface ComponentWithLabel {
UserHandle getUser();
CharSequence getLabel(PackageManager pm);
+
+
+ class ComponentCachingLogic implements CachingLogic {
+
+ private final PackageManager mPackageManager;
+
+ public ComponentCachingLogic(Context context) {
+ mPackageManager = context.getPackageManager();
+ }
+
+ @Override
+ public ComponentName getComponent(ComponentWithLabel object) {
+ return object.getComponent();
+ }
+
+ @Override
+ public UserHandle getUser(ComponentWithLabel object) {
+ return object.getUser();
+ }
+
+ @Override
+ public CharSequence getLabel(ComponentWithLabel object) {
+ return object.getLabel(mPackageManager);
+ }
+
+ @Override
+ public void loadIcon(Context context,
+ ComponentWithLabel object, BitmapInfo target) {
+ // Do not load icon.
+ target.icon = BitmapInfo.LOW_RES_ICON;
+ }
+ }
}
diff --git a/src/com/android/launcher3/icons/IconCache.java b/src/com/android/launcher3/icons/IconCache.java
index 6e2ca28ec6..e10ff5b1b8 100644
--- a/src/com/android/launcher3/icons/IconCache.java
+++ b/src/com/android/launcher3/icons/IconCache.java
@@ -16,15 +16,13 @@
package com.android.launcher3.icons;
-import static com.android.launcher3.icons.CachingLogic.COMPONENT_WITH_LABEL;
-import static com.android.launcher3.icons.CachingLogic.LAUNCHER_ACTIVITY_INFO;
-
import android.content.Context;
import android.content.Intent;
import android.content.pm.LauncherActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Process;
import android.os.UserHandle;
@@ -34,8 +32,11 @@ import com.android.launcher3.AppInfo;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.ItemInfoWithIcon;
import com.android.launcher3.LauncherModel;
+import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.ShortcutInfo;
import com.android.launcher3.Utilities;
+import com.android.launcher3.compat.LauncherAppsCompat;
+import com.android.launcher3.icons.ComponentWithLabel.ComponentCachingLogic;
import com.android.launcher3.model.PackageItemInfo;
import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.Provider;
@@ -49,10 +50,21 @@ public class IconCache extends BaseIconCache {
private static final String TAG = "Launcher.IconCache";
+ private final MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor();
+
+ private final CachingLogic mComponentWithLabelCachingLogic;
+ private final CachingLogic mLauncherActivityInfoCachingLogic;
+
+ private final LauncherAppsCompat mLauncherApps;
+
private int mPendingIconRequestCount = 0;
public IconCache(Context context, InvariantDeviceProfile inv) {
super(context, inv.fillResIconDpi, inv.iconBitmapSize);
+ mComponentWithLabelCachingLogic = new ComponentCachingLogic(context);
+ mLauncherActivityInfoCachingLogic = new LauncherActivtiyCachingLogic(this);
+ mLauncherApps = LauncherAppsCompat.getInstance(mContext);
+
}
/**
@@ -65,7 +77,7 @@ public class IconCache extends BaseIconCache {
PackageManager.GET_UNINSTALLED_PACKAGES);
long userSerial = mUserManager.getSerialNumberForUser(user);
for (LauncherActivityInfo app : mLauncherApps.getActivityList(packageName, user)) {
- addIconToDBAndMemCache(app, LAUNCHER_ACTIVITY_INFO, info, userSerial,
+ addIconToDBAndMemCache(app, mLauncherActivityInfoCachingLogic, info, userSerial,
false /*replace existing*/);
}
} catch (NameNotFoundException e) {
@@ -115,7 +127,7 @@ public class IconCache extends BaseIconCache {
*/
public synchronized void updateTitleAndIcon(AppInfo application) {
CacheEntry entry = cacheLocked(application.componentName,
- application.user, Provider.of(null), LAUNCHER_ACTIVITY_INFO,
+ application.user, Provider.of(null), mLauncherActivityInfoCachingLogic,
false, application.usingLowResIcon());
if (entry.icon != null && !isDefaultIcon(entry.icon, application.user)) {
applyCacheEntry(entry, application);
@@ -151,8 +163,8 @@ public class IconCache extends BaseIconCache {
public synchronized String getTitleNoCache(ComponentWithLabel info) {
CacheEntry entry = cacheLocked(info.getComponent(), info.getUser(), Provider.of(info),
- COMPONENT_WITH_LABEL, false /* usePackageIcon */, true /* useLowResIcon */,
- false /* addToMemCache */);
+ mComponentWithLabelCachingLogic, false /* usePackageIcon */,
+ true /* useLowResIcon */, false /* addToMemCache */);
return Utilities.trim(entry.title);
}
@@ -164,11 +176,35 @@ public class IconCache extends BaseIconCache {
@NonNull Provider activityInfoProvider,
boolean usePkgIcon, boolean useLowResIcon) {
CacheEntry entry = cacheLocked(infoInOut.getTargetComponent(), infoInOut.user,
- activityInfoProvider,
- LAUNCHER_ACTIVITY_INFO, usePkgIcon, useLowResIcon);
+ activityInfoProvider, mLauncherActivityInfoCachingLogic, usePkgIcon, useLowResIcon);
applyCacheEntry(entry, infoInOut);
}
+
+ /**
+ * Fill in {@param infoInOut} with the corresponding icon and label.
+ */
+ public synchronized void getTitleAndIconForApp(
+ PackageItemInfo infoInOut, boolean useLowResIcon) {
+ CacheEntry entry = getEntryForPackageLocked(
+ infoInOut.packageName, infoInOut.user, useLowResIcon);
+ applyCacheEntry(entry, infoInOut);
+ }
+
+ protected void applyCacheEntry(CacheEntry entry, ItemInfoWithIcon info) {
+ info.title = Utilities.trim(entry.title);
+ info.contentDescription = entry.contentDescription;
+ info.applyFrom((entry.icon == null) ? getDefaultIcon(info.user) : entry);
+ }
+
+ public Drawable getFullResIcon(LauncherActivityInfo info) {
+ return getFullResIcon(info, true);
+ }
+
+ public Drawable getFullResIcon(LauncherActivityInfo info, boolean flattenDrawable) {
+ return mIconProvider.getIcon(info, mIconDpi, flattenDrawable);
+ }
+
public static abstract class IconLoadRequest extends HandlerRunnable {
IconLoadRequest(Handler handler, Runnable endRunnable) {
super(handler, endRunnable);
diff --git a/src/com/android/launcher3/icons/LauncherActivtiyCachingLogic.java b/src/com/android/launcher3/icons/LauncherActivtiyCachingLogic.java
new file mode 100644
index 0000000000..8c85b1c799
--- /dev/null
+++ b/src/com/android/launcher3/icons/LauncherActivtiyCachingLogic.java
@@ -0,0 +1,54 @@
+/*
+ * 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.icons;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.LauncherActivityInfo;
+import android.os.UserHandle;
+
+public class LauncherActivtiyCachingLogic implements CachingLogic {
+
+ private final IconCache mCache;
+
+ public LauncherActivtiyCachingLogic(IconCache cache) {
+ mCache = cache;
+ }
+
+ @Override
+ public ComponentName getComponent(LauncherActivityInfo object) {
+ return object.getComponentName();
+ }
+
+ @Override
+ public UserHandle getUser(LauncherActivityInfo object) {
+ return object.getUser();
+ }
+
+ @Override
+ public CharSequence getLabel(LauncherActivityInfo object) {
+ return object.getLabel();
+ }
+
+ @Override
+ public void loadIcon(Context context, LauncherActivityInfo object,
+ BitmapInfo target) {
+ LauncherIcons li = LauncherIcons.obtain(context);
+ li.createBadgedIconBitmap(mCache.getFullResIcon(object),
+ object.getUser(), object.getApplicationInfo().targetSdkVersion).applyTo(target);
+ li.recycle();
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/launcher3/logging/LoggerUtils.java b/src/com/android/launcher3/logging/LoggerUtils.java
index 1c4327c499..4ef86265f5 100644
--- a/src/com/android/launcher3/logging/LoggerUtils.java
+++ b/src/com/android/launcher3/logging/LoggerUtils.java
@@ -40,6 +40,7 @@ import java.lang.reflect.Modifier;
/**
* Helper methods for logging.
*/
+@Deprecated
public class LoggerUtils {
private static final ArrayMap> sNameCache = new ArrayMap<>();
private static final String UNKNOWN = "UNKNOWN";
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
new file mode 100644
index 0000000000..d332dc5ce3
--- /dev/null
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -0,0 +1,46 @@
+/*
+ * 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.logging;
+
+import android.content.Context;
+import android.content.Intent;
+import android.view.View;
+
+import com.android.launcher3.R;
+import com.android.launcher3.util.ComponentKey;
+import com.android.launcher3.util.ResourceBasedOverride;
+import com.android.launcher3.logging.StatsLogUtils.LogStateProvider;
+
+/**
+ * Handles the user event logging in Q.
+ * Since the AOSP Launcher3 doesn't take part in the StatsLog logging, the class
+ * itself is abstract.
+ */
+public abstract class StatsLogManager implements ResourceBasedOverride {
+
+ protected LogStateProvider mStateProvider;
+ public static StatsLogManager newInstance(Context context, LogStateProvider stateProvider) {
+ StatsLogManager mgr = Overrides.getObject(StatsLogManager.class,
+ context.getApplicationContext(), R.string.stats_log_manager_class);
+ mgr.mStateProvider = stateProvider;
+ mgr.verify();
+ return mgr;
+ }
+
+ public void logAppLaunch(View v, Intent intent) { }
+ public void logTaskLaunch(View v, ComponentKey key) { }
+ public void verify() {} // TODO: should move into robo tests
+}
diff --git a/src/com/android/launcher3/logging/StatsLogUtils.java b/src/com/android/launcher3/logging/StatsLogUtils.java
new file mode 100644
index 0000000000..647f255af3
--- /dev/null
+++ b/src/com/android/launcher3/logging/StatsLogUtils.java
@@ -0,0 +1,67 @@
+package com.android.launcher3.logging;
+
+import android.view.View;
+import android.view.ViewParent;
+
+import com.android.launcher3.ItemInfo;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
+
+import androidx.annotation.Nullable;
+
+
+public class StatsLogUtils {
+
+ // Defined in android.stats.launcher.nano
+ // As they cannot be linked in this file, defining again.
+ public final static int LAUNCHER_STATE_BACKGROUND = 0;
+ public final static int LAUNCHER_STATE_HOME = 1;
+ public final static int LAUNCHER_STATE_OVERVIEW = 2;
+ public final static int LAUNCHER_STATE_ALLAPPS = 3;
+
+ private final static int MAXIMUM_VIEW_HIERARCHY_LEVEL = 5;
+
+ public interface LogStateProvider {
+ int getCurrentState();
+ }
+
+ /**
+ * Implemented by containers to provide a container source for a given child.
+ *
+ * Currently,
+ */
+ public interface LogContainerProvider {
+
+ /**
+ * Copies data from the source to the destination proto.
+ *
+ * @param v source of the data
+ * @param info source of the data
+ * @param target dest of the data
+ * @param targetParent dest of the data
+ */
+ void fillInLogContainerData(View v, ItemInfo info, Target target, Target targetParent);
+ }
+
+ /**
+ * Recursively finds the parent of the given child which implements IconLogInfoProvider
+ */
+ public static LogContainerProvider getLaunchProviderRecursive(@Nullable View v) {
+ ViewParent parent;
+ if (v != null) {
+ parent = v.getParent();
+ } else {
+ return null;
+ }
+
+ // Optimization to only check up to 5 parents.
+ int count = MAXIMUM_VIEW_HIERARCHY_LEVEL;
+ while (parent != null && count-- > 0) {
+ if (parent instanceof LogContainerProvider) {
+ return (LogContainerProvider) parent;
+ } else {
+ parent = parent.getParent();
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/com/android/launcher3/logging/UserEventDispatcher.java b/src/com/android/launcher3/logging/UserEventDispatcher.java
index a318dc0eb6..e11516890c 100644
--- a/src/com/android/launcher3/logging/UserEventDispatcher.java
+++ b/src/com/android/launcher3/logging/UserEventDispatcher.java
@@ -41,9 +41,9 @@ import com.android.launcher3.ItemInfo;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.logging.StatsLogUtils.LogContainerProvider;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.launcher3.userevent.nano.LauncherLogProto.LauncherEvent;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
import com.android.launcher3.util.ComponentKey;
@@ -62,10 +62,9 @@ import androidx.annotation.Nullable;
*
* $ adb shell setprop log.tag.UserEvent VERBOSE
*/
+@Deprecated
public class UserEventDispatcher implements ResourceBasedOverride {
- private final static int MAXIMUM_VIEW_HIERARCHY_LEVEL = 5;
-
private static final String TAG = "UserEvent";
private static final boolean IS_VERBOSE =
FeatureFlags.IS_DOGFOOD_BUILD && Utilities.isPropertyEnabled(LogConfig.USEREVENT);
@@ -96,42 +95,19 @@ public class UserEventDispatcher implements ResourceBasedOverride {
}
/**
- * Implemented by containers to provide a container source for a given child.
+ * Fills in the container data on the given event if the given view is not null.
+ * @return whether container data was added.
*/
- public interface LogContainerProvider {
-
- /**
- * Copies data from the source to the destination proto.
- *
- * @param v source of the data
- * @param info source of the data
- * @param target dest of the data
- * @param targetParent dest of the data
- */
- void fillInLogContainerData(View v, ItemInfo info, Target target, Target targetParent);
- }
-
- /**
- * Recursively finds the parent of the given child which implements IconLogInfoProvider
- */
- public static LogContainerProvider getLaunchProviderRecursive(@Nullable View v) {
- ViewParent parent;
- if (v != null) {
- parent = v.getParent();
- } else {
- return null;
+ @Deprecated
+ public static boolean fillInLogContainerData(LauncherLogProto.LauncherEvent event, @Nullable View v) {
+ // Fill in grid(x,y), pageIndex of the child and container type of the parent
+ LogContainerProvider provider = StatsLogUtils.getLaunchProviderRecursive(v);
+ if (v == null || !(v.getTag() instanceof ItemInfo) || provider == null) {
+ return false;
}
-
- // Optimization to only check up to 5 parents.
- int count = MAXIMUM_VIEW_HIERARCHY_LEVEL;
- while (parent != null && count-- > 0) {
- if (parent instanceof LogContainerProvider) {
- return (LogContainerProvider) parent;
- } else {
- parent = parent.getParent();
- }
- }
- return null;
+ ItemInfo itemInfo = (ItemInfo) v.getTag();
+ provider.fillInLogContainerData(v, itemInfo, event.srcTarget[0], event.srcTarget[1]);
+ return true;
}
private boolean mSessionStarted;
@@ -150,21 +126,7 @@ public class UserEventDispatcher implements ResourceBasedOverride {
// intentHash required
// --------------------------------------------------------------
- /**
- * Fills in the container data on the given event if the given view is not null.
- * @return whether container data was added.
- */
- protected boolean fillInLogContainerData(LauncherEvent event, @Nullable View v) {
- // Fill in grid(x,y), pageIndex of the child and container type of the parent
- LogContainerProvider provider = getLaunchProviderRecursive(v);
- if (v == null || !(v.getTag() instanceof ItemInfo) || provider == null) {
- return false;
- }
- ItemInfo itemInfo = (ItemInfo) v.getTag();
- provider.fillInLogContainerData(v, itemInfo, event.srcTarget[0], event.srcTarget[1]);
- return true;
- }
-
+ @Deprecated
public void logAppLaunch(View v, Intent intent) {
LauncherEvent event = newLauncherEvent(newTouchAction(Action.Touch.TAP),
newItemTarget(v, mInstantAppResolver), newTarget(Target.Type.CONTAINER));
@@ -181,6 +143,7 @@ public class UserEventDispatcher implements ResourceBasedOverride {
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
@@ -363,7 +326,7 @@ public class UserEventDispatcher implements ResourceBasedOverride {
}
public void logDeepShortcutsOpen(View icon) {
- LogContainerProvider provider = getLaunchProviderRecursive(icon);
+ LogContainerProvider provider = StatsLogUtils.getLaunchProviderRecursive(icon);
if (icon == null || !(icon.getTag() instanceof ItemInfo)) {
return;
}
@@ -376,15 +339,6 @@ public class UserEventDispatcher implements ResourceBasedOverride {
resetElapsedContainerMillis("deep shortcut open");
}
- /* Currently we are only interested in whether this event happens or not and don't
- * care about which screen moves to where. */
- public void logOverviewReorder() {
- LauncherEvent event = newLauncherEvent(newTouchAction(Action.Touch.DRAGDROP),
- newContainerTarget(ContainerType.WORKSPACE),
- newContainerTarget(ContainerType.OVERVIEW));
- dispatchUserEvent(event, null);
- }
-
public void logDragNDrop(DropTarget.DragObject dragObj, View dropTargetAsView) {
LauncherEvent event = newLauncherEvent(newTouchAction(Action.Touch.DRAGDROP),
newItemTarget(dragObj.originalDragInfo, mInstantAppResolver),
diff --git a/src/com/android/launcher3/model/LoaderResults.java b/src/com/android/launcher3/model/BaseLoaderResults.java
similarity index 85%
rename from src/com/android/launcher3/model/LoaderResults.java
rename to src/com/android/launcher3/model/BaseLoaderResults.java
index 1d18e7667b..d3dc91f3be 100644
--- a/src/com/android/launcher3/model/LoaderResults.java
+++ b/src/com/android/launcher3/model/BaseLoaderResults.java
@@ -30,47 +30,44 @@ import com.android.launcher3.LauncherSettings;
import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.PagedView;
import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.LooperIdleLock;
import com.android.launcher3.util.ViewOnDrawExecutor;
-import com.android.launcher3.widget.WidgetListRowEntry;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
-import java.util.HashMap;
import java.util.Iterator;
import java.util.concurrent.Executor;
/**
- * Helper class to handle results of {@link com.android.launcher3.model.LoaderTask}.
+ * Base Helper class to handle results of {@link com.android.launcher3.model.LoaderTask}.
*/
-public class LoaderResults {
+public abstract class BaseLoaderResults {
- private static final String TAG = "LoaderResults";
- private static final int INVALID_SCREEN_ID = -1;
+ protected static final String TAG = "LoaderResults";
+ protected static final int INVALID_SCREEN_ID = -1;
private static final int ITEMS_CHUNK = 6; // batch size for the workspace icons
- private final Executor mUiExecutor;
+ protected final Executor mUiExecutor;
- private final LauncherAppState mApp;
- private final BgDataModel mBgDataModel;
+ protected final LauncherAppState mApp;
+ protected final BgDataModel mBgDataModel;
private final AllAppsList mBgAllAppsList;
- private final int mPageToBindFirst;
+ protected final int mPageToBindFirst;
- private final WeakReference mCallbacks;
+ protected final WeakReference mCallbacks;
- public LoaderResults(LauncherAppState app, BgDataModel dataModel,
+ public BaseLoaderResults(LauncherAppState app, BgDataModel dataModel,
AllAppsList allAppsList, int pageToBindFirst, WeakReference callbacks) {
mUiExecutor = new MainThreadExecutor();
mApp = app;
mBgDataModel = dataModel;
mBgAllAppsList = allAppsList;
mPageToBindFirst = pageToBindFirst;
- mCallbacks = callbacks == null ? new WeakReference(null) : callbacks;
+ mCallbacks = callbacks == null ? new WeakReference<>(null) : callbacks;
}
/**
@@ -152,8 +149,8 @@ public class LoaderResults {
Executor mainExecutor = mUiExecutor;
// Load items on the current page.
- bindWorkspaceItems(currentWorkspaceItems, currentAppWidgets, mainExecutor);
-
+ bindWorkspaceItems(currentWorkspaceItems, mainExecutor);
+ bindAppWidgets(currentAppWidgets, 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).
@@ -173,8 +170,8 @@ public class LoaderResults {
}
});
- bindWorkspaceItems(otherWorkspaceItems, otherAppWidgets, deferredExecutor);
-
+ bindWorkspaceItems(otherWorkspaceItems, deferredExecutor);
+ bindAppWidgets(otherAppWidgets, deferredExecutor);
// Tell the workspace that we're done binding items
r = new Runnable() {
public void run() {
@@ -252,7 +249,7 @@ public class LoaderResults {
/** Sorts the set of items by hotseat, workspace (spatially from top to bottom, left to
* right) */
- private void sortWorkspaceItemsSpatially(ArrayList workspaceItems) {
+ protected void sortWorkspaceItemsSpatially(ArrayList workspaceItems) {
final InvariantDeviceProfile profile = mApp.getInvariantDeviceProfile();
final int screenCols = profile.numColumns;
final int screenCellCount = profile.numColumns * profile.numRows;
@@ -288,14 +285,12 @@ public class LoaderResults {
});
}
- private void bindWorkspaceItems(final ArrayList workspaceItems,
- final ArrayList appWidgets,
+ protected void bindWorkspaceItems(final ArrayList workspaceItems,
final Executor executor) {
if (com.android.launcher3.Utilities.IS_RUNNING_IN_TEST_HARNESS
&& com.android.launcher3.Utilities.IS_DEBUG_DEVICE) {
- android.util.Log.d("b/117332845",
- android.util.Log.getStackTraceString(new Throwable()));
+ Log.d("b/117332845", Log.getStackTraceString(new Throwable()));
}
// Bind the workspace items
int N = workspaceItems.size();
@@ -307,22 +302,25 @@ public class LoaderResults {
public void run() {
Callbacks callbacks = mCallbacks.get();
if (callbacks != null) {
- callbacks.bindItems(workspaceItems.subList(start, start+chunkSize), false);
+ callbacks.bindItems(workspaceItems.subList(start, start + chunkSize),
+ false);
}
}
};
executor.execute(r);
}
+ }
- // Bind the widgets, one at a time
+ private void bindAppWidgets(ArrayList appWidgets, Executor executor) {
+ int N;// Bind the widgets, one at a time
N = appWidgets.size();
for (int i = 0; i < N; i++) {
final ItemInfo widget = appWidgets.get(i);
final Runnable r = new Runnable() {
public void run() {
- Callbacks callbacks = mCallbacks.get();
- if (callbacks != null) {
- callbacks.bindItems(Collections.singletonList(widget), false);
+ Callbacks callbacks = mCallbacks.get();
+ if (callbacks != null) {
+ callbacks.bindItems(Collections.singletonList(widget), false);
}
}
};
@@ -330,18 +328,7 @@ public class LoaderResults {
}
}
- public void bindDeepShortcuts() {
- final HashMap shortcutMapCopy;
- synchronized (mBgDataModel) {
- shortcutMapCopy = new HashMap<>(mBgDataModel.deepShortcutMap);
- }
- mUiExecutor.execute(() -> {
- Callbacks callbacks = mCallbacks.get();
- if (callbacks != null) {
- callbacks.bindDeepShortcutMap(shortcutMapCopy);
- }
- });
- }
+ public abstract void bindDeepShortcuts();
public void bindAllApps() {
// shallow copy
@@ -359,19 +346,7 @@ public class LoaderResults {
mUiExecutor.execute(r);
}
- public void bindWidgets() {
- final ArrayList widgets =
- mBgDataModel.widgetsModel.getWidgetsList(mApp.getContext());
- Runnable r = new Runnable() {
- public void run() {
- Callbacks callbacks = mCallbacks.get();
- if (callbacks != null) {
- callbacks.bindAllWidgets(widgets);
- }
- }
- };
- mUiExecutor.execute(r);
- }
+ public abstract void bindWidgets();
public LooperIdleLock newIdleLock(Object lock) {
LooperIdleLock idleLock = new LooperIdleLock(lock, Looper.getMainLooper());
diff --git a/src/com/android/launcher3/model/LoaderCursor.java b/src/com/android/launcher3/model/LoaderCursor.java
index ea4d32b282..3aeb1c078c 100644
--- a/src/com/android/launcher3/model/LoaderCursor.java
+++ b/src/com/android/launcher3/model/LoaderCursor.java
@@ -22,6 +22,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.Intent.ShortcutIconResource;
import android.content.pm.LauncherActivityInfo;
+import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.CursorWrapper;
import android.graphics.BitmapFactory;
@@ -41,7 +42,6 @@ import com.android.launcher3.ShortcutInfo;
import com.android.launcher3.Utilities;
import com.android.launcher3.Workspace;
import com.android.launcher3.compat.LauncherAppsCompat;
-import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.icons.LauncherIcons;
@@ -64,7 +64,7 @@ public class LoaderCursor extends CursorWrapper {
public final LongSparseArray allUsers = new LongSparseArray<>();
private final Context mContext;
- private final UserManagerCompat mUserManager;
+ private final PackageManager mPM;
private final IconCache mIconCache;
private final InvariantDeviceProfile mIDP;
@@ -100,7 +100,7 @@ public class LoaderCursor extends CursorWrapper {
mContext = app.getContext();
mIconCache = app.getIconCache();
mIDP = app.getInvariantDeviceProfile();
- mUserManager = UserManagerCompat.getInstance(mContext);
+ mPM = mContext.getPackageManager();
// Init column indices
iconIndex = getColumnIndexOrThrow(LauncherSettings.Favorites.ICON);
@@ -228,7 +228,7 @@ public class LoaderCursor extends CursorWrapper {
throw new InvalidParameterException("Invalid restoreType " + restoreFlag);
}
- info.contentDescription = mUserManager.getBadgedLabelForUser(info.title, info.user);
+ info.contentDescription = mPM.getUserBadgedLabel(info.title, info.user);
info.itemType = itemType;
info.status = restoreFlag;
return info;
@@ -284,7 +284,7 @@ public class LoaderCursor extends CursorWrapper {
info.title = componentName.getClassName();
}
- info.contentDescription = mUserManager.getBadgedLabelForUser(info.title, info.user);
+ info.contentDescription = mPM.getUserBadgedLabel(info.title, info.user);
return info;
}
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index 8b3e2c9a86..8551e6fbc0 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -20,8 +20,6 @@ import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_LOCKED_USER;
import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_SAFEMODE;
import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_SUSPENDED;
import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.MAX_NUM_ITEMS_IN_PREVIEW;
-import static com.android.launcher3.icons.CachingLogic.COMPONENT_WITH_LABEL;
-import static com.android.launcher3.icons.CachingLogic.LAUNCHER_ACTIVITY_INFO;
import static com.android.launcher3.model.LoaderResults.filterCurrentWorkspaceItems;
import android.appwidget.AppWidgetProviderInfo;
@@ -46,6 +44,7 @@ import com.android.launcher3.AllAppsList;
import com.android.launcher3.AppInfo;
import com.android.launcher3.FolderInfo;
import com.android.launcher3.icons.ComponentWithLabel;
+import com.android.launcher3.icons.ComponentWithLabel.ComponentCachingLogic;
import com.android.launcher3.icons.IconCacheUpdateHandler;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.InstallShortcutReceiver;
@@ -63,6 +62,7 @@ import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderIconPreviewVerifier;
+import com.android.launcher3.icons.LauncherActivtiyCachingLogic;
import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.logging.FileLog;
import com.android.launcher3.provider.ImportDataTask;
@@ -202,7 +202,8 @@ public class LoaderTask implements Runnable {
TraceHelper.partitionSection(TAG, "step 2.3: Update icon cache");
IconCacheUpdateHandler updateHandler = mIconCache.getUpdateHandler();
setIgnorePackages(updateHandler);
- updateHandler.updateIcons(allActivityList, LAUNCHER_ACTIVITY_INFO,
+ updateHandler.updateIcons(allActivityList,
+ new LauncherActivtiyCachingLogic(mApp.getIconCache()),
mApp.getModel()::onPackageIconsUpdated);
// Take a break
@@ -233,7 +234,7 @@ public class LoaderTask implements Runnable {
verifyNotStopped();
TraceHelper.partitionSection(TAG, "step 4.3: Update icon cache");
- updateHandler.updateIcons(allWidgetsList, COMPONENT_WITH_LABEL,
+ updateHandler.updateIcons(allWidgetsList, new ComponentCachingLogic(mApp.getContext()),
mApp.getModel()::onWidgetLabelsUpdated);
verifyNotStopped();
diff --git a/src/com/android/launcher3/settings/PreferenceHighlighter.java b/src/com/android/launcher3/settings/PreferenceHighlighter.java
index 4ed4cf1133..8ba814686f 100644
--- a/src/com/android/launcher3/settings/PreferenceHighlighter.java
+++ b/src/com/android/launcher3/settings/PreferenceHighlighter.java
@@ -15,7 +15,7 @@
*/
package com.android.launcher3.settings;
-import static androidx.core.graphics.ColorUtils.setAlphaComponent;
+import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -57,7 +57,7 @@ public class PreferenceHighlighter extends ItemDecoration implements Runnable {
private static final long HIGHLIGHT_DURATION = 15000L;
private static final long HIGHLIGHT_FADE_OUT_DURATION = 500L;
private static final long HIGHLIGHT_FADE_IN_DURATION = 200L;
- private static final int END_COLOR = setAlphaComponent(Color.WHITE, 0);
+ private static final int END_COLOR = setColorAlphaBound(Color.WHITE, 0);
private final Paint mPaint = new Paint();
private final RecyclerView mRv;
@@ -91,7 +91,7 @@ public class PreferenceHighlighter extends ItemDecoration implements Runnable {
if (!mHighLightStarted) {
// Start highlight
- int colorTo = setAlphaComponent(Themes.getColorAccent(mRv.getContext()), 66);
+ int colorTo = setColorAlphaBound(Themes.getColorAccent(mRv.getContext()), 66);
ObjectAnimator anim = ObjectAnimator.ofArgb(this, HIGHLIGHT_COLOR, END_COLOR, colorTo);
anim.setDuration(HIGHLIGHT_FADE_IN_DURATION);
anim.setRepeatMode(ValueAnimator.REVERSE);
diff --git a/src/com/android/launcher3/views/DoubleShadowBubbleTextView.java b/src/com/android/launcher3/views/DoubleShadowBubbleTextView.java
index 64e166eeb8..323eecb91b 100644
--- a/src/com/android/launcher3/views/DoubleShadowBubbleTextView.java
+++ b/src/com/android/launcher3/views/DoubleShadowBubbleTextView.java
@@ -16,6 +16,8 @@
package com.android.launcher3.views;
+import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
+
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
@@ -26,8 +28,6 @@ import android.widget.TextView;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.R;
-import androidx.core.graphics.ColorUtils;
-
/**
* Extension of {@link BubbleTextView} which draws two shadows on the text (ambient and key shadows}
*/
@@ -60,7 +60,7 @@ public class DoubleShadowBubbleTextView extends BubbleTextView {
// We enhance the shadow by drawing the shadow twice
getPaint().setShadowLayer(mShadowInfo.ambientShadowBlur, 0, 0,
- ColorUtils.setAlphaComponent(mShadowInfo.ambientShadowColor, alpha));
+ setColorAlphaBound(mShadowInfo.ambientShadowColor, alpha));
drawWithoutBadge(canvas);
canvas.save();
@@ -69,7 +69,7 @@ public class DoubleShadowBubbleTextView extends BubbleTextView {
getScrollY() + getHeight());
getPaint().setShadowLayer(mShadowInfo.keyShadowBlur, 0.0f, mShadowInfo.keyShadowOffset,
- ColorUtils.setAlphaComponent(mShadowInfo.keyShadowColor, alpha));
+ setColorAlphaBound(mShadowInfo.keyShadowColor, alpha));
drawWithoutBadge(canvas);
canvas.restore();
@@ -107,11 +107,11 @@ public class DoubleShadowBubbleTextView extends BubbleTextView {
return true;
} else if (ambientShadowAlpha > 0) {
textView.getPaint().setShadowLayer(ambientShadowBlur, 0, 0,
- ColorUtils.setAlphaComponent(ambientShadowColor, textAlpha));
+ setColorAlphaBound(ambientShadowColor, textAlpha));
return true;
} else if (keyShadowAlpha > 0) {
textView.getPaint().setShadowLayer(keyShadowBlur, 0.0f, keyShadowOffset,
- ColorUtils.setAlphaComponent(keyShadowColor, textAlpha));
+ setColorAlphaBound(keyShadowColor, textAlpha));
return true;
} else {
return false;
diff --git a/src/com/android/launcher3/views/OptionsPopupView.java b/src/com/android/launcher3/views/OptionsPopupView.java
index c540b59c1c..6ba2f4069c 100644
--- a/src/com/android/launcher3/views/OptionsPopupView.java
+++ b/src/com/android/launcher3/views/OptionsPopupView.java
@@ -34,6 +34,7 @@ import android.widget.Toast;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.popup.ArrowPopup;
import com.android.launcher3.shortcuts.DeepShortcutView;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
@@ -151,8 +152,10 @@ public class OptionsPopupView extends ArrowPopup
ArrayList options = new ArrayList<>();
options.add(new OptionItem(R.string.wallpaper_button_text, R.drawable.ic_wallpaper,
ControlType.WALLPAPER_BUTTON, OptionsPopupView::startWallpaperPicker));
- options.add(new OptionItem(R.string.widget_button_text, R.drawable.ic_widget,
- ControlType.WIDGETS_BUTTON, OptionsPopupView::onWidgetsClicked));
+ if (!FeatureFlags.GO_DISABLE_WIDGETS) {
+ options.add(new OptionItem(R.string.widget_button_text, R.drawable.ic_widget,
+ ControlType.WIDGETS_BUTTON, OptionsPopupView::onWidgetsClicked));
+ }
options.add(new OptionItem(R.string.settings_button_text, R.drawable.ic_setting,
ControlType.SETTINGS_BUTTON, OptionsPopupView::startSettings));
diff --git a/src/com/android/launcher3/views/ScrimView.java b/src/com/android/launcher3/views/ScrimView.java
index 6fd84db26a..deb09654cf 100644
--- a/src/com/android/launcher3/views/ScrimView.java
+++ b/src/com/android/launcher3/views/ScrimView.java
@@ -22,9 +22,9 @@ import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.anim.Interpolators.ACCEL;
import static com.android.launcher3.anim.Interpolators.DEACCEL;
+import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
import static androidx.core.graphics.ColorUtils.compositeColors;
-import static androidx.core.graphics.ColorUtils.setAlphaComponent;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -182,7 +182,7 @@ public class ScrimView extends View implements Insettable, OnChangeListener,
@Override
public void onExtractedColorsChanged(WallpaperColorInfo wallpaperColorInfo) {
mScrimColor = wallpaperColorInfo.getMainColor();
- mEndFlatColor = compositeColors(mEndScrim, setAlphaComponent(
+ mEndFlatColor = compositeColors(mEndScrim, setColorAlphaBound(
mScrimColor, Math.round(mMaxScrimAlpha * 255)));
mEndFlatColorAlpha = Color.alpha(mEndFlatColor);
updateColors();
@@ -201,7 +201,7 @@ public class ScrimView extends View implements Insettable, OnChangeListener,
public void reInitUi() { }
protected void updateColors() {
- mCurrentFlatColor = mProgress >= 1 ? 0 : setAlphaComponent(
+ mCurrentFlatColor = mProgress >= 1 ? 0 : setColorAlphaBound(
mEndFlatColor, Math.round((1 - mProgress) * mEndFlatColorAlpha));
}
diff --git a/src/com/android/launcher3/widget/BaseWidgetSheet.java b/src/com/android/launcher3/widget/BaseWidgetSheet.java
index 48c18f8538..673b3cc14f 100644
--- a/src/com/android/launcher3/widget/BaseWidgetSheet.java
+++ b/src/com/android/launcher3/widget/BaseWidgetSheet.java
@@ -17,6 +17,7 @@ package com.android.launcher3.widget;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
import android.content.Context;
@@ -42,8 +43,6 @@ import com.android.launcher3.util.Themes;
import com.android.launcher3.views.AbstractSlideInView;
import com.android.launcher3.views.BaseDragLayer;
-import androidx.core.graphics.ColorUtils;
-
/**
* Base class for various widgets popup
*/
@@ -162,11 +161,11 @@ abstract class BaseWidgetSheet extends AbstractSlideInView
private static View createColorScrim(Context context) {
View view = new View(context);
- view.forceHasOverlappingRendering(false);
+ if (Utilities.ATLEAST_NOUGAT) view.forceHasOverlappingRendering(false);
WallpaperColorInfo colors = WallpaperColorInfo.getInstance(context);
int alpha = context.getResources().getInteger(R.integer.extracted_color_gradient_alpha);
- view.setBackgroundColor(ColorUtils.setAlphaComponent(colors.getSecondaryColor(), alpha));
+ view.setBackgroundColor(setColorAlphaBound(colors.getSecondaryColor(), alpha));
BaseDragLayer.LayoutParams lp = new BaseDragLayer.LayoutParams(MATCH_PARENT, MATCH_PARENT);
lp.ignoreInsets = true;
diff --git a/src_shortcuts_overrides/com/android/launcher3/model/LoaderResults.java b/src_shortcuts_overrides/com/android/launcher3/model/LoaderResults.java
new file mode 100644
index 0000000000..9785887ac7
--- /dev/null
+++ b/src_shortcuts_overrides/com/android/launcher3/model/LoaderResults.java
@@ -0,0 +1,67 @@
+/*
+ * 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.model;
+
+import com.android.launcher3.AllAppsList;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherModel.Callbacks;
+import com.android.launcher3.util.ComponentKey;
+import com.android.launcher3.widget.WidgetListRowEntry;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * Helper class to handle results of {@link com.android.launcher3.model.LoaderTask}.
+ */
+public class LoaderResults extends BaseLoaderResults {
+
+ public LoaderResults(LauncherAppState app, BgDataModel dataModel,
+ AllAppsList allAppsList, int pageToBindFirst, WeakReference callbacks) {
+ super(app, dataModel, allAppsList, pageToBindFirst, callbacks);
+ }
+
+ @Override
+ public void bindDeepShortcuts() {
+ final HashMap shortcutMapCopy;
+ synchronized (mBgDataModel) {
+ shortcutMapCopy = new HashMap<>(mBgDataModel.deepShortcutMap);
+ }
+ mUiExecutor.execute(() -> {
+ Callbacks callbacks = mCallbacks.get();
+ if (callbacks != null) {
+ callbacks.bindDeepShortcutMap(shortcutMapCopy);
+ }
+ });
+ }
+
+ @Override
+ public void bindWidgets() {
+ final ArrayList widgets =
+ mBgDataModel.widgetsModel.getWidgetsList(mApp.getContext());
+ Runnable r = new Runnable() {
+ public void run() {
+ Callbacks callbacks = mCallbacks.get();
+ if (callbacks != null) {
+ callbacks.bindAllWidgets(widgets);
+ }
+ }
+ };
+ mUiExecutor.execute(r);
+ }
+}
diff --git a/src/com/android/launcher3/model/WidgetsModel.java b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
similarity index 100%
rename from src/com/android/launcher3/model/WidgetsModel.java
rename to src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
diff --git a/tests/dummy_app/Android.mk b/tests/dummy_app/Android.mk
new file mode 100644
index 0000000000..f4ab582ebf
--- /dev/null
+++ b/tests/dummy_app/Android.mk
@@ -0,0 +1,18 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := samples
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := Aardwolf
+
+LOCAL_SDK_VERSION := current
+
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_PACKAGE)
+
+# Use the following include to make our test apk.
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/dummy_app/AndroidManifest.xml b/tests/dummy_app/AndroidManifest.xml
new file mode 100644
index 0000000000..0546015a52
--- /dev/null
+++ b/tests/dummy_app/AndroidManifest.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/dummy_app/res/layout/empty_activity.xml b/tests/dummy_app/res/layout/empty_activity.xml
new file mode 100644
index 0000000000..377c56bc36
--- /dev/null
+++ b/tests/dummy_app/res/layout/empty_activity.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
diff --git a/tests/dummy_app/res/mipmap-anydpi/ic_launcher1.xml b/tests/dummy_app/res/mipmap-anydpi/ic_launcher1.xml
new file mode 100644
index 0000000000..37c8c7387a
--- /dev/null
+++ b/tests/dummy_app/res/mipmap-anydpi/ic_launcher1.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
diff --git a/tests/dummy_app/res/mipmap-anydpi/ic_launcher2.xml b/tests/dummy_app/res/mipmap-anydpi/ic_launcher2.xml
new file mode 100644
index 0000000000..20b2986b6c
--- /dev/null
+++ b/tests/dummy_app/res/mipmap-anydpi/ic_launcher2.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
diff --git a/tests/dummy_app/res/mipmap-xxhdpi/ic_launcher1.png b/tests/dummy_app/res/mipmap-xxhdpi/ic_launcher1.png
new file mode 100644
index 0000000000..73bc8e65b2
Binary files /dev/null and b/tests/dummy_app/res/mipmap-xxhdpi/ic_launcher1.png differ
diff --git a/tests/dummy_app/res/mipmap-xxhdpi/ic_launcher2.png b/tests/dummy_app/res/mipmap-xxhdpi/ic_launcher2.png
new file mode 100644
index 0000000000..cd40b63c20
Binary files /dev/null and b/tests/dummy_app/res/mipmap-xxhdpi/ic_launcher2.png differ
diff --git a/tests/dummy_app/res/mipmap-xxhdpi/icon_back_1.png b/tests/dummy_app/res/mipmap-xxhdpi/icon_back_1.png
new file mode 100644
index 0000000000..8debef3fc7
Binary files /dev/null and b/tests/dummy_app/res/mipmap-xxhdpi/icon_back_1.png differ
diff --git a/tests/dummy_app/res/mipmap-xxhdpi/icon_fore_1.png b/tests/dummy_app/res/mipmap-xxhdpi/icon_fore_1.png
new file mode 100644
index 0000000000..de4079bd28
Binary files /dev/null and b/tests/dummy_app/res/mipmap-xxhdpi/icon_fore_1.png differ
diff --git a/tests/dummy_app/res/mipmap-xxxhdpi/ic_launcher1.png b/tests/dummy_app/res/mipmap-xxxhdpi/ic_launcher1.png
new file mode 100644
index 0000000000..889a99cfb7
Binary files /dev/null and b/tests/dummy_app/res/mipmap-xxxhdpi/ic_launcher1.png differ
diff --git a/tests/dummy_app/res/mipmap-xxxhdpi/ic_launcher2.png b/tests/dummy_app/res/mipmap-xxxhdpi/ic_launcher2.png
new file mode 100644
index 0000000000..973bb794b2
Binary files /dev/null and b/tests/dummy_app/res/mipmap-xxxhdpi/ic_launcher2.png differ
diff --git a/tests/dummy_app/res/mipmap-xxxhdpi/icon_back_1.png b/tests/dummy_app/res/mipmap-xxxhdpi/icon_back_1.png
new file mode 100644
index 0000000000..70c0ebd783
Binary files /dev/null and b/tests/dummy_app/res/mipmap-xxxhdpi/icon_back_1.png differ
diff --git a/tests/dummy_app/res/mipmap-xxxhdpi/icon_fore_1.png b/tests/dummy_app/res/mipmap-xxxhdpi/icon_fore_1.png
new file mode 100644
index 0000000000..9d91632113
Binary files /dev/null and b/tests/dummy_app/res/mipmap-xxxhdpi/icon_fore_1.png differ
diff --git a/tests/dummy_app/res/values/colors.xml b/tests/dummy_app/res/values/colors.xml
new file mode 100644
index 0000000000..b5ce66e9fb
--- /dev/null
+++ b/tests/dummy_app/res/values/colors.xml
@@ -0,0 +1,4 @@
+
+
+ #455A64
+
\ No newline at end of file
diff --git a/tests/dummy_app/src/com/example/android/aardwolf/Activity1.java b/tests/dummy_app/src/com/example/android/aardwolf/Activity1.java
new file mode 100644
index 0000000000..d4eab1545d
--- /dev/null
+++ b/tests/dummy_app/src/com/example/android/aardwolf/Activity1.java
@@ -0,0 +1,31 @@
+/*
+ * 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.example.android.aardwolf;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+
+public class Activity1 extends Activity {
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ View view = getLayoutInflater().inflate(R.layout.empty_activity, null);
+ setContentView(view);
+ }
+}
+
diff --git a/tests/res/raw/aardwolf_dummy_app.apk b/tests/res/raw/aardwolf_dummy_app.apk
new file mode 100644
index 0000000000..39fb368ca9
Binary files /dev/null and b/tests/res/raw/aardwolf_dummy_app.apk differ
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 532d3e8b00..bc5aaeeb75 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -296,11 +296,6 @@ public abstract class AbstractLauncherUiTest {
Process.myUserHandle()).get(0);
}
- protected LauncherActivityInfo getChromeApp() {
- return LauncherAppsCompat.getInstance(mTargetContext)
- .getActivityList("com.android.chrome", Process.myUserHandle()).get(0);
- }
-
/**
* Broadcast receiver which blocks until the result is received.
*/
diff --git a/tests/src/com/android/launcher3/ui/AllAppsIconToHomeTest.java b/tests/src/com/android/launcher3/ui/AllAppsIconToHomeTest.java
index 916007607f..9354862487 100644
--- a/tests/src/com/android/launcher3/ui/AllAppsIconToHomeTest.java
+++ b/tests/src/com/android/launcher3/ui/AllAppsIconToHomeTest.java
@@ -1,18 +1,10 @@
package com.android.launcher3.ui;
-import static org.junit.Assert.assertTrue;
-
import android.content.pm.LauncherActivityInfo;
+
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
-import androidx.test.uiautomator.By;
-import androidx.test.uiautomator.UiObject2;
-import androidx.test.uiautomator.Until;
-import com.android.launcher3.util.Condition;
-import com.android.launcher3.util.Wait;
-
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -24,37 +16,23 @@ import org.junit.runner.RunWith;
public class AllAppsIconToHomeTest extends AbstractLauncherUiTest {
@Test
- @Ignore
- public void testDragIcon_portrait() throws Throwable {
- lockRotation(true);
- performTest();
- }
-
- @Test
- @Ignore
- public void testDragIcon_landscape() throws Throwable {
- lockRotation(false);
- performTest();
- }
-
- private void performTest() throws Throwable {
+ @PortraitLandscape
+ public void testDragIcon() throws Throwable {
LauncherActivityInfo settingsApp = getSettingsApp();
clearHomescreen();
mDevice.pressHome();
mDevice.waitForIdle();
- // Open all apps and wait for load complete.
- final UiObject2 appsContainer = TestViewHelpers.openAllApps();
- Wait.atMost(null, Condition.minChildCount(appsContainer, 2), DEFAULT_UI_TIMEOUT);
-
- // Drag icon to homescreen.
- UiObject2 icon = scrollAndFind(appsContainer, By.text(settingsApp.getLabel().toString()));
- TestViewHelpers.dragToWorkspace(icon, true);
-
- // Verify that the icon works on homescreen.
- mDevice.findObject(By.text(settingsApp.getLabel().toString())).click();
- assertTrue(mDevice.wait(Until.hasObject(By.pkg(
- settingsApp.getComponentName().getPackageName()).depth(0)), DEFAULT_UI_TIMEOUT));
+ final String appName = settingsApp.getLabel().toString();
+ // 1. Open all apps and wait for load complete.
+ // 2. Drag icon to homescreen.
+ // 3. Verify that the icon works on homescreen.
+ mLauncher.getWorkspace().
+ switchToAllApps().
+ getAppIcon(appName).
+ dragToWorkspace().
+ getWorkspaceAppIcon(appName).
+ launch(settingsApp.getComponentName().getPackageName());
}
}
diff --git a/tests/src/com/android/launcher3/ui/ShortcutsLaunchTest.java b/tests/src/com/android/launcher3/ui/ShortcutsLaunchTest.java
index d7a7f6bbe7..1fea4d5c88 100644
--- a/tests/src/com/android/launcher3/ui/ShortcutsLaunchTest.java
+++ b/tests/src/com/android/launcher3/ui/ShortcutsLaunchTest.java
@@ -1,22 +1,18 @@
package com.android.launcher3.ui;
-import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import android.content.pm.LauncherActivityInfo;
-import android.graphics.Point;
+
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
-import androidx.test.uiautomator.By;
-import androidx.test.uiautomator.UiObject2;
-import androidx.test.uiautomator.Until;
-import android.view.MotionEvent;
-import com.android.launcher3.R;
-import com.android.launcher3.util.Condition;
-import com.android.launcher3.util.Wait;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.popup.ArrowPopup;
+import com.android.launcher3.tapl.AppIconMenu;
+import com.android.launcher3.tapl.AppIconMenuItem;
+import com.android.launcher3.views.OptionsPopupView;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -27,47 +23,30 @@ import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class ShortcutsLaunchTest extends AbstractLauncherUiTest {
- @Test
- @Ignore
- public void testAppLauncher_portrait() throws Exception {
- lockRotation(true);
- performTest();
+ private boolean isOptionsPopupVisible(Launcher launcher) {
+ final ArrowPopup popup = OptionsPopupView.getOptionsPopup(launcher);
+ return popup != null && popup.isShown();
}
@Test
- @Ignore
- public void testAppLauncher_landscape() throws Exception {
- lockRotation(false);
- performTest();
- }
-
- private void performTest() throws Exception {
+ @PortraitLandscape
+ public void testAppLauncher() throws Exception {
mActivityMonitor.startLauncher();
- LauncherActivityInfo testApp = getSettingsApp();
+ final LauncherActivityInfo testApp = getSettingsApp();
- // Open all apps and wait for load complete
- final UiObject2 appsContainer = TestViewHelpers.openAllApps();
- Wait.atMost(null, Condition.minChildCount(appsContainer, 2), DEFAULT_UI_TIMEOUT);
+ final AppIconMenu menu = mLauncher.
+ pressHome().
+ switchToAllApps().
+ getAppIcon(testApp.getLabel().toString()).
+ openMenu();
- // Find settings app and verify shortcuts appear when long pressed
- UiObject2 icon = scrollAndFind(appsContainer, By.text(testApp.getLabel().toString()));
- // Press icon center until shortcuts appear
- Point iconCenter = icon.getVisibleCenter();
- TestViewHelpers.sendPointer(MotionEvent.ACTION_DOWN, iconCenter);
- UiObject2 deepShortcutsContainer = TestViewHelpers.findViewById(
- R.id.deep_shortcuts_container);
- assertNotNull(deepShortcutsContainer);
- TestViewHelpers.sendPointer(MotionEvent.ACTION_UP, iconCenter);
+ executeOnLauncher(
+ launcher -> assertTrue("Launcher internal state didn't switch to Showing Menu",
+ isOptionsPopupVisible(launcher)));
- // Verify that launching a shortcut opens a page with the same text
- assertTrue(deepShortcutsContainer.getChildCount() > 0);
+ final AppIconMenuItem menuItem = menu.getMenuItem(1);
+ final String itemName = menuItem.getText();
- // Pick second children as it starts showing shortcuts.
- UiObject2 shortcut = deepShortcutsContainer.getChildren().get(1)
- .findObject(TestViewHelpers.getSelectorForId(R.id.bubble_text));
- shortcut.click();
- assertTrue(mDevice.wait(Until.hasObject(By.pkg(
- testApp.getComponentName().getPackageName())
- .text(shortcut.getText())), DEFAULT_UI_TIMEOUT));
+ menuItem.launch(testApp.getComponentName().getPackageName(), itemName);
}
}
diff --git a/tests/src/com/android/launcher3/ui/ShortcutsToHomeTest.java b/tests/src/com/android/launcher3/ui/ShortcutsToHomeTest.java
index 436c6991db..4c2c959b72 100644
--- a/tests/src/com/android/launcher3/ui/ShortcutsToHomeTest.java
+++ b/tests/src/com/android/launcher3/ui/ShortcutsToHomeTest.java
@@ -1,22 +1,12 @@
package com.android.launcher3.ui;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
import android.content.pm.LauncherActivityInfo;
-import android.graphics.Point;
+
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
-import androidx.test.uiautomator.By;
-import androidx.test.uiautomator.UiObject2;
-import androidx.test.uiautomator.Until;
-import android.view.MotionEvent;
-import com.android.launcher3.R;
-import com.android.launcher3.util.Condition;
-import com.android.launcher3.util.Wait;
+import com.android.launcher3.tapl.AppIconMenuItem;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -28,51 +18,30 @@ import org.junit.runner.RunWith;
public class ShortcutsToHomeTest extends AbstractLauncherUiTest {
@Test
- @Ignore
- public void testDragIcon_portrait() throws Throwable {
- lockRotation(true);
- performTest();
- }
-
- @Test
- @Ignore
- public void testDragIcon_landscape() throws Throwable {
- lockRotation(false);
- performTest();
- }
-
- private void performTest() throws Throwable {
+ @PortraitLandscape
+ public void testDragIcon() throws Throwable {
clearHomescreen();
mActivityMonitor.startLauncher();
- LauncherActivityInfo testApp = getSettingsApp();
+ LauncherActivityInfo testApp = getSettingsApp();
- // Open all apps and wait for load complete.
- final UiObject2 appsContainer = TestViewHelpers.openAllApps();
- Wait.atMost(null, Condition.minChildCount(appsContainer, 2), DEFAULT_UI_TIMEOUT);
+ // 1. Open all apps and wait for load complete.
+ // 2. Find the app and long press it to show shortcuts.
+ // 3. Press icon center until shortcuts appear
+ final AppIconMenuItem menuItem = mLauncher.
+ getWorkspace().
+ switchToAllApps().
+ getAppIcon(testApp.getLabel().toString()).
+ openMenu().
+ getMenuItem(0);
+ final String shortcutName = menuItem.getText();
- // Find the app and long press it to show shortcuts.
- UiObject2 icon = scrollAndFind(appsContainer, By.text(testApp.getLabel().toString()));
- // Press icon center until shortcuts appear
- Point iconCenter = icon.getVisibleCenter();
- TestViewHelpers.sendPointer(MotionEvent.ACTION_DOWN, iconCenter);
- UiObject2 deepShortcutsContainer = TestViewHelpers.findViewById(
- R.id.deep_shortcuts_container);
- assertNotNull(deepShortcutsContainer);
- TestViewHelpers.sendPointer(MotionEvent.ACTION_UP, iconCenter);
-
- // Drag the first shortcut to the home screen.
- assertTrue(deepShortcutsContainer.getChildCount() > 0);
- UiObject2 shortcut = deepShortcutsContainer.getChildren().get(1)
- .findObject(TestViewHelpers.getSelectorForId(R.id.bubble_text));
- String shortcutName = shortcut.getText();
- TestViewHelpers.dragToWorkspace(shortcut, false);
-
- // Verify that the shortcut works on home screen
- // (the app opens and has the same text as the shortcut).
- mDevice.findObject(By.text(shortcutName)).click();
- assertTrue(mDevice.wait(Until.hasObject(By.pkg(
- testApp.getComponentName().getPackageName())
- .text(shortcutName)), DEFAULT_UI_TIMEOUT));
+ // 4. Drag the first shortcut to the home screen.
+ // 5. Verify that the shortcut works on home screen
+ // (the app opens and has the same text as the shortcut).
+ menuItem.
+ dragToWorkspace().
+ getWorkspaceAppIcon(shortcutName).
+ launch(testApp.getComponentName().getPackageName(), shortcutName);
}
}
diff --git a/tests/src/com/android/launcher3/util/IntSetTest.java b/tests/src/com/android/launcher3/util/IntSetTest.java
deleted file mode 100644
index 934b749f5e..0000000000
--- a/tests/src/com/android/launcher3/util/IntSetTest.java
+++ /dev/null
@@ -1,58 +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.launcher3.util;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Unit tests for {@link IntSet}
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class IntSetTest {
-
- @Test
- public void testDuplicateEntries() {
- IntSet set = new IntSet();
-
- set.add(2);
- assertEquals(1, set.size());
-
- set.add(2);
- assertEquals(1, set.size());
- assertTrue(set.contains(2));
- assertFalse(set.contains(1));
-
- set.add(1);
- assertEquals(2, set.size());
- assertTrue(set.contains(2));
- assertTrue(set.contains(1));
-
-
- set.add(10);
- assertEquals(3, set.size());
-
- assertEquals("1, 2, 10", set.mArray.toConcatString());
- }
-}
diff --git a/tests/src/com/android/launcher3/util/TestUtil.java b/tests/src/com/android/launcher3/util/TestUtil.java
new file mode 100644
index 0000000000..1338dcb108
--- /dev/null
+++ b/tests/src/com/android/launcher3/util/TestUtil.java
@@ -0,0 +1,51 @@
+/*
+ * 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.util;
+
+import static androidx.test.InstrumentationRegistry.getContext;
+import static androidx.test.InstrumentationRegistry.getInstrumentation;
+
+import android.content.res.Resources;
+
+import androidx.test.uiautomator.UiDevice;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class TestUtil {
+ public static void installDummyApp() throws IOException {
+ // Copy apk from resources to a local file and install from there.
+ final Resources resources = getContext().getResources();
+ final InputStream in = resources.openRawResource(
+ resources.getIdentifier("aardwolf_dummy_app",
+ "raw", getContext().getPackageName()));
+ final String apkFilename = getInstrumentation().getTargetContext().
+ getFilesDir().getPath() + "/dummy_app.apk";
+
+ final FileOutputStream out = new FileOutputStream(apkFilename);
+ byte[] buff = new byte[1024];
+ int read;
+
+ while ((read = in.read(buff)) > 0) {
+ out.write(buff, 0, read);
+ }
+ in.close();
+ out.close();
+
+ UiDevice.getInstance(getInstrumentation()).executeShellCommand("pm install " + apkFilename);
+ }
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/AppIcon.java b/tests/tapl/com/android/launcher3/tapl/AppIcon.java
index b7ae9f1497..efefc0dca2 100644
--- a/tests/tapl/com/android/launcher3/tapl/AppIcon.java
+++ b/tests/tapl/com/android/launcher3/tapl/AppIcon.java
@@ -16,23 +16,19 @@
package com.android.launcher3.tapl;
+import android.graphics.Point;
import android.widget.TextView;
import androidx.test.uiautomator.By;
import androidx.test.uiautomator.BySelector;
import androidx.test.uiautomator.UiObject2;
-import androidx.test.uiautomator.Until;
/**
* App icon, whether in all apps or in workspace/
*/
-public final class AppIcon {
- private final LauncherInstrumentation mLauncher;
- private final UiObject2 mIcon;
-
+public final class AppIcon extends Launchable {
AppIcon(LauncherInstrumentation launcher, UiObject2 icon) {
- mLauncher = launcher;
- mIcon = icon;
+ super(launcher, icon);
}
static BySelector getAppIconSelector(String appName) {
@@ -40,20 +36,13 @@ public final class AppIcon {
}
/**
- * Clicks the icon to launch its app.
+ * Long-clicks the icon to open its menu.
*/
- public Background launch(String packageName) {
- LauncherInstrumentation.log("AppIcon.launch before click " + mIcon.getVisibleCenter());
- LauncherInstrumentation.assertTrue(
- "Launching an app didn't open a new window: " + mIcon.getText(),
- mIcon.clickAndWait(Until.newWindow(), LauncherInstrumentation.WAIT_TIME_MS));
- LauncherInstrumentation.assertTrue(
- "App didn't start: " + packageName, mLauncher.getDevice().wait(Until.hasObject(
- By.pkg(packageName).depth(0)), LauncherInstrumentation.WAIT_TIME_MS));
- return new Background(mLauncher);
- }
-
- UiObject2 getIcon() {
- return mIcon;
+ public AppIconMenu openMenu() {
+ final Point iconCenter = mObject.getVisibleCenter();
+ mLauncher.longTap(iconCenter.x, iconCenter.y);
+ final UiObject2 deepShortcutsContainer = mLauncher.waitForLauncherObject(
+ "deep_shortcuts_container");
+ return new AppIconMenu(mLauncher, deepShortcutsContainer);
}
}
diff --git a/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java b/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java
new file mode 100644
index 0000000000..2a03f9a089
--- /dev/null
+++ b/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java
@@ -0,0 +1,46 @@
+/*
+ * 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.tapl;
+
+import static org.junit.Assert.assertTrue;
+
+import androidx.test.uiautomator.UiObject2;
+
+/**
+ * Context menu of an app icon.
+ */
+public class AppIconMenu {
+ private final LauncherInstrumentation mLauncher;
+ private final UiObject2 mDeepShortcutsContainer;
+
+ AppIconMenu(LauncherInstrumentation launcher,
+ UiObject2 deepShortcutsContainer) {
+ mLauncher = launcher;
+ mDeepShortcutsContainer = deepShortcutsContainer;
+ }
+
+ /**
+ * Returns a menu item with a given number. Fails if it doesn't exist.
+ */
+ public AppIconMenuItem getMenuItem(int itemNumber) {
+ assertTrue(mDeepShortcutsContainer.getChildCount() > itemNumber);
+
+ final UiObject2 shortcut = mLauncher.waitForObjectInContainer(
+ mDeepShortcutsContainer.getChildren().get(itemNumber), "bubble_text");
+ return new AppIconMenuItem(mLauncher, shortcut);
+ }
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/AppIconMenuItem.java b/tests/tapl/com/android/launcher3/tapl/AppIconMenuItem.java
new file mode 100644
index 0000000000..c39f8d1675
--- /dev/null
+++ b/tests/tapl/com/android/launcher3/tapl/AppIconMenuItem.java
@@ -0,0 +1,35 @@
+/*
+ * 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.tapl;
+
+import androidx.test.uiautomator.UiObject2;
+
+/**
+ * Menu item in an app icon menu.
+ */
+public class AppIconMenuItem extends Launchable {
+ AppIconMenuItem(LauncherInstrumentation launcher, UiObject2 shortcut) {
+ super(launcher, shortcut);
+ }
+
+ /**
+ * Returns the visible text of the menu item.
+ */
+ public String getText() {
+ return mObject.getText();
+ }
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/Launchable.java b/tests/tapl/com/android/launcher3/tapl/Launchable.java
new file mode 100644
index 0000000000..7e2c9660d5
--- /dev/null
+++ b/tests/tapl/com/android/launcher3/tapl/Launchable.java
@@ -0,0 +1,81 @@
+/*
+ * 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.tapl;
+
+import android.graphics.Point;
+
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.BySelector;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.UiObject2;
+import androidx.test.uiautomator.Until;
+
+/**
+ * Ancestor for AppIcon and AppMenuItem.
+ */
+class Launchable {
+ private static final int DRAG_SPEED = 500;
+ protected final LauncherInstrumentation mLauncher;
+
+ protected final UiObject2 mObject;
+
+ Launchable(LauncherInstrumentation launcher, UiObject2 object) {
+ mObject = object;
+ mLauncher = launcher;
+ }
+
+ UiObject2 getObject() {
+ return mObject;
+ }
+
+ /**
+ * Clicks the object to launch its app.
+ */
+ public Background launch(String expectedPackageName) {
+ return launch(expectedPackageName, By.pkg(expectedPackageName).depth(0));
+ }
+
+ /**
+ * Clicks the object to launch its app.
+ */
+ public Background launch(String expectedPackageName, String expectedAppText) {
+ return launch(expectedPackageName, By.pkg(expectedPackageName).text(expectedAppText));
+ }
+
+ private Background launch(String errorMessage, BySelector selector) {
+ LauncherInstrumentation.log("Launchable.launch before click " +
+ mObject.getVisibleCenter());
+ LauncherInstrumentation.assertTrue(
+ "Launching an app didn't open a new window: " + mObject.getText(),
+ mObject.clickAndWait(Until.newWindow(), LauncherInstrumentation.WAIT_TIME_MS));
+ LauncherInstrumentation.assertTrue(
+ "App didn't start: " + errorMessage,
+ mLauncher.getDevice().wait(Until.hasObject(selector),
+ LauncherInstrumentation.WAIT_TIME_MS));
+ return new Background(mLauncher);
+ }
+
+ /**
+ * Drags an object to the center of homescreen.
+ */
+ public Workspace dragToWorkspace() {
+ final UiDevice device = mLauncher.getDevice();
+ mObject.drag(new Point(
+ device.getDisplayWidth() / 2, device.getDisplayHeight() / 2), DRAG_SPEED);
+ return new Workspace(mLauncher);
+ }
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 31abc53c91..67106f7eac 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -28,6 +28,13 @@ import android.util.Log;
import android.view.Surface;
import android.view.accessibility.AccessibilityEvent;
+import androidx.annotation.NonNull;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.BySelector;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.UiObject2;
+import androidx.test.uiautomator.Until;
+
import com.android.launcher3.TestProtocol;
import com.android.quickstep.SwipeUpSetting;
@@ -36,13 +43,6 @@ import org.junit.Assert;
import java.lang.ref.WeakReference;
import java.util.concurrent.TimeoutException;
-import androidx.annotation.NonNull;
-import androidx.test.uiautomator.By;
-import androidx.test.uiautomator.BySelector;
-import androidx.test.uiautomator.UiDevice;
-import androidx.test.uiautomator.UiObject2;
-import androidx.test.uiautomator.Until;
-
/**
* The main tapl object. The only object that can be explicitly constructed by the using code. It
* produces all other objects.
@@ -394,6 +394,11 @@ public final class LauncherInstrumentation {
return mDevice;
}
+ void longTap(int x, int y) {
+ mDevice.drag(x, y, x, y, 0);
+ }
+
+
void swipe(int startX, int startY, int endX, int endY) {
executeAndWaitForEvent(
() -> mDevice.swipe(startX, startY, endX, endY, 60),
diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java
index 493f26ae9c..c63822e2ea 100644
--- a/tests/tapl/com/android/launcher3/tapl/Workspace.java
+++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java
@@ -19,12 +19,12 @@ package com.android.launcher3.tapl;
import static junit.framework.TestCase.assertTrue;
import android.graphics.Point;
-import androidx.test.uiautomator.Direction;
-import androidx.test.uiautomator.UiObject2;
import android.view.KeyEvent;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.test.uiautomator.Direction;
+import androidx.test.uiautomator.UiObject2;
/**
* Operations on the workspace screen.
@@ -85,6 +85,21 @@ public final class Workspace extends Home {
return icon != null ? new AppIcon(mLauncher, icon) : null;
}
+
+ /**
+ * Returns an icon for the app; fails if the icon doesn't exist.
+ *
+ * @param appName name of the app
+ * @return app icon.
+ */
+ @NonNull
+ public AppIcon getWorkspaceAppIcon(String appName) {
+ return new AppIcon(mLauncher,
+ mLauncher.getObjectInContainer(
+ verifyActiveContainer(),
+ AppIcon.getAppIconSelector(appName)));
+ }
+
/**
* Ensures that workspace is scrollable. If it's not, drags an icon icons from hotseat to the
* second screen.
@@ -111,7 +126,7 @@ public final class Workspace extends Home {
private void dragIconToNextScreen(AppIcon app, UiObject2 workspace) {
final Point dest = new Point(
mLauncher.getDevice().getDisplayWidth(), workspace.getVisibleBounds().centerY());
- app.getIcon().drag(dest, ICON_DRAG_SPEED);
+ app.getObject().drag(dest, ICON_DRAG_SPEED);
verifyActiveContainer();
}