Merge "Make TogglableFlag backed by DeviceConfig for e2e testing" into ub-launcher3-qt-qpr1-dev
diff --git a/SecondaryDisplayLauncher/res/values-zh-rTW/strings.xml b/SecondaryDisplayLauncher/res/values-zh-rTW/strings.xml
index bf76f29..c02fe2c 100644
--- a/SecondaryDisplayLauncher/res/values-zh-rTW/strings.xml
+++ b/SecondaryDisplayLauncher/res/values-zh-rTW/strings.xml
@@ -21,5 +21,5 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="couldnt_launch" msgid="7873588052226763866">"無法啟動活動"</string>
<string name="add_app_shortcut" msgid="2756755330707509435">"新增應用程式捷徑"</string>
- <string name="set_wallpaper" msgid="6475195450505435904">"設定桌布"</string>
+ <string name="set_wallpaper" msgid="6475195450505435904">"套用桌布"</string>
</resources>
diff --git a/go/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/LandscapeStatesTouchController.java b/go/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/LandscapeStatesTouchController.java
index 1ccd7d7..66aec40 100644
--- a/go/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/LandscapeStatesTouchController.java
+++ b/go/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/LandscapeStatesTouchController.java
@@ -64,7 +64,7 @@
}
@Override
- protected int getLogContainerTypeForNormalState() {
+ protected int getLogContainerTypeForNormalState(MotionEvent ev) {
return LauncherLogProto.ContainerType.WORKSPACE;
}
}
diff --git a/go/src/com/android/launcher3/shortcuts/DeepShortcutManager.java b/go/src/com/android/launcher3/shortcuts/DeepShortcutManager.java
index 1e44910..ee113df 100644
--- a/go/src/com/android/launcher3/shortcuts/DeepShortcutManager.java
+++ b/go/src/com/android/launcher3/shortcuts/DeepShortcutManager.java
@@ -25,6 +25,7 @@
import android.os.UserHandle;
import com.android.launcher3.ItemInfo;
+import com.android.launcher3.notification.NotificationKeyData;
import java.util.Collections;
import java.util.List;
@@ -48,10 +49,6 @@
private DeepShortcutManager(Context context) {
}
- public static boolean supportsShortcuts(ItemInfo info) {
- return false;
- }
-
public boolean wasLastCallSuccess() {
return false;
}
diff --git a/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java b/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java
index d84633d..36d1c3e 100644
--- a/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java
+++ b/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java
@@ -36,12 +36,16 @@
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Handler;
+import android.os.LocaleList;
import android.os.Looper;
import android.os.Process;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
import com.android.launcher3.icons.BaseIconFactory;
import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.icons.BitmapRenderer;
@@ -57,8 +61,6 @@
import java.util.Set;
import java.util.function.Supplier;
-import androidx.annotation.NonNull;
-
public abstract class BaseIconCache {
private static final String TAG = "BaseIconCache";
@@ -84,6 +86,7 @@
protected int mIconDpi;
protected IconDB mIconDb;
+ protected LocaleList mLocaleList = LocaleList.getEmptyLocaleList();
protected String mSystemState = "";
private final String mDbFileName;
@@ -227,12 +230,12 @@
/**
* Refreshes the system state definition used to check the validity of the cache. It
- * incorporates all the properties that can affect the cache like locale and system-version.
+ * incorporates all the properties that can affect the cache like the list of enabled locale
+ * and system-version.
*/
private void updateSystemState() {
- final String locale =
- mContext.getResources().getConfiguration().getLocales().toLanguageTags();
- mSystemState = locale + "," + Build.VERSION.SDK_INT;
+ mLocaleList = mContext.getResources().getConfiguration().getLocales();
+ mSystemState = mLocaleList.toLanguageTags() + "," + Build.VERSION.SDK_INT;
}
protected String getIconSystemState(String packageName) {
@@ -269,7 +272,7 @@
mCache.put(key, entry);
ContentValues values = newContentValues(entry, entry.title.toString(),
- componentName.getPackageName());
+ componentName.getPackageName(), cachingLogic.getKeywords(object, mLocaleList));
addIconToDB(values, componentName, info, userSerial);
}
@@ -445,7 +448,7 @@
// Add the icon in the DB here, since these do not get written during
// package updates.
ContentValues values = newContentValues(
- iconInfo, entry.title.toString(), packageName);
+ iconInfo, entry.title.toString(), packageName, null);
addIconToDB(values, cacheKey.componentName, info, getSerialNumberForUser(user));
} catch (NameNotFoundException e) {
@@ -504,23 +507,35 @@
return false;
}
- static final class IconDB extends SQLiteCacheHelper {
- private final static int RELEASE_VERSION = 26;
+ /**
+ * Returns a cursor for an arbitrary query to the cache db
+ */
+ public synchronized Cursor queryCacheDb(String[] columns, String selection,
+ String[] selectionArgs) {
+ return mIconDb.query(columns, selection, selectionArgs);
+ }
- public final static String TABLE_NAME = "icons";
- public final static String COLUMN_ROWID = "rowid";
- public final static String COLUMN_COMPONENT = "componentName";
- public final static String COLUMN_USER = "profileId";
- public final static String COLUMN_LAST_UPDATED = "lastUpdated";
- public final static String COLUMN_VERSION = "version";
- public final static String COLUMN_ICON = "icon";
- public final static String COLUMN_ICON_COLOR = "icon_color";
- public final static String COLUMN_LABEL = "label";
- public final static String COLUMN_SYSTEM_STATE = "system_state";
+ /**
+ * Cache class to store the actual entries on disk
+ */
+ public static final class IconDB extends SQLiteCacheHelper {
+ private static final int RELEASE_VERSION = 27;
- public final static String[] COLUMNS_HIGH_RES = new String[] {
+ public static final String TABLE_NAME = "icons";
+ public static final String COLUMN_ROWID = "rowid";
+ public static final String COLUMN_COMPONENT = "componentName";
+ public static final String COLUMN_USER = "profileId";
+ public static final String COLUMN_LAST_UPDATED = "lastUpdated";
+ public static final String COLUMN_VERSION = "version";
+ public static final String COLUMN_ICON = "icon";
+ public static final String COLUMN_ICON_COLOR = "icon_color";
+ public static final String COLUMN_LABEL = "label";
+ public static final String COLUMN_SYSTEM_STATE = "system_state";
+ public static final String COLUMN_KEYWORDS = "keywords";
+
+ public static final String[] COLUMNS_HIGH_RES = new String[] {
IconDB.COLUMN_ICON_COLOR, IconDB.COLUMN_LABEL, IconDB.COLUMN_ICON };
- public final static String[] COLUMNS_LOW_RES = new String[] {
+ public static final String[] COLUMNS_LOW_RES = new String[] {
IconDB.COLUMN_ICON_COLOR, IconDB.COLUMN_LABEL };
public IconDB(Context context, String dbFileName, int iconPixelSize) {
@@ -529,21 +544,23 @@
@Override
protected void onCreateTable(SQLiteDatabase db) {
- db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" +
- COLUMN_COMPONENT + " TEXT NOT NULL, " +
- COLUMN_USER + " INTEGER NOT NULL, " +
- COLUMN_LAST_UPDATED + " INTEGER NOT NULL DEFAULT 0, " +
- COLUMN_VERSION + " INTEGER NOT NULL DEFAULT 0, " +
- COLUMN_ICON + " BLOB, " +
- COLUMN_ICON_COLOR + " INTEGER NOT NULL DEFAULT 0, " +
- COLUMN_LABEL + " TEXT, " +
- COLUMN_SYSTEM_STATE + " TEXT, " +
- "PRIMARY KEY (" + COLUMN_COMPONENT + ", " + COLUMN_USER + ") " +
- ");");
+ db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " ("
+ + COLUMN_COMPONENT + " TEXT NOT NULL, "
+ + COLUMN_USER + " INTEGER NOT NULL, "
+ + COLUMN_LAST_UPDATED + " INTEGER NOT NULL DEFAULT 0, "
+ + COLUMN_VERSION + " INTEGER NOT NULL DEFAULT 0, "
+ + COLUMN_ICON + " BLOB, "
+ + COLUMN_ICON_COLOR + " INTEGER NOT NULL DEFAULT 0, "
+ + COLUMN_LABEL + " TEXT, "
+ + COLUMN_SYSTEM_STATE + " TEXT, "
+ + COLUMN_KEYWORDS + " TEXT, "
+ + "PRIMARY KEY (" + COLUMN_COMPONENT + ", " + COLUMN_USER + ") "
+ + ");");
}
}
- private ContentValues newContentValues(BitmapInfo bitmapInfo, String label, String packageName) {
+ private ContentValues newContentValues(BitmapInfo bitmapInfo, String label,
+ String packageName, @Nullable String keywords) {
ContentValues values = new ContentValues();
values.put(IconDB.COLUMN_ICON,
bitmapInfo.isLowRes() ? null : GraphicsUtils.flattenBitmap(bitmapInfo.icon));
@@ -551,7 +568,7 @@
values.put(IconDB.COLUMN_LABEL, label);
values.put(IconDB.COLUMN_SYSTEM_STATE, getIconSystemState(packageName));
-
+ values.put(IconDB.COLUMN_KEYWORDS, keywords);
return values;
}
diff --git a/iconloaderlib/src/com/android/launcher3/icons/cache/CachingLogic.java b/iconloaderlib/src/com/android/launcher3/icons/cache/CachingLogic.java
index addb51f..09f59b8 100644
--- a/iconloaderlib/src/com/android/launcher3/icons/cache/CachingLogic.java
+++ b/iconloaderlib/src/com/android/launcher3/icons/cache/CachingLogic.java
@@ -17,8 +17,11 @@
import android.content.ComponentName;
import android.content.Context;
+import android.os.LocaleList;
import android.os.UserHandle;
+import androidx.annotation.Nullable;
+
import com.android.launcher3.icons.BitmapInfo;
public interface CachingLogic<T> {
@@ -30,4 +33,12 @@
CharSequence getLabel(T object);
void loadIcon(Context context, T object, BitmapInfo target);
+
+ /**
+ * Provides a option list of keywords to associate with this object
+ */
+ @Nullable
+ default String getKeywords(T object, LocaleList localeList) {
+ return null;
+ }
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/AppsDividerView.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/AppsDividerView.java
index 311db21..425fb13 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/AppsDividerView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/AppsDividerView.java
@@ -31,6 +31,9 @@
import android.view.View;
import android.view.animation.Interpolator;
+import androidx.annotation.ColorInt;
+import androidx.core.content.ContextCompat;
+
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
@@ -41,9 +44,6 @@
import com.android.launcher3.anim.PropertySetter;
import com.android.launcher3.util.Themes;
-import androidx.annotation.ColorInt;
-import androidx.core.content.ContextCompat;
-
/**
* A view which shows a horizontal divider
*/
@@ -288,10 +288,10 @@
}
@Override
- public void setContentVisibility(boolean hasHeaderExtra, boolean hasContent,
- PropertySetter setter, Interpolator fadeInterpolator) {
+ public void setContentVisibility(boolean hasHeaderExtra, boolean hasAllAppsContent,
+ PropertySetter setter, Interpolator headerFade, Interpolator allAppsFade) {
// Don't use setViewAlpha as we want to control the visibility ourselves.
- setter.setFloat(this, ALPHA, hasContent ? 1 : 0, fadeInterpolator);
+ setter.setFloat(this, ALPHA, hasAllAppsContent ? 1 : 0, allAppsFade);
}
@Override
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java
index 8f1282d..24fc61b 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java
@@ -95,6 +95,10 @@
private AppPredictor createPredictor(Client client, int count) {
AppPredictionManager apm = mContext.getSystemService(AppPredictionManager.class);
+ if (apm == null) {
+ return null;
+ }
+
AppPredictor predictor = apm.createAppPredictionSession(
new AppPredictionContext.Builder(mContext)
.setUiSurface(client.id)
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionRowView.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionRowView.java
index cb5cbdd..0c7ba9c 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionRowView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionRowView.java
@@ -32,6 +32,9 @@
import android.view.animation.Interpolator;
import android.widget.LinearLayout;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
import com.android.launcher3.AppInfo;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.DeviceProfile;
@@ -62,9 +65,6 @@
import java.util.Collections;
import java.util.List;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
@TargetApi(Build.VERSION_CODES.P)
public class PredictionRowView extends LinearLayout implements
LogContainerProvider, OnDeviceProfileChangeListener, FloatingHeaderRow {
@@ -80,7 +80,7 @@
@Override
public Integer get(PredictionRowView view) {
- return view.mIconCurrentTextAlpha;
+ return view.mIconLastSetTextAlpha;
}
};
@@ -103,6 +103,8 @@
private final int mIconTextColor;
private final int mIconFullTextAlpha;
+ private int mIconLastSetTextAlpha;
+ // Might use mIconFullTextAlpha instead of mIconLastSetTextAlpha if we are translucent.
private int mIconCurrentTextAlpha;
private FloatingHeaderView mParent;
@@ -315,8 +317,14 @@
}
}
- public void setTextAlpha(int alpha) {
- mIconCurrentTextAlpha = alpha;
+ public void setTextAlpha(int textAlpha) {
+ mIconLastSetTextAlpha = textAlpha;
+ if (getAlpha() < 1 && textAlpha > 0) {
+ // If the entire header is translucent, make sure the text is at full opacity so it's
+ // not double-translucent. However, we support keeping the text invisible (alpha == 0).
+ textAlpha = mIconFullTextAlpha;
+ }
+ mIconCurrentTextAlpha = textAlpha;
int iconColor = setColorAlphaBound(mIconTextColor, mIconCurrentTextAlpha);
for (int i = 0; i < getChildCount(); i++) {
((BubbleTextView) getChildAt(i)).setTextColor(iconColor);
@@ -324,6 +332,13 @@
}
@Override
+ public void setAlpha(float alpha) {
+ super.setAlpha(alpha);
+ // Reapply text alpha so that we update it to be full alpha if the row is now translucent.
+ setTextAlpha(mIconLastSetTextAlpha);
+ }
+
+ @Override
public boolean hasOverlappingRendering() {
return false;
}
@@ -351,23 +366,15 @@
}
@Override
- public void setContentVisibility(boolean hasHeaderExtra, boolean hasContent,
- PropertySetter setter, Interpolator fadeInterpolator) {
- boolean isDrawn = getAlpha() > 0;
- int textAlpha = hasHeaderExtra
- ? (hasContent ? mIconFullTextAlpha : 0) // Text follows the content visibility
- : mIconCurrentTextAlpha; // Leave as before
- if (!isDrawn) {
- // If the header is not drawn, no need to animate the text alpha
- setTextAlpha(textAlpha);
- } else {
- setter.setInt(this, TEXT_ALPHA, textAlpha, fadeInterpolator);
- }
-
+ public void setContentVisibility(boolean hasHeaderExtra, boolean hasAllAppsContent,
+ PropertySetter setter, Interpolator headerFade, Interpolator allAppsFade) {
+ // Text follows all apps visibility
+ int textAlpha = hasHeaderExtra && hasAllAppsContent ? mIconFullTextAlpha : 0;
+ setter.setInt(this, TEXT_ALPHA, textAlpha, allAppsFade);
setter.setFloat(mOverviewScrollFactor, AnimatedFloat.VALUE,
- (hasHeaderExtra && !hasContent) ? 1 : 0, LINEAR);
+ (hasHeaderExtra && !hasAllAppsContent) ? 1 : 0, LINEAR);
setter.setFloat(mContentAlphaFactor, AnimatedFloat.VALUE, hasHeaderExtra ? 1 : 0,
- fadeInterpolator);
+ headerFade);
}
@Override
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
index 5ee08c1..50cfac8 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
@@ -19,6 +19,7 @@
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Launcher;
+import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.AllAppsTransitionController;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.quickstep.util.LayoutUtils;
@@ -68,8 +69,8 @@
if (taskCount == 0) {
return super.getOverviewScaleAndTranslation(launcher);
}
- TaskView dummyTask = recentsView.getTaskViewAt(Math.max(taskCount - 1,
- recentsView.getCurrentPage()));
+ TaskView dummyTask = recentsView.getTaskViewAt(Utilities.boundToRange(
+ recentsView.getCurrentPage(), 0, taskCount - 1));
return recentsView.getTempClipAnimationHelper().updateForFullscreenOverview(dummyTask)
.getScaleAndTranslation();
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewPeekState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewPeekState.java
index c954762..427206a 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewPeekState.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewPeekState.java
@@ -15,7 +15,9 @@
*/
package com.android.launcher3.uioverrides.states;
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_FADE;
+import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_SCRIM_FADE;
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_TRANSLATE_X;
+import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.INSTANT;
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_7;
@@ -43,6 +45,7 @@
if (this == OVERVIEW_PEEK && fromState == NORMAL) {
builder.setInterpolator(ANIM_OVERVIEW_FADE, INSTANT);
builder.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, OVERSHOOT_1_7);
+ builder.setInterpolator(ANIM_OVERVIEW_SCRIM_FADE, FAST_OUT_SLOW_IN);
}
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java
index 5543860..151ceb8 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -43,7 +43,6 @@
import com.android.launcher3.Workspace;
import com.android.launcher3.allapps.DiscoveryBounce;
import com.android.launcher3.anim.AnimatorSetBuilder;
-import com.android.launcher3.uioverrides.UiFactory;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.quickstep.SysUINavigationMode;
@@ -128,14 +127,15 @@
if (launcher.getDeviceProfile().isVerticalBarLayout()) {
return VERTICAL_SWIPE_INDICATOR | RECENTS_CLEAR_ALL_BUTTON;
} else {
+ boolean hasAllAppsHeaderExtra = launcher.getAppsView() != null
+ && launcher.getAppsView().getFloatingHeaderView().hasVisibleContent();
return HOTSEAT_SEARCH_BOX | VERTICAL_SWIPE_INDICATOR | RECENTS_CLEAR_ALL_BUTTON |
- (launcher.getAppsView().getFloatingHeaderView().hasVisibleContent()
- ? ALL_APPS_HEADER_EXTRA : HOTSEAT_ICONS);
+ (hasAllAppsHeaderExtra ? ALL_APPS_HEADER_EXTRA : HOTSEAT_ICONS);
}
}
@Override
- public float getWorkspaceScrimAlpha(Launcher launcher) {
+ public float getOverviewScrimAlpha(Launcher launcher) {
return 0.5f;
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java
index f06b8a9..ab346c0 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java
@@ -23,13 +23,17 @@
import static com.android.launcher3.LauncherState.OVERVIEW_PEEK;
import static com.android.launcher3.LauncherStateManager.ANIM_ALL;
import static com.android.launcher3.LauncherStateManager.ATOMIC_OVERVIEW_PEEK_COMPONENT;
+import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_ALL_APPS_FADE;
+import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_ALL_APPS_HEADER_FADE;
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_HOTSEAT_SCALE;
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_HOTSEAT_TRANSLATE;
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_VERTICAL_PROGRESS;
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_WORKSPACE_FADE;
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_WORKSPACE_SCALE;
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_WORKSPACE_TRANSLATE;
+import static com.android.launcher3.anim.Interpolators.ACCEL;
import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
+import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
@@ -43,6 +47,7 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.anim.AnimatorSetBuilder;
+import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
import com.android.quickstep.OverviewInteractionState;
import com.android.quickstep.util.MotionPauseDetector;
@@ -102,6 +107,9 @@
mPeekAnim.start();
recentsView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
+
+ mLauncher.getDragLayer().getScrim().animateToSysuiMultiplier(isPaused ? 0 : 1,
+ peekDuration, 0);
});
}
}
@@ -120,6 +128,13 @@
LauncherState toState) {
if (fromState == NORMAL && toState == ALL_APPS) {
AnimatorSetBuilder builder = new AnimatorSetBuilder();
+ // Fade in prediction icons quickly, then rest of all apps after reaching overview.
+ float progressToReachOverview = NORMAL.getVerticalProgress(mLauncher)
+ - OVERVIEW.getVerticalProgress(mLauncher);
+ builder.setInterpolator(ANIM_ALL_APPS_HEADER_FADE, Interpolators.clampToProgress(ACCEL,
+ 0, ALL_APPS_CONTENT_FADE_THRESHOLD));
+ builder.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.clampToProgress(LINEAR,
+ progressToReachOverview, 1));
// Get workspace out of the way quickly, to prepare for potential pause.
builder.setInterpolator(ANIM_WORKSPACE_SCALE, DEACCEL_3);
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/OverviewToAllAppsTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/OverviewToAllAppsTouchController.java
index 73f328b..9091168 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/OverviewToAllAppsTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/OverviewToAllAppsTouchController.java
@@ -75,7 +75,7 @@
}
@Override
- protected int getLogContainerTypeForNormalState() {
+ protected int getLogContainerTypeForNormalState(MotionEvent ev) {
return LauncherLogProto.ContainerType.WORKSPACE;
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
index 18b8af4..eb571f6 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
@@ -154,7 +154,7 @@
}
@Override
- protected int getLogContainerTypeForNormalState() {
+ protected int getLogContainerTypeForNormalState(MotionEvent ev) {
return LauncherLogProto.ContainerType.NAVBAR;
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
index 5e77e0a..5ebefa3 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
@@ -81,6 +81,7 @@
});
factory.onRemoteAnimationReceived(null);
factory.createActivityController(RECENTS_LAUNCH_DURATION);
+ factory.setRecentsAttachedToAppWindow(true, false);
mActivity = activity;
mRecentsView = mActivity.getOverviewPanel();
return false;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
index e3d622f..d627a7f 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
@@ -411,15 +411,27 @@
// FolderIconView can be seen morphing into the icon shape.
final float windowAlphaThreshold = isFloatingIconView ? 1f - SHAPE_PROGRESS_DURATION : 1f;
anim.addOnUpdateListener(new RectFSpringAnim.OnUpdateListener() {
+
+ // Alpha interpolates between [1, 0] between progress values [start, end]
+ final float start = 0f;
+ final float end = 0.85f;
+
+ private float getWindowAlpha(float progress) {
+ if (progress <= start) {
+ return 1f;
+ }
+ if (progress >= end) {
+ return 0f;
+ }
+ return Utilities.mapToRange(progress, start, end, 1, 0, ACCEL_1_5);
+ }
+
@Override
public void onUpdate(RectF currentRect, float progress) {
homeAnim.setPlayFraction(progress);
- float alphaProgress = ACCEL_1_5.getInterpolation(progress);
- float windowAlpha = Utilities.boundToRange(Utilities.mapToRange(alphaProgress, 0,
- windowAlphaThreshold, 1.5f, 0f, Interpolators.LINEAR), 0, 1);
mTransformParams.setProgress(progress)
- .setCurrentRectAndTargetAlpha(currentRect, windowAlpha);
+ .setCurrentRectAndTargetAlpha(currentRect, getWindowAlpha(progress));
if (isFloatingIconView) {
mTransformParams.setCornerRadius(endRadius * progress + startRadius
* (1f - progress));
@@ -429,7 +441,8 @@
if (isFloatingIconView) {
((FloatingIconView) floatingView).update(currentRect, 1f, progress,
- windowAlphaThreshold, mClipAnimationHelper.getCurrentCornerRadius(), false);
+ windowAlphaThreshold, mClipAnimationHelper.getCurrentCornerRadius(),
+ false);
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewCommandHelper.java
index 6533c63..a94f25d 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewCommandHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewCommandHelper.java
@@ -99,6 +99,7 @@
@Override
protected void onTransitionComplete() {
+ // TODO(b/138729100) This doesn't execute first time launcher is run
if (mTriggeredFromAltTab) {
RecentsView rv = (RecentsView) mHelper.getVisibleRecentsView();
if (rv == null) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java
index ca89c33..e51ba63 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java
@@ -188,9 +188,9 @@
return true;
}
- public void setCancelWithDeferredScreenshot(boolean deferredWithScreenshot) {
+ public void setDeferCancelUntilNextTransition(boolean defer, boolean screenshot) {
if (targetSet != null) {
- targetSet.controller.setCancelWithDeferredScreenshot(deferredWithScreenshot);
+ targetSet.controller.setDeferCancelUntilNextTransition(defer, screenshot);
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java
index b90f6c2..17457aa 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java
@@ -16,6 +16,8 @@
package com.android.quickstep;
+import static com.android.launcher3.util.MainThreadInitializedObject.forOverride;
+
import android.graphics.Matrix;
import android.view.View;
@@ -47,8 +49,7 @@
};
public static final MainThreadInitializedObject<TaskOverlayFactory> INSTANCE =
- new MainThreadInitializedObject<>(c -> Overrides.getObject(TaskOverlayFactory.class,
- c, R.string.task_overlay_factory_class));
+ forOverride(TaskOverlayFactory.class, R.string.task_overlay_factory_class);
public List<TaskSystemShortcut> getEnabledShortcuts(TaskView taskView) {
final ArrayList<TaskSystemShortcut> shortcuts = new ArrayList<>();
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java
index 213c5d3..fd45923 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java
@@ -207,8 +207,7 @@
}
};
WindowManagerWrapper.getInstance().overridePendingAppTransitionMultiThumbFuture(
- future, animStartedListener, mHandler, true /* scaleUp */,
- v.getDisplay().getDisplayId());
+ future, animStartedListener, mHandler, true /* scaleUp */, displayId);
}
});
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
index d7ed15c..86ba855 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
@@ -31,6 +31,7 @@
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_ASSISTANT;
@@ -68,6 +69,7 @@
import androidx.annotation.BinderThread;
import androidx.annotation.UiThread;
+import androidx.annotation.WorkerThread;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.MainThreadExecutor;
@@ -145,6 +147,11 @@
private static final String TAG = "TouchInteractionService";
+ private static final String KEY_BACK_NOTIFICATION_COUNT = "backNotificationCount";
+ private static final String NOTIFY_ACTION_BACK = "com.android.quickstep.action.BACK_GESTURE";
+ private static final int MAX_BACK_NOTIFICATION_COUNT = 3;
+ private int mBackGestureNotificationCounter = -1;
+
private final IBinder mMyBinder = new IOverviewProxy.Stub() {
public void onActiveNavBarRegionChanges(Region region) {
@@ -205,6 +212,10 @@
mOverviewComponentObserver.getActivityControlHelper();
UserEventDispatcher.newInstance(getBaseContext()).logActionBack(completed, downX, downY,
isButton, gestureSwipeLeft, activityControl.getContainerType());
+
+ if (completed && !isButton && shouldNotifyBackGesture()) {
+ BACKGROUND_EXECUTOR.execute(TouchInteractionService.this::tryNotifyBackGesture);
+ }
}
public void onSystemUiStateChanged(int stateFlags) {
@@ -335,6 +346,9 @@
if (mInputEventReceiver != null) {
mInputEventReceiver.dispose();
mInputEventReceiver = null;
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "disposeEventHandlers");
+ }
}
if (mInputMonitorCompat != null) {
mInputMonitorCompat.dispose();
@@ -476,6 +490,8 @@
// Temporarily disable model preload
// new ModelPreload().start(this);
+ mBackGestureNotificationCounter = Math.max(0, Utilities.getDevicePrefs(this)
+ .getInt(KEY_BACK_NOTIFICATION_COUNT, MAX_BACK_NOTIFICATION_COUNT));
Utilities.unregisterReceiverSafely(this, mUserUnlockedReceiver);
}
@@ -566,6 +582,7 @@
private boolean validSystemUiFlags() {
return (mSystemUiStateFlags & SYSUI_STATE_NAV_BAR_HIDDEN) == 0
&& (mSystemUiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) == 0
+ && (mSystemUiStateFlags & SYSUI_STATE_QUICK_SETTINGS_EXPANDED) == 0
&& ((mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED) == 0
|| (mSystemUiStateFlags & SYSUI_STATE_OVERVIEW_DISABLED) == 0);
}
@@ -640,10 +657,12 @@
// In the case where we are in the excluded assistant state, ignore it and treat the
// running activity as the task behind the assistant
runningTaskInfo = mAM.getRunningTask(ACTIVITY_TYPE_ASSISTANT);
- final ComponentName homeComponent =
+ if (!ActivityManagerWrapper.isHomeTask(runningTaskInfo)) {
+ final ComponentName homeComponent =
mOverviewComponentObserver.getHomeIntent().getComponent();
- forceOverviewInputConsumer =
+ forceOverviewInputConsumer =
runningTaskInfo.baseIntent.getComponent().equals(homeComponent);
+ }
}
if (runningTaskInfo == null && !sSwipeSharedState.goingToLauncher
@@ -816,8 +835,9 @@
pw.println(" assistantAvailable=" + mAssistantAvailable);
pw.println(" assistantDisabled="
+ QuickStepContract.isAssistantGestureDisabled(mSystemUiStateFlags));
- pw.println(" resumed="
- + mOverviewComponentObserver.getActivityControlHelper().isResumed());
+ boolean resumed = mOverviewComponentObserver != null
+ && mOverviewComponentObserver.getActivityControlHelper().isResumed();
+ pw.println(" resumed=" + resumed);
pw.println(" useSharedState=" + mConsumer.useSharedSwipeState());
if (mConsumer.useSharedSwipeState()) {
sSwipeSharedState.dump(" ", pw);
@@ -860,6 +880,22 @@
mRecentsModel, mInputConsumer, isLikelyToStartNewTask, continuingLastGesture);
}
+ protected boolean shouldNotifyBackGesture() {
+ return mBackGestureNotificationCounter > 0 &&
+ mGestureBlockingActivity != null;
+ }
+
+ @WorkerThread
+ protected void tryNotifyBackGesture() {
+ if (shouldNotifyBackGesture()) {
+ mBackGestureNotificationCounter--;
+ Utilities.getDevicePrefs(this).edit()
+ .putInt(KEY_BACK_NOTIFICATION_COUNT, mBackGestureNotificationCounter).apply();
+ sendBroadcast(new Intent(NOTIFY_ACTION_BACK).setPackage(
+ mGestureBlockingActivity.getPackageName()));
+ }
+ }
+
public static void startRecentsActivityAsync(Intent intent, RecentsAnimationListener listener) {
BACKGROUND_EXECUTOR.execute(() -> ActivityManagerWrapper.getInstance()
.startRecentsActivity(intent, null, listener, null, null));
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
index 363e4cc..0d29e5d 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -736,18 +736,19 @@
: LAST_TASK;
}
} else {
- if (mMode == Mode.NO_BUTTON && endVelocity < 0 && !mIsShelfPeeking) {
+ // If swiping at a diagonal, base end target on the faster velocity.
+ boolean isSwipeUp = endVelocity < 0;
+ boolean willGoToNewTaskOnSwipeUp =
+ goingToNewTask && Math.abs(velocity.x) > Math.abs(endVelocity);
+
+ if (mMode == Mode.NO_BUTTON && isSwipeUp && !willGoToNewTaskOnSwipeUp) {
+ endTarget = HOME;
+ } else if (mMode == Mode.NO_BUTTON && isSwipeUp && !mIsShelfPeeking) {
// If swiping at a diagonal, base end target on the faster velocity.
- endTarget = goingToNewTask && Math.abs(velocity.x) > Math.abs(endVelocity)
- ? NEW_TASK : HOME;
- } else if (endVelocity < 0) {
- if (reachedOverviewThreshold) {
- endTarget = RECENTS;
- } else {
- // If swiping at a diagonal, base end target on the faster velocity.
- endTarget = goingToNewTask && Math.abs(velocity.x) > Math.abs(endVelocity)
- ? NEW_TASK : RECENTS;
- }
+ endTarget = NEW_TASK;
+ } else if (isSwipeUp) {
+ endTarget = !reachedOverviewThreshold && willGoToNewTaskOnSwipeUp
+ ? NEW_TASK : RECENTS;
} else {
endTarget = goingToNewTask ? NEW_TASK : LAST_TASK;
}
@@ -943,17 +944,16 @@
}
if (start == end || duration <= 0) {
mLauncherTransitionController.dispatchSetInterpolator(t -> end);
- mLauncherTransitionController.getAnimationPlayer().end();
} else {
mLauncherTransitionController.dispatchSetInterpolator(adjustedInterpolator);
mAnimationFactory.adjustActivityControllerInterpolators();
- mLauncherTransitionController.getAnimationPlayer().setDuration(duration);
-
- if (QUICKSTEP_SPRINGS.get()) {
- mLauncherTransitionController.dispatchOnStartWithVelocity(end, velocityPxPerMs.y);
- }
- mLauncherTransitionController.getAnimationPlayer().start();
}
+ mLauncherTransitionController.getAnimationPlayer().setDuration(Math.max(0, duration));
+
+ if (QUICKSTEP_SPRINGS.get()) {
+ mLauncherTransitionController.dispatchOnStartWithVelocity(end, velocityPxPerMs.y);
+ }
+ mLauncherTransitionController.getAnimationPlayer().start();
mHasLauncherTransitionControllerStarted = true;
}
@@ -1186,7 +1186,8 @@
private void setupLauncherUiAfterSwipeUpToRecentsAnimation() {
endLauncherTransitionController();
mActivityControlHelper.onSwipeUpToRecentsComplete(mActivity);
- mRecentsAnimationWrapper.setCancelWithDeferredScreenshot(true);
+ mRecentsAnimationWrapper.setDeferCancelUntilNextTransition(true /* defer */,
+ true /* screenshot */);
mRecentsView.onSwipeUpAnimationSuccess();
RecentsModel.INSTANCE.get(mContext).onOverviewShown(false, TAG);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java
index 631c34c..6ec1da0 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java
@@ -50,6 +50,7 @@
import com.android.quickstep.util.ObjectWrapper;
import com.android.quickstep.util.RectFSpringAnim;
import com.android.quickstep.util.SwipeAnimationTargetSet;
+import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -335,7 +336,8 @@
ThumbnailData thumbnail =
mRecentsAnimationWrapper.targetSet.controller.screenshotTask(mRunningTaskId);
- mRecentsAnimationWrapper.setCancelWithDeferredScreenshot(true);
+ mRecentsAnimationWrapper.setDeferCancelUntilNextTransition(true /* defer */,
+ false /* screenshot */);
ActivityOptions options = ActivityOptions.makeCustomAnimation(mContext, 0, 0);
ActivityOptionsCompat.setFreezeRecentTasksList(options);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java
index 83601e6..14083dd 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java
@@ -23,6 +23,7 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.util.Preconditions;
import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener;
+import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
import com.android.systemui.shared.system.RecentsAnimationListener;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
@@ -39,7 +40,7 @@
public class RecentsAnimationListenerSet implements RecentsAnimationListener {
// The actual app surface is replaced by a screenshot upon recents animation cancelation when
- // deferredWithScreenshot is true. Launcher takes the responsibility to clean up this screenshot
+ // the thumbnailData exists. Launcher takes the responsibility to clean up this screenshot
// after app transition is finished. This delay is introduced to cover the app transition
// period of time.
private final int TRANSITION_DELAY = 100;
@@ -90,14 +91,14 @@
}
@Override
- public final void onAnimationCanceled(boolean deferredWithScreenshot) {
+ public final void onAnimationCanceled(ThumbnailData thumbnailData) {
Utilities.postAsyncCallback(MAIN_THREAD_EXECUTOR.getHandler(), () -> {
for (SwipeAnimationListener listener : getListeners()) {
listener.onRecentsAnimationCanceled();
}
});
// TODO: handle the transition better instead of simply using a transition delay.
- if (deferredWithScreenshot) {
+ if (thumbnailData != null) {
MAIN_THREAD_EXECUTOR.getHandler().postDelayed(() -> mController.cleanupScreenshot(),
TRANSITION_DELAY);
}
@@ -109,6 +110,6 @@
public void cancelListener() {
mCancelled = true;
- onAnimationCanceled(false);
+ onAnimationCanceled(null);
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
index 1705c97..1069bed 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
@@ -15,6 +15,11 @@
*/
package com.android.quickstep.util;
+import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
+import static com.android.launcher3.LauncherState.BACKGROUND_APP;
+import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.anim.Interpolators.LINEAR;
+
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.AnimatorListenerAdapter;
@@ -35,15 +40,11 @@
import com.android.launcher3.anim.AnimatorSetBuilder;
import com.android.launcher3.anim.PropertySetter;
import com.android.launcher3.anim.SpringObjectAnimator;
+import com.android.launcher3.graphics.OverviewScrim;
import java.util.ArrayList;
import java.util.List;
-import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
-import static com.android.launcher3.LauncherState.BACKGROUND_APP;
-import static com.android.launcher3.LauncherState.NORMAL;
-import static com.android.launcher3.anim.Interpolators.LINEAR;
-
/**
* Creates an animation where all the workspace items are moved into their final location,
* staggered row by row from the bottom up.
@@ -122,8 +123,8 @@
addStaggeredAnimationForView(qsb, grid.inv.numRows + 2, totalRows);
}
- addWorkspaceScrimAnimationForState(launcher, BACKGROUND_APP, 0);
- addWorkspaceScrimAnimationForState(launcher, NORMAL, ALPHA_DURATION_MS);
+ addScrimAnimationForState(launcher, BACKGROUND_APP, 0);
+ addScrimAnimationForState(launcher, NORMAL, ALPHA_DURATION_MS);
AnimatorListener resetClipListener = new AnimatorListenerAdapter() {
int numAnimations = mAnimators.size();
@@ -191,13 +192,17 @@
mAnimators.add(alpha);
}
- private void addWorkspaceScrimAnimationForState(Launcher launcher, LauncherState state,
- long duration) {
+ private void addScrimAnimationForState(Launcher launcher, LauncherState state, long duration) {
AnimatorSetBuilder scrimAnimBuilder = new AnimatorSetBuilder();
AnimationConfig scrimAnimConfig = new AnimationConfig();
scrimAnimConfig.duration = duration;
PropertySetter scrimPropertySetter = scrimAnimConfig.getPropertySetter(scrimAnimBuilder);
launcher.getWorkspace().getStateTransitionAnimation().setScrim(scrimPropertySetter, state);
mAnimators.add(scrimAnimBuilder.build());
+ Animator fadeOverviewScrim = ObjectAnimator.ofFloat(
+ launcher.getDragLayer().getOverviewScrim(), OverviewScrim.SCRIM_PROGRESS,
+ state.getOverviewScrimAlpha(launcher));
+ fadeOverviewScrim.setDuration(duration);
+ mAnimators.add(fadeOverviewScrim);
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
index 9b157d1..1bf77f5 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
@@ -97,6 +97,7 @@
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
+import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.OverScroller;
import com.android.launcher3.util.PendingAnimation;
import com.android.launcher3.util.Themes;
@@ -1051,9 +1052,10 @@
if (task != null) {
ActivityManagerWrapper.getInstance().removeTask(task.key.id);
if (shouldLog) {
+ ComponentKey componentKey = TaskUtils.getLaunchComponentKeyForTask(task.key);
mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
- onEndListener.logAction, Direction.UP, index,
- TaskUtils.getLaunchComponentKeyForTask(task.key));
+ onEndListener.logAction, Direction.UP, index, componentKey);
+ mActivity.getStatsLogManager().logTaskDismiss(this, componentKey);
}
}
}
diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
index fc8d02a..991408c 100644
--- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
@@ -32,6 +32,7 @@
import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
import static com.android.quickstep.TaskUtils.taskIsATargetWithMode;
import static com.android.systemui.shared.system.QuickStepContract.getWindowCornerRadius;
+import static com.android.systemui.shared.system.QuickStepContract.supportsRoundedCornersOnWindows;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
@@ -495,6 +496,8 @@
endCrop = windowTargetBounds.height();
}
+ final float initialWindowRadius = supportsRoundedCornersOnWindows(mLauncher.getResources())
+ ? startCrop / 2f : 0f;
final float windowRadius = mDeviceProfile.isMultiWindowMode
? 0 : getWindowCornerRadius(mLauncher.getResources());
appAnimator.addUpdateListener(new MultiValueUpdateListener() {
@@ -506,7 +509,7 @@
alphaDuration, LINEAR);
FloatProp mCroppedSize = new FloatProp(startCrop, endCrop, 0, CROP_DURATION,
EXAGGERATED_EASE);
- FloatProp mWindowRadius = new FloatProp(startCrop / 2f, windowRadius, 0,
+ FloatProp mWindowRadius = new FloatProp(initialWindowRadius, windowRadius, 0,
RADIUS_DURATION, EXAGGERATED_EASE);
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
index f0204b9..174e49b 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
@@ -19,16 +19,20 @@
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_FADE;
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_SCALE;
+import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_SCRIM_FADE;
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_TRANSLATE_X;
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_TRANSLATE_Y;
import static com.android.launcher3.anim.AnimatorSetBuilder.FLAG_DONT_ANIMATE_OVERVIEW;
import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE_IN_OUT;
import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.graphics.Scrim.SCRIM_PROGRESS;
import android.util.FloatProperty;
import android.view.View;
import android.view.animation.Interpolator;
+import androidx.annotation.NonNull;
+
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.LauncherState.ScaleAndTranslation;
@@ -36,8 +40,7 @@
import com.android.launcher3.LauncherStateManager.StateHandler;
import com.android.launcher3.anim.AnimatorSetBuilder;
import com.android.launcher3.anim.PropertySetter;
-
-import androidx.annotation.NonNull;
+import com.android.launcher3.graphics.OverviewScrim;
/**
* State handler for recents view. Manages UI changes and animations for recents view based off the
@@ -67,6 +70,8 @@
mRecentsView.setTranslationX(translationX);
mRecentsView.setTranslationY(scaleAndTranslation.translationY);
getContentAlphaProperty().set(mRecentsView, state.overviewUi ? 1f : 0);
+ OverviewScrim scrim = mLauncher.getDragLayer().getOverviewScrim();
+ SCRIM_PROGRESS.set(scrim, state.getOverviewScrimAlpha(mLauncher));
}
@Override
@@ -110,6 +115,9 @@
translateYInterpolator);
setter.setFloat(mRecentsView, getContentAlphaProperty(), toState.overviewUi ? 1 : 0,
builder.getInterpolator(ANIM_OVERVIEW_FADE, AGGRESSIVE_EASE_IN_OUT));
+ OverviewScrim scrim = mLauncher.getDragLayer().getOverviewScrim();
+ setter.setFloat(scrim, SCRIM_PROGRESS, toState.getOverviewScrimAlpha(mLauncher),
+ builder.getInterpolator(ANIM_OVERVIEW_SCRIM_FADE, LINEAR));
}
/**
diff --git a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
index 97cd38a..c02df93 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
@@ -32,9 +32,11 @@
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.app.Activity;
+import android.app.Person;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
+import android.content.pm.ShortcutInfo;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.util.Base64;
@@ -244,4 +246,9 @@
}
return new ScaleAndTranslation(1.1f, 0f, 0f);
}
+
+ public static Person[] getPersons(ShortcutInfo si) {
+ Person[] persons = si.getPersons();
+ return persons == null ? Utilities.EMPTY_PERSON_ARRAY : persons;
+ }
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/LandscapeEdgeSwipeController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/LandscapeEdgeSwipeController.java
index 0605953..bb72315 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/LandscapeEdgeSwipeController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/LandscapeEdgeSwipeController.java
@@ -46,7 +46,7 @@
}
@Override
- protected int getLogContainerTypeForNormalState() {
+ protected int getLogContainerTypeForNormalState(MotionEvent ev) {
return LauncherLogProto.ContainerType.NAVBAR;
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
index 109d751..b81edfa 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
@@ -62,7 +62,7 @@
/**
* The progress at which all apps content will be fully visible when swiping up from overview.
*/
- private static final float ALL_APPS_CONTENT_FADE_THRESHOLD = 0.08f;
+ protected static final float ALL_APPS_CONTENT_FADE_THRESHOLD = 0.08f;
/**
* The progress at which recents will begin fading out when swiping up from overview.
@@ -147,8 +147,8 @@
}
@Override
- protected int getLogContainerTypeForNormalState() {
- return ContainerType.HOTSEAT;
+ protected int getLogContainerTypeForNormalState(MotionEvent ev) {
+ return isTouchOverHotseat(mLauncher, ev) ? ContainerType.HOTSEAT : ContainerType.WORKSPACE;
}
private AnimatorSetBuilder getNormalToOverviewAnimation() {
diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java
index 9f12484..dfab434 100644
--- a/quickstep/src/com/android/quickstep/RecentsModel.java
+++ b/quickstep/src/com/android/quickstep/RecentsModel.java
@@ -16,15 +16,12 @@
package com.android.quickstep;
import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId;
-import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SUPPORTS_WINDOW_CORNERS;
-import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_WINDOW_CORNER_RADIUS;
import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.content.ComponentCallbacks2;
import android.content.Context;
import android.os.Build;
-import android.os.Bundle;
import android.os.HandlerThread;
import android.os.Process;
import android.os.RemoteException;
@@ -35,7 +32,6 @@
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.TaskStackChangeListener;
import java.util.ArrayList;
@@ -52,7 +48,7 @@
// We do not need any synchronization for this variable as its only written on UI thread.
public static final MainThreadInitializedObject<RecentsModel> INSTANCE =
- new MainThreadInitializedObject<>(c -> new RecentsModel(c));
+ new MainThreadInitializedObject<>(RecentsModel::new);
private final List<TaskThumbnailChangeListener> mThumbnailChangeListeners = new ArrayList<>();
private final Context mContext;
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
index 2f411ef..13a8dc2 100644
--- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -25,6 +25,7 @@
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.DISMISS_TASK;
import static android.stats.launcher.nano.Launcher.BACKGROUND;
import static android.stats.launcher.nano.Launcher.OVERVIEW;
@@ -74,6 +75,16 @@
MessageNano.toByteArray(ext), true);
}
+ @Override
+ public void logTaskDismiss(View v, ComponentKey componentKey) {
+ LauncherExtension ext = new LauncherExtension();
+ ext.srcTarget = new LauncherTarget[SUPPORTED_TARGET_DEPTH];
+ int srcState = OVERVIEW;
+ fillInLauncherExtension(v, ext);
+ StatsLogCompat.write(DISMISS_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) {
diff --git a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
index 5a2f5c1..3747f9a 100644
--- a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
+++ b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
@@ -98,7 +98,7 @@
public ShelfScrimView(Context context, AttributeSet attrs) {
super(context, attrs);
- mMaxScrimAlpha = Math.round(OVERVIEW.getWorkspaceScrimAlpha(mLauncher) * 255);
+ mMaxScrimAlpha = Math.round(OVERVIEW.getOverviewScrimAlpha(mLauncher) * 255);
mEndAlpha = Color.alpha(mEndScrim);
mRadius = BOTTOM_CORNER_RADIUS_RATIO * Themes.getDialogCornerRadius(context);
diff --git a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
index 28a9707..f27f400 100644
--- a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
+++ b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
@@ -27,6 +27,7 @@
import static com.android.systemui.shared.system.QuickStepContract.NAV_BAR_MODE_GESTURAL_OVERLAY;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.util.Log;
import androidx.test.uiautomator.UiDevice;
@@ -106,35 +107,51 @@
Log.e(TAG, "Exception", e);
throw e;
} finally {
- setActiveOverlay(prevOverlayPkg, originalMode);
+ Assert.assertTrue(setActiveOverlay(prevOverlayPkg, originalMode));
}
mLauncher.disableDebugTracing();
}
- public void evaluateWithoutChangingSetting(Statement base) throws Throwable {
- base.evaluate();
- }
-
private void evaluateWithThreeButtons() throws Throwable {
- setActiveOverlay(NAV_BAR_MODE_3BUTTON_OVERLAY,
- LauncherInstrumentation.NavigationModel.THREE_BUTTON);
- evaluateWithoutChangingSetting(base);
+ if (setActiveOverlay(NAV_BAR_MODE_3BUTTON_OVERLAY,
+ LauncherInstrumentation.NavigationModel.THREE_BUTTON)) {
+ base.evaluate();
+ }
}
private void evaluateWithTwoButtons() throws Throwable {
- setActiveOverlay(NAV_BAR_MODE_2BUTTON_OVERLAY,
- LauncherInstrumentation.NavigationModel.TWO_BUTTON);
- base.evaluate();
+ if (setActiveOverlay(NAV_BAR_MODE_2BUTTON_OVERLAY,
+ LauncherInstrumentation.NavigationModel.TWO_BUTTON)) {
+ base.evaluate();
+ }
}
private void evaluateWithZeroButtons() throws Throwable {
- setActiveOverlay(NAV_BAR_MODE_GESTURAL_OVERLAY,
- LauncherInstrumentation.NavigationModel.ZERO_BUTTON);
- base.evaluate();
+ if (setActiveOverlay(NAV_BAR_MODE_GESTURAL_OVERLAY,
+ LauncherInstrumentation.NavigationModel.ZERO_BUTTON)) {
+ base.evaluate();
+ }
}
- private void setActiveOverlay(String overlayPackage,
+ private boolean packageExists(String packageName) {
+ try {
+ PackageManager pm = getInstrumentation().getContext().getPackageManager();
+ if (pm.getApplicationInfo(packageName, 0 /* flags */) == null) {
+ return false;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ }
+ return true;
+ }
+
+ private boolean setActiveOverlay(String overlayPackage,
LauncherInstrumentation.NavigationModel expectedMode) throws Exception {
+ if (!packageExists(overlayPackage)) {
+ Log.d(TAG, "setActiveOverlay: " + overlayPackage + " pkg does not exist");
+ return false;
+ }
+
setOverlayPackageEnabled(NAV_BAR_MODE_3BUTTON_OVERLAY,
overlayPackage == NAV_BAR_MODE_3BUTTON_OVERLAY);
setOverlayPackageEnabled(NAV_BAR_MODE_2BUTTON_OVERLAY,
@@ -178,6 +195,7 @@
Assert.assertTrue("Switching nav mode: " + error, error == null);
Thread.sleep(5000);
+ return true;
}
private void setOverlayPackageEnabled(String overlayPackage, boolean enable)
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index b796140e..3b0432e 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -88,7 +88,7 @@
<string name="notification_dots_title" msgid="9062440428204120317">"नई सूचनाएं बताने वाला गोल निशान"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"चालू"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"चालू"</string>
- <string name="title_missing_notification_access" msgid="7503287056163941064">"सूचना के एक्सेस की ज़रूरत है"</string>
+ <string name="title_missing_notification_access" msgid="7503287056163941064">"सूचना के ऐक्सेस की ज़रूरत है"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"सूचना बिंदु दिखाने के लिए, <xliff:g id="NAME">%1$s</xliff:g> के ऐप्लिकेशन सूचना चालू करें"</string>
<string name="title_change_settings" msgid="1376365968844349552">"सेटिंग बदलें"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"नई सूचनाएं बताने वाला गोल निशान दिखाएं"</string>
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index 672665e..c926bc1 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -89,7 +89,7 @@
<string name="notification_dots_desc_on" msgid="1679848116452218908">"ஆன்"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"ஆஃப்"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"அறிவிப்பிற்கான அணுகல் தேவை"</string>
- <string name="msg_missing_notification_access" msgid="281113995110910548">"அறிவிப்புப் புள்ளிகளைக் காட்ட, <xliff:g id="NAME">%1$s</xliff:g> இன் பயன்பாட்டு அறிவிப்புகளை இயக்கவும்"</string>
+ <string name="msg_missing_notification_access" msgid="281113995110910548">"அறிவிப்புப் புள்ளிகளைக் காட்ட, <xliff:g id="NAME">%1$s</xliff:g> இன் ஆப்ஸ் அறிவிப்புகளை இயக்கவும்"</string>
<string name="title_change_settings" msgid="1376365968844349552">"அமைப்புகளை மாற்று"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"அறிவிப்புப் புள்ளிகளைக் காட்டு"</string>
<string name="auto_add_shortcuts_label" msgid="8222286205987725611">"முகப்புத் திரையில் ஐகானைச் சேர்"</string>
diff --git a/res/values/config.xml b/res/values/config.xml
index 638a411..0387184 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -72,6 +72,7 @@
<string name="system_shortcut_factory_class" translatable="false"></string>
<string name="app_launch_tracker_class" translatable="false"></string>
<string name="test_information_handler_class" translatable="false"></string>
+ <string name="launcher_activity_logic_class" translatable="false"></string>
<!-- Package name of the default wallpaper picker. -->
<string name="wallpaper_picker_package" translatable="false"></string>
diff --git a/src/com/android/launcher3/AppWidgetsRestoredReceiver.java b/src/com/android/launcher3/AppWidgetsRestoredReceiver.java
index d949141..e3ef5d6 100644
--- a/src/com/android/launcher3/AppWidgetsRestoredReceiver.java
+++ b/src/com/android/launcher3/AppWidgetsRestoredReceiver.java
@@ -11,6 +11,7 @@
import android.util.Log;
import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.model.LoaderTask;
import com.android.launcher3.provider.RestoreDbTask;
@@ -18,6 +19,8 @@
import androidx.annotation.WorkerThread;
+import static android.os.Process.myUserHandle;
+
public class AppWidgetsRestoredReceiver extends BroadcastReceiver {
private static final String TAG = "AWRestoredReceiver";
@@ -77,9 +80,14 @@
state = LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY;
}
- String[] widgetIdParams = new String[] { Integer.toString(oldWidgetIds[i]) };
+ // b/135926478: Work profile widget restore is broken in platform. This forces us to
+ // recreate the widget during loading with the correct host provider.
+ long mainProfileId = UserManagerCompat.getInstance(context)
+ .getSerialNumberForUser(myUserHandle());
+ String oldWidgetId = Integer.toString(oldWidgetIds[i]);
int result = new ContentWriter(context, new ContentWriter.CommitParams(
- "appWidgetId=? and (restored & 1) = 1", widgetIdParams))
+ "appWidgetId=? and (restored & 1) = 1 and profileId=?",
+ new String[] { oldWidgetId, Long.toString(mainProfileId) }))
.put(LauncherSettings.Favorites.APPWIDGET_ID, newWidgetIds[i])
.put(LauncherSettings.Favorites.RESTORED, state)
.commit();
@@ -87,7 +95,7 @@
if (result == 0) {
Cursor cursor = cr.query(Favorites.CONTENT_URI,
new String[] {Favorites.APPWIDGET_ID},
- "appWidgetId=?", widgetIdParams, null);
+ "appWidgetId=?", new String[] { oldWidgetId }, null);
try {
if (!cursor.moveToFirst()) {
// The widget no long exists.
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index 5055309..f0b3afd 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -170,7 +170,7 @@
getUserEventDispatcher().logAppLaunch(v, intent);
getStatsLogManager().logAppLaunch(v, intent);
return true;
- } catch (ActivityNotFoundException|SecurityException e) {
+ } catch (NullPointerException|ActivityNotFoundException|SecurityException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e);
}
diff --git a/src/com/android/launcher3/IconProvider.java b/src/com/android/launcher3/IconProvider.java
index e1ef954..0f006f7 100644
--- a/src/com/android/launcher3/IconProvider.java
+++ b/src/com/android/launcher3/IconProvider.java
@@ -1,16 +1,17 @@
package com.android.launcher3;
-import android.content.Context;
+import static com.android.launcher3.util.MainThreadInitializedObject.forOverride;
+
import android.content.pm.LauncherActivityInfo;
import android.graphics.drawable.Drawable;
+import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.ResourceBasedOverride;
public class IconProvider implements ResourceBasedOverride {
- public static IconProvider newInstance(Context context) {
- return Overrides.getObject(IconProvider.class, context, R.string.icon_provider_class);
- }
+ public static MainThreadInitializedObject<IconProvider> INSTANCE =
+ forOverride(IconProvider.class, R.string.icon_provider_class);
public IconProvider() { }
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 03fdc97..d79230f 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -127,6 +127,7 @@
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.PendingRequestArgs;
import com.android.launcher3.util.RaceConditionTracker;
+import com.android.launcher3.util.ShortcutUtil;
import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.Thunk;
@@ -873,9 +874,7 @@
if (mLauncherCallbacks != null) {
mLauncherCallbacks.onStop();
}
-
- getUserEventDispatcher().logActionCommand(Action.Command.STOP,
- mStateManager.getState().containerType, -1);
+ logStopAndResume(Action.Command.STOP);
mAppWidgetHost.setListenIfResumed(false);
@@ -901,8 +900,7 @@
private void handleDeferredResume() {
if (hasBeenResumed() && !mStateManager.getState().disableInteraction) {
- getUserEventDispatcher().logActionCommand(Action.Command.RESUME,
- mStateManager.getState().containerType, -1);
+ logStopAndResume(Action.Command.RESUME);
getUserEventDispatcher().startSession();
UiFactory.onLauncherStateOrResumeChanged(this);
@@ -929,6 +927,17 @@
}
}
+ private void logStopAndResume(int command) {
+ int containerType = mStateManager.getState().containerType;
+ if (containerType == ContainerType.WORKSPACE && mWorkspace != null) {
+ getUserEventDispatcher().logActionCommand(command,
+ containerType, -1, mWorkspace.isOverlayShown() ? -1 : 0);
+ } else {
+ getUserEventDispatcher().logActionCommand(command, containerType, -1);
+ }
+
+ }
+
protected void onStateSet(LauncherState state) {
getAppWidgetHost().setResumed(state == LauncherState.NORMAL);
if (mDeferredResumePending) {
@@ -1896,6 +1905,10 @@
if (mPendingExecutor != null) {
mPendingExecutor.markCompleted();
mPendingExecutor = null;
+
+ // We might have set this flag previously and forgot to clear it.
+ mAppsView.getAppsStore()
+ .disableDeferUpdatesSilently(AllAppsStore.DEFER_UPDATES_NEXT_DRAW);
}
}
@@ -2249,9 +2262,7 @@
@Override
public void executeOnNextDraw(ViewOnDrawExecutor executor) {
- if (mPendingExecutor != null) {
- mPendingExecutor.markCompleted();
- }
+ clearPendingBinds();
mPendingExecutor = executor;
if (!isInState(ALL_APPS)) {
mAppsView.getAppsStore().enableDeferUpdates(AllAppsStore.DEFER_UPDATES_NEXT_DRAW);
@@ -2492,7 +2503,7 @@
KeyEvent.KEYCODE_O, KeyEvent.META_CTRL_ON));
}
if (currentFocus.getTag() instanceof ItemInfo
- && DeepShortcutManager.supportsShortcuts((ItemInfo) currentFocus.getTag())) {
+ && ShortcutUtil.supportsShortcuts((ItemInfo) currentFocus.getTag())) {
shortcutInfos.add(new KeyboardShortcutInfo(
getString(R.string.shortcuts_menu_with_notifications_description),
KeyEvent.KEYCODE_S, KeyEvent.META_CTRL_ON));
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index d07638a..2a801d6 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -19,14 +19,12 @@
import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_ICON_PARAMS;
import static com.android.launcher3.util.SecureSettingsObserver.newNotificationSettingsObserver;
-import android.app.KeyguardManager;
import android.content.ComponentName;
import android.content.ContentProviderClient;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
-import android.os.Process;
import android.util.Log;
import com.android.launcher3.compat.LauncherAppsCompat;
@@ -46,7 +44,7 @@
// We do not need any synchronization for this variable as its only written on UI thread.
private static final MainThreadInitializedObject<LauncherAppState> INSTANCE =
- new MainThreadInitializedObject<>((c) -> new LauncherAppState(c));
+ new MainThreadInitializedObject<>(LauncherAppState::new);
private final Context mContext;
private final LauncherModel mModel;
diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java
index dcfd272..6e2626b 100644
--- a/src/com/android/launcher3/LauncherState.java
+++ b/src/com/android/launcher3/LauncherState.java
@@ -243,6 +243,10 @@
return 0;
}
+ public float getOverviewScrimAlpha(Launcher launcher) {
+ return 0;
+ }
+
public String getDescription(Launcher launcher) {
return launcher.getWorkspace().getCurrentPageDescription();
}
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index d2b8d4e..bbb3915 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -1562,12 +1562,20 @@
final boolean pagesFlipped = isPageOrderFlipped();
info.setScrollable(getPageCount() > 1);
if (getCurrentPage() < getPageCount() - 1) {
- info.addAction(pagesFlipped ? AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD
- : AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
+ info.addAction(pagesFlipped ?
+ AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD
+ : AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD);
+ info.addAction(mIsRtl ?
+ AccessibilityNodeInfo.AccessibilityAction.ACTION_PAGE_LEFT
+ : AccessibilityNodeInfo.AccessibilityAction.ACTION_PAGE_RIGHT);
}
if (getCurrentPage() > 0) {
- info.addAction(pagesFlipped ? AccessibilityNodeInfo.ACTION_SCROLL_FORWARD
- : AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
+ info.addAction(pagesFlipped ?
+ AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD
+ : AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD);
+ info.addAction(mIsRtl ?
+ AccessibilityNodeInfo.AccessibilityAction.ACTION_PAGE_RIGHT
+ : AccessibilityNodeInfo.AccessibilityAction.ACTION_PAGE_LEFT);
}
// Accessibility-wise, PagedView doesn't support long click, so disabling it.
@@ -1607,8 +1615,21 @@
if (pagesFlipped ? scrollRight() : scrollLeft()) {
return true;
}
+ } break;
+ case android.R.id.accessibilityActionPageRight: {
+ if (!mIsRtl) {
+ return scrollRight();
+ } else {
+ return scrollLeft();
+ }
}
- break;
+ case android.R.id.accessibilityActionPageLeft: {
+ if (!mIsRtl) {
+ return scrollLeft();
+ } else {
+ return scrollRight();
+ }
+ }
}
return false;
}
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index fc5cd8a..3bef598 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -21,6 +21,7 @@
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.app.ActivityManager;
+import android.app.Person;
import android.app.WallpaperManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -109,6 +110,9 @@
private static final Matrix sMatrix = new Matrix();
private static final Matrix sInverseMatrix = new Matrix();
+ public static final String[] EMPTY_STRING_ARRAY = new String[0];
+ public static final Person[] EMPTY_PERSON_ARRAY = new Person[0];
+
public static final boolean ATLEAST_Q = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q;
public static final boolean ATLEAST_P =
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 269a591..3be91d4 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -85,6 +85,7 @@
import com.android.launcher3.pageindicators.WorkspacePageIndicator;
import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider;
+import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.touch.WorkspaceTouchListener;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
@@ -420,6 +421,9 @@
}
// Always enter the spring loaded mode
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.NO_DRAG_TO_WORKSPACE, "Switching to SPRING_LOADED");
+ }
mLauncher.getStateManager().goToState(SPRING_LOADED);
}
@@ -1741,6 +1745,9 @@
public void prepareAccessibilityDrop() { }
public void onDrop(final DragObject d, DragOptions options) {
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.NO_DRAG_TO_WORKSPACE, "Workspace.onDrop");
+ }
mDragViewVisualCenter = d.getVisualCenter(mDragViewVisualCenter);
CellLayout dropTargetLayout = mDropToLayout;
@@ -2418,6 +2425,9 @@
* to add an item to one of the workspace screens.
*/
private void onDropExternal(final int[] touchXY, final CellLayout cellLayout, DragObject d) {
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.NO_DRAG_TO_WORKSPACE, "Workspace.onDropExternal");
+ }
if (d.dragInfo instanceof PendingAddShortcutInfo) {
WorkspaceItemInfo si = ((PendingAddShortcutInfo) d.dragInfo)
.activityInfo.createWorkspaceItemInfo();
@@ -3251,6 +3261,10 @@
}
}
+ public boolean isOverlayShown() {
+ return mOverlayShown;
+ }
+
void moveToDefaultScreen() {
int page = DEFAULT_PAGE;
if (!workspaceInModalState() && getNextPage() != page) {
diff --git a/src/com/android/launcher3/WorkspaceItemInfo.java b/src/com/android/launcher3/WorkspaceItemInfo.java
index 5a2373b..b72866c 100644
--- a/src/com/android/launcher3/WorkspaceItemInfo.java
+++ b/src/com/android/launcher3/WorkspaceItemInfo.java
@@ -16,17 +16,23 @@
package com.android.launcher3;
+import android.app.Person;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ShortcutInfo;
import android.text.TextUtils;
+import androidx.annotation.NonNull;
+
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.shortcuts.ShortcutKey;
+import com.android.launcher3.uioverrides.UiFactory;
import com.android.launcher3.util.ContentWriter;
+import java.util.Arrays;
+
/**
* Represents a launchable icon on the workspaces and in folders.
*/
@@ -83,10 +89,17 @@
public int status;
/**
+ * A set of person's Id associated with the WorkspaceItemInfo, this is only used if the item
+ * represents a deep shortcut.
+ */
+ @NonNull private String[] personKeys = Utilities.EMPTY_STRING_ARRAY;
+
+ /**
* The installation progress [0-100] of the package that this shortcut represents.
*/
private int mInstallProgress;
+
public WorkspaceItemInfo() {
itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
}
@@ -98,6 +111,7 @@
iconResource = info.iconResource;
status = info.status;
mInstallProgress = info.mInstallProgress;
+ personKeys = info.personKeys.clone();
}
/** TODO: Remove this. It's only called by ApplicationInfo.makeWorkspaceItem. */
@@ -175,6 +189,10 @@
runtimeStatusFlags |= FLAG_DISABLED_BY_PUBLISHER;
}
disabledMessage = shortcutInfo.getDisabledMessage();
+
+ Person[] persons = UiFactory.getPersons(shortcutInfo);
+ personKeys = persons.length == 0 ? Utilities.EMPTY_STRING_ARRAY
+ : Arrays.stream(persons).map(Person::getKey).sorted().toArray(String[]::new);
}
/** Returns the WorkspaceItemInfo id associated with the deep shortcut. */
@@ -183,6 +201,11 @@
getIntent().getStringExtra(ShortcutKey.EXTRA_SHORTCUT_ID) : null;
}
+ @NonNull
+ public String[] getPersonKeys() {
+ return personKeys;
+ }
+
@Override
public ComponentName getTargetComponent() {
ComponentName cn = super.getTargetComponent();
diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
index fd4df52..0c1303b 100644
--- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
@@ -40,6 +40,7 @@
import com.android.launcher3.shortcuts.DeepShortcutManager;
import com.android.launcher3.touch.ItemLongClickListener;
import com.android.launcher3.util.IntArray;
+import com.android.launcher3.util.ShortcutUtil;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.widget.LauncherAppWidgetHostView;
@@ -115,7 +116,7 @@
// If the request came from keyboard, do not add custom shortcuts as that is already
// exposed as a direct shortcut
- if (!fromKeyboard && DeepShortcutManager.supportsShortcuts(item)) {
+ if (!fromKeyboard && ShortcutUtil.supportsShortcuts(item)) {
info.addAction(mActions.get(NotificationListener.getInstanceIfConnected() != null
? SHORTCUTS_AND_NOTIFICATIONS : DEEP_SHORTCUTS));
}
diff --git a/src/com/android/launcher3/allapps/AllAppsStore.java b/src/com/android/launcher3/allapps/AllAppsStore.java
index 160042e..267363f 100644
--- a/src/com/android/launcher3/allapps/AllAppsStore.java
+++ b/src/com/android/launcher3/allapps/AllAppsStore.java
@@ -80,6 +80,10 @@
}
}
+ public void disableDeferUpdatesSilently(int flag) {
+ mDeferUpdatesFlags &= ~flag;
+ }
+
public int getDeferUpdatesFlags() {
return mDeferUpdatesFlags;
}
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index a64374b..5b3beec 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -7,6 +7,7 @@
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.LauncherState.VERTICAL_SWIPE_INDICATOR;
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_ALL_APPS_FADE;
+import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_ALL_APPS_HEADER_FADE;
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_SCALE;
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_VERTICAL_PROGRESS;
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
@@ -208,13 +209,14 @@
PropertySetter setter = config == null ? NO_ANIM_PROPERTY_SETTER
: config.getPropertySetter(builder);
boolean hasHeaderExtra = (visibleElements & ALL_APPS_HEADER_EXTRA) != 0;
- boolean hasContent = (visibleElements & ALL_APPS_CONTENT) != 0;
+ boolean hasAllAppsContent = (visibleElements & ALL_APPS_CONTENT) != 0;
Interpolator allAppsFade = builder.getInterpolator(ANIM_ALL_APPS_FADE, LINEAR);
- setter.setViewAlpha(mAppsView.getContentView(), hasContent ? 1 : 0, allAppsFade);
- setter.setViewAlpha(mAppsView.getScrollBar(), hasContent ? 1 : 0, allAppsFade);
- mAppsView.getFloatingHeaderView().setContentVisibility(hasHeaderExtra, hasContent, setter,
- allAppsFade);
+ Interpolator headerFade = builder.getInterpolator(ANIM_ALL_APPS_HEADER_FADE, allAppsFade);
+ setter.setViewAlpha(mAppsView.getContentView(), hasAllAppsContent ? 1 : 0, allAppsFade);
+ setter.setViewAlpha(mAppsView.getScrollBar(), hasAllAppsContent ? 1 : 0, allAppsFade);
+ mAppsView.getFloatingHeaderView().setContentVisibility(hasHeaderExtra, hasAllAppsContent,
+ setter, headerFade, allAppsFade);
mAppsView.getSearchUiManager().setContentVisibility(visibleElements, setter, allAppsFade);
setter.setInt(mScrimView, ScrimView.DRAG_HANDLE_ALPHA,
diff --git a/src/com/android/launcher3/allapps/FloatingHeaderRow.java b/src/com/android/launcher3/allapps/FloatingHeaderRow.java
index 922e4f1..f899587 100644
--- a/src/com/android/launcher3/allapps/FloatingHeaderRow.java
+++ b/src/com/android/launcher3/allapps/FloatingHeaderRow.java
@@ -46,8 +46,8 @@
*/
boolean hasVisibleContent();
- void setContentVisibility(boolean hasHeaderExtra, boolean hasContent,
- PropertySetter setter, Interpolator fadeInterpolator);
+ void setContentVisibility(boolean hasHeaderExtra, boolean hasAllAppsContent,
+ PropertySetter setter, Interpolator headerFade, Interpolator allAppsFade);
/**
* Scrolls the content vertically.
diff --git a/src/com/android/launcher3/allapps/FloatingHeaderView.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java
index 66dced9..42a0eee 100644
--- a/src/com/android/launcher3/allapps/FloatingHeaderView.java
+++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java
@@ -27,6 +27,10 @@
import android.view.animation.Interpolator;
import android.widget.LinearLayout;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.recyclerview.widget.RecyclerView;
+
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Insettable;
import com.android.launcher3.Launcher;
@@ -40,10 +44,6 @@
import java.util.ArrayList;
import java.util.Map;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.RecyclerView;
-
public class FloatingHeaderView extends LinearLayout implements
ValueAnimator.AnimatorUpdateListener, PluginListener<AllAppsRow>, Insettable,
OnHeightUpdatedListener {
@@ -363,14 +363,14 @@
p.y = getTop() - mCurrentRV.getTop() - mParent.getTop();
}
- public void setContentVisibility(boolean hasHeader, boolean hasContent, PropertySetter setter,
- Interpolator fadeInterpolator) {
+ public void setContentVisibility(boolean hasHeader, boolean hasAllAppsContent,
+ PropertySetter setter, Interpolator headerFade, Interpolator allAppsFade) {
for (FloatingHeaderRow row : mAllRows) {
- row.setContentVisibility(hasHeader, hasContent, setter, fadeInterpolator);
+ row.setContentVisibility(hasHeader, hasAllAppsContent, setter, headerFade, allAppsFade);
}
- allowTouchForwarding(hasContent);
- setter.setFloat(mTabLayout, ALPHA, hasContent ? 1 : 0, fadeInterpolator);
+ allowTouchForwarding(hasAllAppsContent);
+ setter.setFloat(mTabLayout, ALPHA, hasAllAppsContent ? 1 : 0, headerFade);
}
protected void allowTouchForwarding(boolean allow) {
diff --git a/src/com/android/launcher3/allapps/PluginHeaderRow.java b/src/com/android/launcher3/allapps/PluginHeaderRow.java
index b283ff4..535ef54 100644
--- a/src/com/android/launcher3/allapps/PluginHeaderRow.java
+++ b/src/com/android/launcher3/allapps/PluginHeaderRow.java
@@ -64,10 +64,10 @@
}
@Override
- public void setContentVisibility(boolean hasHeaderExtra, boolean hasContent,
- PropertySetter setter, Interpolator fadeInterpolator) {
+ public void setContentVisibility(boolean hasHeaderExtra, boolean hasAllAppsContent,
+ PropertySetter setter, Interpolator headerFade, Interpolator allAppsFade) {
// Don't use setViewAlpha as we want to control the visibility ourselves.
- setter.setFloat(mView, ALPHA, hasContent ? 1 : 0, fadeInterpolator);
+ setter.setFloat(mView, ALPHA, hasAllAppsContent ? 1 : 0, headerFade);
}
@Override
diff --git a/src/com/android/launcher3/anim/AnimatorSetBuilder.java b/src/com/android/launcher3/anim/AnimatorSetBuilder.java
index 52a896e..cd30dea 100644
--- a/src/com/android/launcher3/anim/AnimatorSetBuilder.java
+++ b/src/com/android/launcher3/anim/AnimatorSetBuilder.java
@@ -39,6 +39,8 @@
public static final int ANIM_OVERVIEW_TRANSLATE_Y = 8;
public static final int ANIM_OVERVIEW_FADE = 9;
public static final int ANIM_ALL_APPS_FADE = 10;
+ public static final int ANIM_OVERVIEW_SCRIM_FADE = 11;
+ public static final int ANIM_ALL_APPS_HEADER_FADE = 12; // e.g. predictions
public static final int FLAG_DONT_ANIMATE_OVERVIEW = 1 << 0;
diff --git a/src/com/android/launcher3/compat/PackageInstallerCompat.java b/src/com/android/launcher3/compat/PackageInstallerCompat.java
index 7dad7e9..4f4d641 100644
--- a/src/com/android/launcher3/compat/PackageInstallerCompat.java
+++ b/src/com/android/launcher3/compat/PackageInstallerCompat.java
@@ -19,6 +19,7 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageInstaller;
+import android.os.UserHandle;
import java.util.HashMap;
import java.util.List;
@@ -48,6 +49,11 @@
*/
public abstract HashMap<String, PackageInstaller.SessionInfo> updateAndGetActiveSessionCache();
+ /**
+ * @return an active SessionInfo for {@param pkg} or null if none exists.
+ */
+ public abstract PackageInstaller.SessionInfo getActiveSessionInfo(UserHandle user, String pkg);
+
public abstract void onStop();
public static final class PackageInstallInfo {
diff --git a/src/com/android/launcher3/compat/PackageInstallerCompatVL.java b/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
index a34ca50..8a5eabc 100644
--- a/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
+++ b/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
@@ -64,9 +64,9 @@
@Override
public HashMap<String, SessionInfo> updateAndGetActiveSessionCache() {
HashMap<String, SessionInfo> activePackages = new HashMap<>();
- UserHandle user = Process.myUserHandle();
+ UserHandle primaryUser = Process.myUserHandle();
for (SessionInfo info : getAllVerifiedSessions()) {
- addSessionInfoToCache(info, user);
+ addSessionInfoToCache(info, Utilities.ATLEAST_Q ? info.getUser() : primaryUser);
if (info.getAppPackageName() != null) {
activePackages.put(info.getAppPackageName(), info);
mActiveSessions.put(info.getSessionId(), info.getAppPackageName());
@@ -75,6 +75,19 @@
return activePackages;
}
+ public SessionInfo getActiveSessionInfo(UserHandle user, String pkg) {
+ for (SessionInfo info : getAllVerifiedSessions()) {
+ boolean match = pkg.equals(info.getAppPackageName());
+ if (Utilities.ATLEAST_Q && !user.equals(info.getUser())) {
+ match = false;
+ }
+ if (match) {
+ return info;
+ }
+ }
+ return null;
+ }
+
@Thunk void addSessionInfoToCache(SessionInfo info, UserHandle user) {
String packageName = info.getAppPackageName();
if (packageName != null) {
diff --git a/src/com/android/launcher3/config/BaseFlags.java b/src/com/android/launcher3/config/BaseFlags.java
index 6436e4c..23edcd2 100644
--- a/src/com/android/launcher3/config/BaseFlags.java
+++ b/src/com/android/launcher3/config/BaseFlags.java
@@ -106,6 +106,10 @@
"FAKE_LANDSCAPE_UI", false,
"Rotate launcher UI instead of using transposed layout");
+ public static final TogglableFlag APP_SEARCH_IMPROVEMENTS = new TogglableFlag(
+ "APP_SEARCH_IMPROVEMENTS", false,
+ "Adds localized title and keyword search and ranking");
+
public static void initialize(Context context) {
// Avoid the disk read for user builds
if (Utilities.IS_DEBUG_DEVICE) {
diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java
index a72089d..a2dcbf8 100644
--- a/src/com/android/launcher3/dragndrop/AddItemActivity.java
+++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java
@@ -153,16 +153,6 @@
PinItemDragListener listener = new PinItemDragListener(mRequest, bounds,
img.getBitmap().getWidth(), img.getWidth());
- Intent homeIntent = listener.addToIntent(
- new Intent(Intent.ACTION_MAIN)
- .addCategory(Intent.CATEGORY_HOME)
- .setPackage(getPackageName())
- .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
-
- listener.initWhenReady();
- startActivity(homeIntent,
- ActivityOptions.makeCustomAnimation(this, 0, android.R.anim.fade_out).toBundle());
- mFinishOnPause = true;
// Start a system drag and drop. We use a transparent bitmap as preview for system drag
// as the preview is handled internally by launcher.
@@ -179,6 +169,18 @@
outShadowTouchPoint.set(SHADOW_SIZE / 2, SHADOW_SIZE / 2);
}
}, null, View.DRAG_FLAG_GLOBAL);
+
+
+ Intent homeIntent = listener.addToIntent(
+ new Intent(Intent.ACTION_MAIN)
+ .addCategory(Intent.CATEGORY_HOME)
+ .setPackage(getPackageName())
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+
+ listener.initWhenReady();
+ startActivity(homeIntent,
+ ActivityOptions.makeCustomAnimation(this, 0, android.R.anim.fade_out).toBundle());
+ mFinishOnPause = true;
return false;
}
diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java
index d32dd2e..b72fd98 100644
--- a/src/com/android/launcher3/dragndrop/DragController.java
+++ b/src/com/android/launcher3/dragndrop/DragController.java
@@ -579,6 +579,9 @@
}
private void drop(DropTarget dropTarget, Runnable flingAnimation) {
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.NO_DRAG_TO_WORKSPACE, "DragController.drop");
+ }
final int[] coordinates = mCoordinatesTemp;
mDragObject.x = coordinates[0];
mDragObject.y = coordinates[1];
diff --git a/src/com/android/launcher3/dragndrop/DragDriver.java b/src/com/android/launcher3/dragndrop/DragDriver.java
index 84fc94d..bd2a03b 100644
--- a/src/com/android/launcher3/dragndrop/DragDriver.java
+++ b/src/com/android/launcher3/dragndrop/DragDriver.java
@@ -17,10 +17,12 @@
package com.android.launcher3.dragndrop;
import android.content.Context;
+import android.util.Log;
import android.view.DragEvent;
import android.view.MotionEvent;
import com.android.launcher3.DropTarget.DragObject;
+import com.android.launcher3.testing.TestProtocol;
/**
* Base class for driving a drag/drop operation.
@@ -52,6 +54,9 @@
mEventListener.onDriverDragMove(ev.getX(), ev.getY());
break;
case MotionEvent.ACTION_UP:
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.NO_DRAG_TO_WORKSPACE, "DragDriver.ACTION_UP");
+ }
mEventListener.onDriverDragMove(ev.getX(), ev.getY());
mEventListener.onDriverDragEnd(ev.getX(), ev.getY());
break;
diff --git a/src/com/android/launcher3/dragndrop/DragLayer.java b/src/com/android/launcher3/dragndrop/DragLayer.java
index 6ba015b..b59164a 100644
--- a/src/com/android/launcher3/dragndrop/DragLayer.java
+++ b/src/com/android/launcher3/dragndrop/DragLayer.java
@@ -48,12 +48,13 @@
import com.android.launcher3.DropTargetBar;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
-import com.android.launcher3.graphics.RotationMode;
import com.android.launcher3.ShortcutAndWidgetContainer;
import com.android.launcher3.Workspace;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderIcon;
+import com.android.launcher3.graphics.OverviewScrim;
+import com.android.launcher3.graphics.RotationMode;
import com.android.launcher3.graphics.WorkspaceAndHotseatScrim;
import com.android.launcher3.keyboard.ViewGroupFocusHelper;
import com.android.launcher3.uioverrides.UiFactory;
@@ -92,7 +93,8 @@
// Related to adjacent page hints
private final ViewGroupFocusHelper mFocusIndicatorHelper;
- private final WorkspaceAndHotseatScrim mScrim;
+ private final WorkspaceAndHotseatScrim mWorkspaceScrim;
+ private final OverviewScrim mOverviewScrim;
/**
* Used to create a new DragLayer from XML.
@@ -108,12 +110,13 @@
setChildrenDrawingOrderEnabled(true);
mFocusIndicatorHelper = new ViewGroupFocusHelper(this);
- mScrim = new WorkspaceAndHotseatScrim(this);
+ mWorkspaceScrim = new WorkspaceAndHotseatScrim(this);
+ mOverviewScrim = new OverviewScrim(this);
}
public void setup(DragController dragController, Workspace workspace) {
mDragController = dragController;
- mScrim.setWorkspace(workspace);
+ mWorkspaceScrim.setWorkspace(workspace);
recreateControllers();
}
@@ -529,25 +532,39 @@
@Override
protected void dispatchDraw(Canvas canvas) {
// Draw the background below children.
- mScrim.draw(canvas);
+ mWorkspaceScrim.draw(canvas);
+ mOverviewScrim.updateCurrentScrimmedView(this);
mFocusIndicatorHelper.draw(canvas);
super.dispatchDraw(canvas);
}
@Override
+ protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
+ if (child == mOverviewScrim.getScrimmedView()) {
+ mOverviewScrim.draw(canvas);
+ }
+ return super.drawChild(canvas, child, drawingTime);
+ }
+
+ @Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
- mScrim.setSize(w, h);
+ mWorkspaceScrim.setSize(w, h);
}
@Override
public void setInsets(Rect insets) {
super.setInsets(insets);
- mScrim.onInsetsChanged(insets);
+ mWorkspaceScrim.onInsetsChanged(insets);
+ mOverviewScrim.onInsetsChanged(insets);
}
public WorkspaceAndHotseatScrim getScrim() {
- return mScrim;
+ return mWorkspaceScrim;
+ }
+
+ public OverviewScrim getOverviewScrim() {
+ return mOverviewScrim;
}
@Override
diff --git a/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java b/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java
index 0c5a1fc..d8a1f99 100644
--- a/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java
+++ b/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java
@@ -28,6 +28,8 @@
import android.os.Build;
import android.util.Log;
+import androidx.annotation.Nullable;
+
import com.android.launcher3.Launcher;
import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.R;
@@ -66,15 +68,19 @@
return mBadge;
}
- public static FolderAdaptiveIcon createFolderAdaptiveIcon(
+ public static @Nullable FolderAdaptiveIcon createFolderAdaptiveIcon(
Launcher launcher, int folderId, Point dragViewSize) {
Preconditions.assertNonUiThread();
int margin = launcher.getResources()
.getDimensionPixelSize(R.dimen.blur_size_medium_outline);
// Allocate various bitmaps on the background thread, because why not!
- final Bitmap badge = Bitmap.createBitmap(
- dragViewSize.x - margin, dragViewSize.y - margin, Bitmap.Config.ARGB_8888);
+ int width = dragViewSize.x - margin;
+ int height = dragViewSize.y - margin;
+ if (width <= 0 || height <= 0) {
+ return null;
+ }
+ final Bitmap badge = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
// Create the actual drawable on the UI thread to avoid race conditions with
// FolderIcon draw pass
diff --git a/src/com/android/launcher3/graphics/DrawableFactory.java b/src/com/android/launcher3/graphics/DrawableFactory.java
index c9566cb..288749f 100644
--- a/src/com/android/launcher3/graphics/DrawableFactory.java
+++ b/src/com/android/launcher3/graphics/DrawableFactory.java
@@ -17,6 +17,7 @@
package com.android.launcher3.graphics;
import static com.android.launcher3.graphics.IconShape.getShapePath;
+import static com.android.launcher3.util.MainThreadInitializedObject.forOverride;
import android.content.Context;
import android.content.pm.ActivityInfo;
@@ -31,6 +32,8 @@
import android.os.UserHandle;
import android.util.ArrayMap;
+import androidx.annotation.UiThread;
+
import com.android.launcher3.FastBitmapDrawable;
import com.android.launcher3.ItemInfoWithIcon;
import com.android.launcher3.R;
@@ -38,16 +41,13 @@
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.ResourceBasedOverride;
-import androidx.annotation.UiThread;
-
/**
* Factory for creating new drawables.
*/
public class DrawableFactory implements ResourceBasedOverride {
public static final MainThreadInitializedObject<DrawableFactory> INSTANCE =
- new MainThreadInitializedObject<>(c -> Overrides.getObject(DrawableFactory.class,
- c.getApplicationContext(), R.string.drawable_factory_class));
+ forOverride(DrawableFactory.class, R.string.drawable_factory_class);
protected final UserHandle mMyUser = Process.myUserHandle();
protected final ArrayMap<UserHandle, Bitmap> mUserBadges = new ArrayMap<>();
diff --git a/src/com/android/launcher3/graphics/OverviewScrim.java b/src/com/android/launcher3/graphics/OverviewScrim.java
new file mode 100644
index 0000000..d707403
--- /dev/null
+++ b/src/com/android/launcher3/graphics/OverviewScrim.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.graphics;
+
+import static android.view.View.VISIBLE;
+
+import static com.android.launcher3.LauncherState.HOTSEAT_ICONS;
+import static com.android.launcher3.LauncherState.OVERVIEW;
+
+import android.graphics.Rect;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+/**
+ * View scrim which draws behind overview (recent apps).
+ */
+public class OverviewScrim extends Scrim {
+
+ private @NonNull View mStableScrimmedView;
+ // Might be higher up if mStableScrimmedView is invisible.
+ private @Nullable View mCurrentScrimmedView;
+
+ public OverviewScrim(View view) {
+ super(view);
+ mStableScrimmedView = mCurrentScrimmedView = mLauncher.getOverviewPanel();
+
+ onExtractedColorsChanged(mWallpaperColorInfo);
+ }
+
+ public void onInsetsChanged(Rect insets) {
+ mStableScrimmedView = (OVERVIEW.getVisibleElements(mLauncher) & HOTSEAT_ICONS) != 0
+ ? mLauncher.getHotseat()
+ : mLauncher.getOverviewPanel();
+ }
+
+ public void updateCurrentScrimmedView(ViewGroup root) {
+ // Find the lowest view that is at or above the view we want to show the scrim behind.
+ mCurrentScrimmedView = mStableScrimmedView;
+ int currentIndex = root.indexOfChild(mCurrentScrimmedView);
+ final int childCount = root.getChildCount();
+ while (mCurrentScrimmedView.getVisibility() != VISIBLE && currentIndex < childCount) {
+ currentIndex++;
+ mCurrentScrimmedView = root.getChildAt(currentIndex);
+ }
+ }
+
+ /**
+ * @return The view to draw the scrim behind.
+ */
+ public View getScrimmedView() {
+ return mCurrentScrimmedView;
+ }
+}
diff --git a/src/com/android/launcher3/graphics/Scrim.java b/src/com/android/launcher3/graphics/Scrim.java
new file mode 100644
index 0000000..5c14f8d
--- /dev/null
+++ b/src/com/android/launcher3/graphics/Scrim.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.graphics;
+
+import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
+
+import android.graphics.Canvas;
+import android.util.Property;
+import android.view.View;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.uioverrides.WallpaperColorInfo;
+
+/**
+ * Contains general scrim properties such as wallpaper-extracted color that subclasses can use.
+ */
+public class Scrim implements View.OnAttachStateChangeListener,
+ WallpaperColorInfo.OnChangeListener {
+
+ public static Property<Scrim, Float> SCRIM_PROGRESS =
+ new Property<Scrim, Float>(Float.TYPE, "scrimProgress") {
+ @Override
+ public Float get(Scrim scrim) {
+ return scrim.mScrimProgress;
+ }
+
+ @Override
+ public void set(Scrim scrim, Float value) {
+ scrim.setScrimProgress(value);
+ }
+ };
+
+ protected final Launcher mLauncher;
+ protected final WallpaperColorInfo mWallpaperColorInfo;
+ protected final View mRoot;
+
+ protected float mScrimProgress;
+ protected int mScrimColor;
+ protected int mScrimAlpha = 0;
+
+ public Scrim(View view) {
+ mRoot = view;
+ mLauncher = Launcher.getLauncher(view.getContext());
+ mWallpaperColorInfo = WallpaperColorInfo.getInstance(mLauncher);
+
+ view.addOnAttachStateChangeListener(this);
+ }
+
+ public void draw(Canvas canvas) {
+ canvas.drawColor(setColorAlphaBound(mScrimColor, mScrimAlpha));
+ }
+
+ private void setScrimProgress(float progress) {
+ if (mScrimProgress != progress) {
+ mScrimProgress = progress;
+ mScrimAlpha = Math.round(255 * mScrimProgress);
+ invalidate();
+ }
+ }
+
+ @Override
+ public void onViewAttachedToWindow(View view) {
+ mWallpaperColorInfo.addOnChangeListener(this);
+ onExtractedColorsChanged(mWallpaperColorInfo);
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View view) {
+ mWallpaperColorInfo.removeOnChangeListener(this);
+ }
+
+ @Override
+ public void onExtractedColorsChanged(WallpaperColorInfo wallpaperColorInfo) {
+ mScrimColor = wallpaperColorInfo.getMainColor();
+ if (mScrimAlpha > 0) {
+ invalidate();
+ }
+ }
+
+ public void invalidate() {
+ mRoot.invalidate();
+ }
+}
diff --git a/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java b/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java
index c0aa75f..6740fa1 100644
--- a/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java
+++ b/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java
@@ -40,34 +40,19 @@
import android.util.Property;
import android.view.View;
+import androidx.core.graphics.ColorUtils;
+
import com.android.launcher3.CellLayout;
-import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.ResourceUtils;
import com.android.launcher3.Workspace;
import com.android.launcher3.uioverrides.WallpaperColorInfo;
import com.android.launcher3.util.Themes;
-import androidx.core.graphics.ColorUtils;
-
/**
* View scrim which draws behind hotseat and workspace
*/
-public class WorkspaceAndHotseatScrim implements
- View.OnAttachStateChangeListener, WallpaperColorInfo.OnChangeListener {
-
- public static Property<WorkspaceAndHotseatScrim, Float> SCRIM_PROGRESS =
- new Property<WorkspaceAndHotseatScrim, Float>(Float.TYPE, "scrimProgress") {
- @Override
- public Float get(WorkspaceAndHotseatScrim scrim) {
- return scrim.mScrimProgress;
- }
-
- @Override
- public void set(WorkspaceAndHotseatScrim scrim, Float value) {
- scrim.setScrimProgress(value);
- }
- };
+public class WorkspaceAndHotseatScrim extends Scrim {
public static Property<WorkspaceAndHotseatScrim, Float> SYSUI_PROGRESS =
new Property<WorkspaceAndHotseatScrim, Float>(Float.TYPE, "sysUiProgress") {
@@ -117,9 +102,6 @@
private static final int ALPHA_MASK_WIDTH_DP = 2;
private final Rect mHighlightRect = new Rect();
- private final Launcher mLauncher;
- private final WallpaperColorInfo mWallpaperColorInfo;
- private final View mRoot;
private Workspace mWorkspace;
@@ -132,11 +114,6 @@
private final Drawable mTopScrim;
- private int mFullScrimColor;
-
- private float mScrimProgress;
- private int mScrimAlpha = 0;
-
private float mSysUiProgress = 1;
private boolean mHideSysUiScrim;
@@ -144,9 +121,7 @@
private float mSysUiAnimMultiplier = 1;
public WorkspaceAndHotseatScrim(View view) {
- mRoot = view;
- mLauncher = Launcher.getLauncher(view.getContext());
- mWallpaperColorInfo = WallpaperColorInfo.getInstance(mLauncher);
+ super(view);
mMaskHeight = ResourceUtils.pxFromDp(ALPHA_MASK_BITMAP_DP,
view.getResources().getDisplayMetrics());
@@ -154,7 +129,6 @@
mBottomMask = mTopScrim == null ? null : createDitheredAlphaMask();
mHideSysUiScrim = mTopScrim == null;
- view.addOnAttachStateChangeListener(this);
onExtractedColorsChanged(mWallpaperColorInfo);
}
@@ -176,7 +150,7 @@
canvas.clipRect(mHighlightRect, Region.Op.DIFFERENCE);
}
- canvas.drawColor(setColorAlphaBound(mFullScrimColor, mScrimAlpha));
+ super.draw(canvas);
canvas.restore();
}
@@ -190,11 +164,8 @@
mSysUiAnimMultiplier = 0;
reapplySysUiAlphaNoInvalidate();
- ObjectAnimator anim = ObjectAnimator.ofFloat(this, SYSUI_ANIM_MULTIPLIER, 1);
- anim.setAutoCancel(true);
- anim.setDuration(600);
- anim.setStartDelay(mLauncher.getWindow().getTransitionBackgroundFadeDuration());
- anim.start();
+ animateToSysuiMultiplier(1, 600,
+ mLauncher.getWindow().getTransitionBackgroundFadeDuration());
mAnimateScrimOnNextDraw = false;
}
@@ -207,24 +178,24 @@
}
}
+ public void animateToSysuiMultiplier(float toMultiplier, long duration,
+ long startDelay) {
+ ObjectAnimator anim = ObjectAnimator.ofFloat(this, SYSUI_ANIM_MULTIPLIER, toMultiplier);
+ anim.setAutoCancel(true);
+ anim.setDuration(duration);
+ anim.setStartDelay(startDelay);
+ anim.start();
+ }
+
public void onInsetsChanged(Rect insets) {
mDrawTopScrim = mTopScrim != null && insets.top > 0;
mDrawBottomScrim = mBottomMask != null &&
!mLauncher.getDeviceProfile().isVerticalBarLayout();
}
- private void setScrimProgress(float progress) {
- if (mScrimProgress != progress) {
- mScrimProgress = progress;
- mScrimAlpha = Math.round(255 * mScrimProgress);
- invalidate();
- }
- }
-
@Override
public void onViewAttachedToWindow(View view) {
- mWallpaperColorInfo.addOnChangeListener(this);
- onExtractedColorsChanged(mWallpaperColorInfo);
+ super.onViewAttachedToWindow(view);
if (mTopScrim != null) {
IntentFilter filter = new IntentFilter(ACTION_SCREEN_OFF);
@@ -235,7 +206,7 @@
@Override
public void onViewDetachedFromWindow(View view) {
- mWallpaperColorInfo.removeOnChangeListener(this);
+ super.onViewDetachedFromWindow(view);
if (mTopScrim != null) {
mRoot.getContext().unregisterReceiver(mReceiver);
}
@@ -248,10 +219,7 @@
mBottomMaskPaint.setColor(ColorUtils.compositeColors(DARK_SCRIM_COLOR,
wallpaperColorInfo.getMainColor()));
reapplySysUiAlpha();
- mFullScrimColor = wallpaperColorInfo.getMainColor();
- if (mScrimAlpha > 0) {
- invalidate();
- }
+ super.onExtractedColorsChanged(wallpaperColorInfo);
}
public void setSize(int w, int h) {
@@ -291,10 +259,6 @@
}
}
- public void invalidate() {
- mRoot.invalidate();
- }
-
public Bitmap createDitheredAlphaMask() {
DisplayMetrics dm = mLauncher.getResources().getDisplayMetrics();
int width = ResourceUtils.pxFromDp(ALPHA_MASK_WIDTH_DP, dm);
diff --git a/src/com/android/launcher3/icons/IconCache.java b/src/com/android/launcher3/icons/IconCache.java
index 648445e..55d58b9 100644
--- a/src/com/android/launcher3/icons/IconCache.java
+++ b/src/com/android/launcher3/icons/IconCache.java
@@ -29,6 +29,8 @@
import android.os.UserHandle;
import android.util.Log;
+import androidx.annotation.NonNull;
+
import com.android.launcher3.AppInfo;
import com.android.launcher3.IconProvider;
import com.android.launcher3.InvariantDeviceProfile;
@@ -36,8 +38,8 @@
import com.android.launcher3.LauncherFiles;
import com.android.launcher3.LauncherModel;
import com.android.launcher3.MainThreadExecutor;
-import com.android.launcher3.WorkspaceItemInfo;
import com.android.launcher3.Utilities;
+import com.android.launcher3.WorkspaceItemInfo;
import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.icons.ComponentWithLabel.ComponentCachingLogic;
@@ -50,8 +52,6 @@
import java.util.function.Supplier;
-import androidx.annotation.NonNull;
-
/**
* Cache of application icons. Icons can be made from any thread.
*/
@@ -75,11 +75,11 @@
super(context, LauncherFiles.APP_ICONS_DB, LauncherModel.getWorkerLooper(),
inv.fillResIconDpi, inv.iconBitmapSize, true /* inMemoryCache */);
mComponentWithLabelCachingLogic = new ComponentCachingLogic(context);
- mLauncherActivityInfoCachingLogic = new LauncherActivtiyCachingLogic(this);
+ mLauncherActivityInfoCachingLogic = LauncherActivityCachingLogic.newInstance(context);
mLauncherApps = LauncherAppsCompat.getInstance(mContext);
mUserManager = UserManagerCompat.getInstance(mContext);
mInstantAppResolver = InstantAppResolver.newInstance(mContext);
- mIconProvider = IconProvider.newInstance(context);
+ mIconProvider = IconProvider.INSTANCE.get(context);
}
@Override
diff --git a/src/com/android/launcher3/icons/LauncherActivtiyCachingLogic.java b/src/com/android/launcher3/icons/LauncherActivityCachingLogic.java
similarity index 67%
rename from src/com/android/launcher3/icons/LauncherActivtiyCachingLogic.java
rename to src/com/android/launcher3/icons/LauncherActivityCachingLogic.java
index 7c99633..f9a94da 100644
--- a/src/com/android/launcher3/icons/LauncherActivtiyCachingLogic.java
+++ b/src/com/android/launcher3/icons/LauncherActivityCachingLogic.java
@@ -20,14 +20,23 @@
import android.content.pm.LauncherActivityInfo;
import android.os.UserHandle;
+import com.android.launcher3.IconProvider;
+import com.android.launcher3.R;
import com.android.launcher3.icons.cache.CachingLogic;
+import com.android.launcher3.util.ResourceBasedOverride;
-public class LauncherActivtiyCachingLogic implements CachingLogic<LauncherActivityInfo> {
+/**
+ * Caching logic for LauncherActivityInfo.
+ */
+public class LauncherActivityCachingLogic
+ implements CachingLogic<LauncherActivityInfo>, ResourceBasedOverride {
- private final IconCache mCache;
-
- public LauncherActivtiyCachingLogic(IconCache cache) {
- mCache = cache;
+ /**
+ * Creates and returns a new instance
+ */
+ public static LauncherActivityCachingLogic newInstance(Context context) {
+ return Overrides.getObject(LauncherActivityCachingLogic.class, context,
+ R.string.launcher_activity_logic_class);
}
@Override
@@ -49,8 +58,10 @@
public void loadIcon(Context context, LauncherActivityInfo object,
BitmapInfo target) {
LauncherIcons li = LauncherIcons.obtain(context);
- li.createBadgedIconBitmap(mCache.getFullResIcon(object),
+ li.createBadgedIconBitmap(
+ IconProvider.INSTANCE.get(context)
+ .getIcon(object, li.mFillResIconDpi, true /* flattenDrawable */),
object.getUser(), object.getApplicationInfo().targetSdkVersion).applyTo(target);
li.recycle();
}
-}
\ No newline at end of file
+}
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index 9b9543e..d11d434 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -40,5 +40,6 @@
public void logAppLaunch(View v, Intent intent) { }
public void logTaskLaunch(View v, ComponentKey key) { }
+ public void logTaskDismiss(View v, ComponentKey key) { }
public void verify() {} // TODO: should move into robo tests
}
diff --git a/src/com/android/launcher3/logging/UserEventDispatcher.java b/src/com/android/launcher3/logging/UserEventDispatcher.java
index d81020e..c72b07a 100644
--- a/src/com/android/launcher3/logging/UserEventDispatcher.java
+++ b/src/com/android/launcher3/logging/UserEventDispatcher.java
@@ -187,6 +187,14 @@
dstContainerType >=0 ? newContainerTarget(dstContainerType) : null);
}
+ public void logActionCommand(int command, int srcContainerType, int dstContainerType,
+ int pageIndex) {
+ Target srcTarget = newContainerTarget(srcContainerType);
+ srcTarget.pageIndex = pageIndex;
+ logActionCommand(command, srcTarget,
+ dstContainerType >=0 ? newContainerTarget(dstContainerType) : null);
+ }
+
public void logActionCommand(int command, Target srcTarget, Target dstTarget) {
LauncherEvent event = newLauncherEvent(newCommandAction(command), srcTarget);
if (command == Action.Command.STOP) {
diff --git a/src/com/android/launcher3/model/AppLaunchTracker.java b/src/com/android/launcher3/model/AppLaunchTracker.java
index 1613d47..29a46cf 100644
--- a/src/com/android/launcher3/model/AppLaunchTracker.java
+++ b/src/com/android/launcher3/model/AppLaunchTracker.java
@@ -15,18 +15,18 @@
*/
package com.android.launcher3.model;
-import static com.android.launcher3.util.ResourceBasedOverride.Overrides.getObject;
+import static com.android.launcher3.util.MainThreadInitializedObject.forOverride;
import android.content.ComponentName;
import android.os.UserHandle;
+import androidx.annotation.Nullable;
+
import com.android.launcher3.R;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.ResourceBasedOverride;
-import androidx.annotation.Nullable;
-
/**
* Callback for receiving various app launch events
*/
@@ -43,8 +43,7 @@
public static final MainThreadInitializedObject<AppLaunchTracker> INSTANCE =
- new MainThreadInitializedObject<>(c ->
- getObject(AppLaunchTracker.class, c, R.string.app_launch_tracker_class));
+ forOverride(AppLaunchTracker.class, R.string.app_launch_tracker_class);
public void onStartShortcut(String packageName, String shortcutId, UserHandle user,
@Nullable String container) { }
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index 0138572..4b01b5e 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -49,8 +49,8 @@
import com.android.launcher3.LauncherAppWidgetInfo;
import com.android.launcher3.LauncherModel;
import com.android.launcher3.LauncherSettings;
-import com.android.launcher3.WorkspaceItemInfo;
import com.android.launcher3.Utilities;
+import com.android.launcher3.WorkspaceItemInfo;
import com.android.launcher3.compat.AppWidgetManagerCompat;
import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.PackageInstallerCompat;
@@ -61,7 +61,7 @@
import com.android.launcher3.icons.ComponentWithLabel;
import com.android.launcher3.icons.ComponentWithLabel.ComponentCachingLogic;
import com.android.launcher3.icons.IconCache;
-import com.android.launcher3.icons.LauncherActivtiyCachingLogic;
+import com.android.launcher3.icons.LauncherActivityCachingLogic;
import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.icons.cache.IconCacheUpdateHandler;
import com.android.launcher3.logging.FileLog;
@@ -196,7 +196,7 @@
IconCacheUpdateHandler updateHandler = mIconCache.getUpdateHandler();
setIgnorePackages(updateHandler);
updateHandler.updateIcons(allActivityList,
- new LauncherActivtiyCachingLogic(mApp.getIconCache()),
+ LauncherActivityCachingLogic.newInstance(mApp.getContext()),
mApp.getModel()::onPackageIconsUpdated);
// Take a break
diff --git a/src/com/android/launcher3/notification/NotificationKeyData.java b/src/com/android/launcher3/notification/NotificationKeyData.java
index 5050457..bfa4ba9 100644
--- a/src/com/android/launcher3/notification/NotificationKeyData.java
+++ b/src/com/android/launcher3/notification/NotificationKeyData.java
@@ -17,12 +17,18 @@
package com.android.launcher3.notification;
import android.app.Notification;
+import android.app.Person;
import android.service.notification.StatusBarNotification;
+import com.android.launcher3.Utilities;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
/**
* The key data associated with the notification, used to determine what to include
@@ -34,19 +40,25 @@
public final String notificationKey;
public final String shortcutId;
public int count;
+ @NonNull public final String[] personKeysFromNotification;
- private NotificationKeyData(String notificationKey, String shortcutId, int count) {
+ private NotificationKeyData(String notificationKey, String shortcutId, int count,
+ String[] personKeysFromNotification) {
this.notificationKey = notificationKey;
this.shortcutId = shortcutId;
this.count = Math.max(1, count);
+ this.personKeysFromNotification = personKeysFromNotification;
}
public static NotificationKeyData fromNotification(StatusBarNotification sbn) {
Notification notif = sbn.getNotification();
- return new NotificationKeyData(sbn.getKey(), notif.getShortcutId(), notif.number);
+ return new NotificationKeyData(sbn.getKey(), notif.getShortcutId(), notif.number,
+ extractPersonKeyOnly(notif.extras.getParcelableArrayList(
+ Notification.EXTRA_PEOPLE_LIST)));
}
- public static List<String> extractKeysOnly(@NonNull List<NotificationKeyData> notificationKeys) {
+ public static List<String> extractKeysOnly(
+ @NonNull List<NotificationKeyData> notificationKeys) {
List<String> keysOnly = new ArrayList<>(notificationKeys.size());
for (NotificationKeyData notificationKeyData : notificationKeys) {
keysOnly.add(notificationKeyData.notificationKey);
@@ -54,6 +66,13 @@
return keysOnly;
}
+ private static String[] extractPersonKeyOnly(@Nullable ArrayList<Person> people) {
+ if (people == null || people.isEmpty()) {
+ return Utilities.EMPTY_STRING_ARRAY;
+ }
+ return people.stream().map(Person::getKey).sorted().toArray(String[]::new);
+ }
+
@Override
public boolean equals(Object obj) {
if (!(obj instanceof NotificationKeyData)) {
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index 25d9f79..baaad65 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -72,6 +72,7 @@
import com.android.launcher3.touch.ItemClickHandler;
import com.android.launcher3.touch.ItemLongClickListener;
import com.android.launcher3.util.PackageUserKey;
+import com.android.launcher3.util.ShortcutUtil;
import com.android.launcher3.views.BaseDragLayer;
import java.util.ArrayList;
@@ -201,7 +202,7 @@
return null;
}
ItemInfo itemInfo = (ItemInfo) icon.getTag();
- if (!DeepShortcutManager.supportsShortcuts(itemInfo)) {
+ if (!ShortcutUtil.supportsShortcuts(itemInfo)) {
return null;
}
diff --git a/src/com/android/launcher3/popup/PopupDataProvider.java b/src/com/android/launcher3/popup/PopupDataProvider.java
index 2d301ac..4612b2a 100644
--- a/src/com/android/launcher3/popup/PopupDataProvider.java
+++ b/src/com/android/launcher3/popup/PopupDataProvider.java
@@ -29,17 +29,22 @@
import com.android.launcher3.shortcuts.DeepShortcutManager;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.PackageUserKey;
+import com.android.launcher3.util.ShortcutUtil;
import com.android.launcher3.widget.WidgetListRowEntry;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.function.Predicate;
+import java.util.stream.Collectors;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
/**
* Provides data for the popup menu that appears after long-clicking on apps.
@@ -129,7 +134,8 @@
for (PackageUserKey packageUserKey : mPackageUserToDotInfos.keySet()) {
DotInfo prevDot = updatedDots.get(packageUserKey);
DotInfo newDot = mPackageUserToDotInfos.get(packageUserKey);
- if (prevDot == null) {
+ if (prevDot == null
+ || prevDot.getNotificationCount() != newDot.getNotificationCount()) {
updatedDots.put(packageUserKey, newDot);
} else {
// No need to update the dot if it already existed (no visual change).
@@ -155,7 +161,7 @@
}
public int getShortcutCountForItem(ItemInfo info) {
- if (!DeepShortcutManager.supportsShortcuts(info)) {
+ if (!ShortcutUtil.supportsDeepShortcuts(info)) {
return 0;
}
ComponentName component = info.getTargetComponent();
@@ -167,17 +173,26 @@
return count == null ? 0 : count;
}
- public DotInfo getDotInfoForItem(ItemInfo info) {
- if (!DeepShortcutManager.supportsShortcuts(info)) {
+ public @Nullable DotInfo getDotInfoForItem(@NonNull ItemInfo info) {
+ if (!ShortcutUtil.supportsShortcuts(info)) {
return null;
}
-
- return mPackageUserToDotInfos.get(PackageUserKey.fromItemInfo(info));
+ DotInfo dotInfo = mPackageUserToDotInfos.get(PackageUserKey.fromItemInfo(info));
+ if (dotInfo == null) {
+ return null;
+ }
+ List<NotificationKeyData> notifications = getNotificationsForItem(
+ info, dotInfo.getNotificationKeys());
+ if (notifications.isEmpty()) {
+ return null;
+ }
+ return dotInfo;
}
public @NonNull List<NotificationKeyData> getNotificationKeysForItem(ItemInfo info) {
DotInfo dotInfo = getDotInfoForItem(info);
- return dotInfo == null ? Collections.EMPTY_LIST : dotInfo.getNotificationKeys();
+ return dotInfo == null ? Collections.EMPTY_LIST
+ : getNotificationsForItem(info, dotInfo.getNotificationKeys());
}
/** This makes a potentially expensive binder call and should be run on a background thread. */
@@ -226,6 +241,27 @@
return null;
}
+ /**
+ * Returns a list of notifications that are relevant to given ItemInfo.
+ */
+ public static @NonNull List<NotificationKeyData> getNotificationsForItem(
+ @NonNull ItemInfo info, @NonNull List<NotificationKeyData> notifications) {
+ String shortcutId = ShortcutUtil.getShortcutIdIfPinnedShortcut(info);
+ if (shortcutId == null) {
+ return notifications;
+ }
+ String[] personKeys = ShortcutUtil.getPersonKeysIfPinnedShortcut(info);
+ return notifications.stream().filter((NotificationKeyData notification) -> {
+ if (notification.shortcutId != null) {
+ return notification.shortcutId.equals(shortcutId);
+ }
+ if (notification.personKeysFromNotification.length != 0) {
+ return Arrays.equals(notification.personKeysFromNotification, personKeys);
+ }
+ return false;
+ }).collect(Collectors.toList());
+ }
+
public interface PopupDataChangeListener {
PopupDataChangeListener INSTANCE = new PopupDataChangeListener() { };
diff --git a/src/com/android/launcher3/popup/RemoteActionShortcut.java b/src/com/android/launcher3/popup/RemoteActionShortcut.java
index 41ab4df..5a5fbab 100644
--- a/src/com/android/launcher3/popup/RemoteActionShortcut.java
+++ b/src/com/android/launcher3/popup/RemoteActionShortcut.java
@@ -29,11 +29,12 @@
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
import com.android.launcher3.userevent.nano.LauncherLogProto;
public class RemoteActionShortcut extends SystemShortcut<BaseDraggingActivity> {
private static final String TAG = "RemoteActionShortcut";
- private static final boolean DEBUG = false;
+ private static final boolean DEBUG = Utilities.IS_DEBUG_DEVICE;
private final RemoteAction mAction;
diff --git a/src/com/android/launcher3/popup/SystemShortcutFactory.java b/src/com/android/launcher3/popup/SystemShortcutFactory.java
index 516fafa..37a2092 100644
--- a/src/com/android/launcher3/popup/SystemShortcutFactory.java
+++ b/src/com/android/launcher3/popup/SystemShortcutFactory.java
@@ -15,6 +15,10 @@
*/
package com.android.launcher3.popup;
+import static com.android.launcher3.util.MainThreadInitializedObject.forOverride;
+
+import androidx.annotation.NonNull;
+
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
@@ -24,13 +28,10 @@
import java.util.ArrayList;
import java.util.List;
-import androidx.annotation.NonNull;
-
public class SystemShortcutFactory implements ResourceBasedOverride {
public static final MainThreadInitializedObject<SystemShortcutFactory> INSTANCE =
- new MainThreadInitializedObject<>(c -> Overrides.getObject(
- SystemShortcutFactory.class, c, R.string.system_shortcut_factory_class));
+ forOverride(SystemShortcutFactory.class, R.string.system_shortcut_factory_class);
/** Note that these are in order of priority. */
private final SystemShortcut[] mAllShortcuts;
diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java
index bab454f..4fd0f88 100644
--- a/src/com/android/launcher3/testing/TestInformationHandler.java
+++ b/src/com/android/launcher3/testing/TestInformationHandler.java
@@ -112,6 +112,13 @@
}
break;
}
+
+ case TestProtocol.REQUEST_ALLOCATED_MEMORY: {
+ final Runtime runtime = Runtime.getRuntime();
+ response.putLong(TestProtocol.TEST_INFO_RESPONSE_FIELD,
+ runtime.totalMemory() - runtime.freeMemory());
+ break;
+ }
}
return response;
}
diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java
index 9846a04..f9f5dc4 100644
--- a/src/com/android/launcher3/testing/TestProtocol.java
+++ b/src/com/android/launcher3/testing/TestProtocol.java
@@ -73,10 +73,12 @@
public static final String REQUEST_APP_LIST_FREEZE_FLAGS = "app-list-freeze-flags";
public static final String REQUEST_OVERVIEW_LEFT_GESTURE_MARGIN = "overview-left-margin";
public static final String REQUEST_OVERVIEW_RIGHT_GESTURE_MARGIN = "overview-right-margin";
+ public static final String REQUEST_ALLOCATED_MEMORY = "allocated-memory";
public static boolean sDebugTracing = false;
public static final String REQUEST_ENABLE_DEBUG_TRACING = "enable-debug-tracing";
public static final String REQUEST_DISABLE_DEBUG_TRACING = "disable-debug-tracing";
public static final String NO_BACKGROUND_TO_OVERVIEW_TAG = "b/138251824";
+ public static final String NO_DRAG_TO_WORKSPACE = "b/138729456";
}
diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
index 49f515a..c5ba5ba 100644
--- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
+++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
@@ -69,6 +69,7 @@
protected final SwipeDetector.Direction mSwipeDirection;
private boolean mNoIntercept;
+ private boolean mIsLogContainerSet;
protected int mStartContainerType;
protected LauncherState mStartState;
@@ -180,7 +181,7 @@
/**
* Returns the container that the touch started from when leaving NORMAL state.
*/
- protected abstract int getLogContainerTypeForNormalState();
+ protected abstract int getLogContainerTypeForNormalState(MotionEvent ev);
private boolean reinitCurrentAnimation(boolean reachedToState, boolean isDragTowardPositive) {
LauncherState newFromState = mFromState == null ? mLauncher.getStateManager().getState()
@@ -231,13 +232,7 @@
@Override
public void onDragStart(boolean start) {
mStartState = mLauncher.getStateManager().getState();
- if (mStartState == ALL_APPS) {
- mStartContainerType = LauncherLogProto.ContainerType.ALLAPPS;
- } else if (mStartState == NORMAL) {
- mStartContainerType = getLogContainerTypeForNormalState();
- } else if (mStartState == OVERVIEW){
- mStartContainerType = LauncherLogProto.ContainerType.TASKSWITCHER;
- }
+ mIsLogContainerSet = false;
if (mCurrentAnimation == null) {
mFromState = mStartState;
mToState = null;
@@ -285,6 +280,21 @@
return true;
}
+ @Override
+ public boolean onDrag(float displacement, MotionEvent ev) {
+ if (!mIsLogContainerSet) {
+ if (mStartState == ALL_APPS) {
+ mStartContainerType = LauncherLogProto.ContainerType.ALLAPPS;
+ } else if (mStartState == NORMAL) {
+ mStartContainerType = getLogContainerTypeForNormalState(ev);
+ } else if (mStartState == OVERVIEW) {
+ mStartContainerType = LauncherLogProto.ContainerType.TASKSWITCHER;
+ }
+ mIsLogContainerSet = true;
+ }
+ return onDrag(displacement);
+ }
+
protected void updateProgress(float fraction) {
mCurrentAnimation.setPlayFraction(fraction);
if (mAtomicComponentsController != null) {
@@ -518,6 +528,7 @@
logReachedState(logAction, targetState);
}
mLauncher.getStateManager().goToState(targetState, false /* animated */);
+ mLauncher.getDragLayer().getScrim().animateToSysuiMultiplier(1, 0, 0);
}
private void logReachedState(int logAction, LauncherState targetState) {
diff --git a/src/com/android/launcher3/touch/ItemClickHandler.java b/src/com/android/launcher3/touch/ItemClickHandler.java
index 2895a89..03493a5 100644
--- a/src/com/android/launcher3/touch/ItemClickHandler.java
+++ b/src/com/android/launcher3/touch/ItemClickHandler.java
@@ -25,9 +25,15 @@
import static com.android.launcher3.model.AppLaunchTracker.CONTAINER_ALL_APPS;
import android.app.AlertDialog;
+import android.content.ActivityNotFoundException;
+import android.content.Context;
import android.content.Intent;
+import android.content.pm.LauncherApps;
+import android.content.pm.PackageInstaller.SessionInfo;
import android.os.Process;
+import android.os.UserHandle;
import android.text.TextUtils;
+import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;
@@ -43,11 +49,12 @@
import com.android.launcher3.LauncherAppWidgetProviderInfo;
import com.android.launcher3.PromiseAppInfo;
import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
import com.android.launcher3.WorkspaceItemInfo;
import com.android.launcher3.compat.AppWidgetManagerCompat;
+import com.android.launcher3.compat.PackageInstallerCompat;
import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderIcon;
-import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.views.FloatingIconView;
import com.android.launcher3.widget.PendingAppWidgetHostView;
@@ -58,6 +65,8 @@
*/
public class ItemClickHandler {
+ private static final String TAG = ItemClickHandler.class.getSimpleName();
+
/**
* Instance used for click handling on items
*/
@@ -146,6 +155,8 @@
startMarketIntentForPackage(v, launcher, packageName);
return;
}
+ UserHandle user = v.getTag() instanceof ItemInfo
+ ? ((ItemInfo) v.getTag()).user : Process.myUserHandle();
new AlertDialog.Builder(launcher)
.setTitle(R.string.abandoned_promises_title)
.setMessage(R.string.abandoned_promise_explanation)
@@ -153,12 +164,28 @@
(d, i) -> startMarketIntentForPackage(v, launcher, packageName))
.setNeutralButton(R.string.abandoned_clean_this,
(d, i) -> launcher.getWorkspace()
- .removeAbandonedPromise(packageName, Process.myUserHandle()))
+ .removeAbandonedPromise(packageName, user))
.create().show();
}
private static void startMarketIntentForPackage(View v, Launcher launcher, String packageName) {
ItemInfo item = (ItemInfo) v.getTag();
+ if (Utilities.ATLEAST_Q) {
+ PackageInstallerCompat pkgInstaller = PackageInstallerCompat.getInstance(launcher);
+ SessionInfo sessionInfo = pkgInstaller.getActiveSessionInfo(item.user, packageName);
+ if (sessionInfo != null) {
+ LauncherApps launcherApps = launcher.getSystemService(LauncherApps.class);
+ try {
+ launcherApps.startPackageInstallerSessionDetailsActivity(sessionInfo, null,
+ launcher.getActivityLaunchOptionsAsBundle(v));
+ return;
+ } catch (Exception e) {
+ Log.e(TAG, "Unable to launch market intent for package=" + packageName, e);
+ }
+ }
+ }
+
+ // Fallback to using custom market intent.
Intent intent = new PackageManagerHelper(launcher).getMarketIntent(packageName);
launcher.startActivitySafely(v, intent, item, null);
}
diff --git a/src/com/android/launcher3/util/MainThreadInitializedObject.java b/src/com/android/launcher3/util/MainThreadInitializedObject.java
index 2ee0328..e185a31 100644
--- a/src/com/android/launcher3/util/MainThreadInitializedObject.java
+++ b/src/com/android/launcher3/util/MainThreadInitializedObject.java
@@ -18,12 +18,13 @@
import android.content.Context;
import android.os.Looper;
+import androidx.annotation.VisibleForTesting;
+
import com.android.launcher3.MainThreadExecutor;
+import com.android.launcher3.util.ResourceBasedOverride.Overrides;
import java.util.concurrent.ExecutionException;
-import androidx.annotation.VisibleForTesting;
-
/**
* Utility class for defining singletons which are initiated on main thread.
*/
@@ -60,6 +61,14 @@
mValue = value;
}
+ /**
+ * Initializes a provider based on resource overrides
+ */
+ public static <T extends ResourceBasedOverride> MainThreadInitializedObject<T> forOverride(
+ Class<T> clazz, int resourceId) {
+ return new MainThreadInitializedObject<>(c -> Overrides.getObject(clazz, c, resourceId));
+ }
+
public interface ObjectProvider<T> {
T get(Context context);
diff --git a/src/com/android/launcher3/util/PackageUserKey.java b/src/com/android/launcher3/util/PackageUserKey.java
index 1ce2822..e624517 100644
--- a/src/com/android/launcher3/util/PackageUserKey.java
+++ b/src/com/android/launcher3/util/PackageUserKey.java
@@ -38,7 +38,7 @@
* @return Whether this PackageUserKey was successfully updated - it shouldn't be used if not.
*/
public boolean updateFromItemInfo(ItemInfo info) {
- if (DeepShortcutManager.supportsShortcuts(info)) {
+ if (ShortcutUtil.supportsShortcuts(info)) {
update(info.getTargetComponent().getPackageName(), info.user);
return true;
}
diff --git a/src/com/android/launcher3/util/ShortcutUtil.java b/src/com/android/launcher3/util/ShortcutUtil.java
new file mode 100644
index 0000000..792d69f
--- /dev/null
+++ b/src/com/android/launcher3/util/ShortcutUtil.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.util;
+
+import com.android.launcher3.ItemInfo;
+import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.WorkspaceItemInfo;
+import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.shortcuts.ShortcutKey;
+
+public class ShortcutUtil {
+ public static boolean supportsShortcuts(ItemInfo info) {
+ return isActive(info) && (isApp(info) || isPinnedShortcut(info));
+ }
+
+ public static boolean supportsDeepShortcuts(ItemInfo info) {
+ return isActive(info) && isApp(info);
+ }
+
+ public static String getShortcutIdIfPinnedShortcut(ItemInfo info) {
+ return isActive(info) && isPinnedShortcut(info) ?
+ ShortcutKey.fromItemInfo(info).getId() : null;
+ }
+
+ public static String[] getPersonKeysIfPinnedShortcut(ItemInfo info) {
+ return isActive(info) && isPinnedShortcut(info) ?
+ ((WorkspaceItemInfo) info).getPersonKeys() : Utilities.EMPTY_STRING_ARRAY;
+ }
+
+ private static boolean isActive(ItemInfo info) {
+ boolean isLoading = info instanceof WorkspaceItemInfo
+ && ((WorkspaceItemInfo) info).hasPromiseIconUi();
+ return !isLoading && !info.isDisabled() && !FeatureFlags.GO_DISABLE_WIDGETS;
+ }
+
+ private static boolean isApp(ItemInfo info) {
+ return info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
+ }
+
+ private static boolean isPinnedShortcut(ItemInfo info) {
+ return info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT
+ && info.container != ItemInfo.NO_ID
+ && info instanceof WorkspaceItemInfo;
+ }
+}
\ No newline at end of file
diff --git a/src_shortcuts_overrides/com/android/launcher3/shortcuts/DeepShortcutManager.java b/src_shortcuts_overrides/com/android/launcher3/shortcuts/DeepShortcutManager.java
index 6b6f70d..7119aea 100644
--- a/src_shortcuts_overrides/com/android/launcher3/shortcuts/DeepShortcutManager.java
+++ b/src_shortcuts_overrides/com/android/launcher3/shortcuts/DeepShortcutManager.java
@@ -27,10 +27,6 @@
import android.os.UserHandle;
import android.util.Log;
-import com.android.launcher3.ItemInfo;
-import com.android.launcher3.LauncherSettings;
-import com.android.launcher3.WorkspaceItemInfo;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -63,13 +59,6 @@
mLauncherApps = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE);
}
- public static boolean supportsShortcuts(ItemInfo info) {
- boolean isItemPromise = info instanceof WorkspaceItemInfo
- && ((WorkspaceItemInfo) info).hasPromiseIconUi();
- return info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION
- && !info.isDisabled() && !isItemPromise;
- }
-
public boolean wasLastCallSuccess() {
return mWasLastCallSuccess;
}
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/AllAppsSwipeController.java b/src_ui_overrides/com/android/launcher3/uioverrides/AllAppsSwipeController.java
index e9dc800..bd6ea50 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/AllAppsSwipeController.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/AllAppsSwipeController.java
@@ -57,7 +57,7 @@
}
@Override
- protected int getLogContainerTypeForNormalState() {
+ protected int getLogContainerTypeForNormalState(MotionEvent ev) {
return mLauncher.getDragLayer().isEventOverView(mLauncher.getHotseat(), mTouchDownEvent) ?
ContainerType.HOTSEAT : ContainerType.WORKSPACE;
}
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
index 5cc64dc..467ae02 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
@@ -17,9 +17,11 @@
package com.android.launcher3.uioverrides;
import android.app.Activity;
+import android.app.Person;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
+import android.content.pm.ShortcutInfo;
import android.os.Bundle;
import android.os.CancellationSignal;
@@ -27,6 +29,7 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState.ScaleAndTranslation;
import com.android.launcher3.LauncherStateManager.StateHandler;
+import com.android.launcher3.Utilities;
import com.android.launcher3.graphics.RotationMode;
import com.android.launcher3.util.TouchController;
@@ -95,4 +98,7 @@
public static void clearSwipeSharedState(boolean finishAnimation) {}
+ public static Person[] getPersons(ShortcutInfo si) {
+ return Utilities.EMPTY_PERSON_ARRAY;
+ }
}
diff --git a/tests/AndroidManifest-common.xml b/tests/AndroidManifest-common.xml
index 61c7306..c6f55a7 100644
--- a/tests/AndroidManifest-common.xml
+++ b/tests/AndroidManifest-common.xml
@@ -20,6 +20,9 @@
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>
+ <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
+ <uses-permission android:name="android.permission.READ_LOGS"/>
+
<application android:debuggable="true">
<uses-library android:name="android.test.runner"/>
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 8dc8cea..fc19baa 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -38,6 +38,7 @@
import androidx.test.InstrumentationRegistry;
import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.BySelector;
import androidx.test.uiautomator.UiDevice;
import androidx.test.uiautomator.Until;
@@ -330,30 +331,27 @@
}
protected void startAppFast(String packageName) {
- final Instrumentation instrumentation = getInstrumentation();
- final Intent intent = instrumentation.getContext().getPackageManager().
- getLaunchIntentForPackage(packageName);
- intent.addCategory(Intent.CATEGORY_LAUNCHER);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- instrumentation.getTargetContext().startActivity(intent);
- assertTrue(packageName + " didn't start",
- mDevice.wait(Until.hasObject(By.pkg(packageName).depth(0)), DEFAULT_UI_TIMEOUT));
+ startIntent(
+ getInstrumentation().getContext().getPackageManager().getLaunchIntentForPackage(
+ packageName),
+ By.pkg(packageName).depth(0));
}
protected void startTestActivity(int activityNumber) {
final String packageName = getAppPackageName();
- final Instrumentation instrumentation = getInstrumentation();
- final Intent intent = instrumentation.getContext().getPackageManager().
+ final Intent intent = getInstrumentation().getContext().getPackageManager().
getLaunchIntentForPackage(packageName);
- intent.addCategory(Intent.CATEGORY_LAUNCHER);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setComponent(new ComponentName(packageName,
"com.android.launcher3.tests.Activity" + activityNumber));
- instrumentation.getTargetContext().startActivity(intent);
- assertTrue(packageName + " didn't start",
- mDevice.wait(
- Until.hasObject(By.pkg(packageName).text("TestActivity" + activityNumber)),
- DEFAULT_UI_TIMEOUT));
+ startIntent(intent, By.pkg(packageName).text("TestActivity" + activityNumber));
+ }
+
+ private void startIntent(Intent intent, BySelector selector) {
+ intent.addCategory(Intent.CATEGORY_LAUNCHER);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ getInstrumentation().getTargetContext().startActivity(intent);
+ assertTrue("App didn't start: " + selector,
+ mDevice.wait(Until.hasObject(selector), DEFAULT_UI_TIMEOUT));
}
public static String resolveSystemApp(String category) {
diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
index 4dab44f..0c87ab9 100644
--- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
+++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
@@ -173,6 +173,7 @@
@Test
public void testWorkspace() throws Exception {
+ mLauncher.enableDebugTracing();
final Workspace workspace = mLauncher.getWorkspace();
// Test that ensureWorkspaceIsScrollable adds a page by dragging an icon there.
@@ -190,7 +191,7 @@
launcher -> assertTrue("ensureScrollable didn't make workspace scrollable",
isWorkspaceScrollable(launcher)));
assertNotNull("ensureScrollable didn't add Chrome app",
- workspace.tryGetWorkspaceAppIcon("Chrome"));
+ workspace.getWorkspaceAppIcon("Chrome"));
// Test flinging workspace.
workspace.flingBackward();
@@ -206,8 +207,9 @@
assertTrue("Launcher internal state is not Home", isInState(LauncherState.NORMAL));
// Test starting a workspace app.
- final AppIcon app = workspace.tryGetWorkspaceAppIcon("Chrome");
+ final AppIcon app = workspace.getWorkspaceAppIcon("Chrome");
assertNotNull("No Chrome app in workspace", app);
+ mLauncher.disableDebugTracing();
}
public static void runIconLaunchFromAllAppsTest(AbstractLauncherUiTest test, AllApps allApps) {
@@ -298,6 +300,7 @@
@Test
@PortraitLandscape
public void testDragAppIcon() throws Throwable {
+ mLauncher.enableDebugTracing();
// 1. Open all apps and wait for load complete.
// 2. Drag icon to homescreen.
// 3. Verify that the icon works on homescreen.
@@ -314,11 +317,13 @@
"Launcher activity is the top activity; expecting another activity to be the top "
+ "one",
isInBackground(launcher)));
+ mLauncher.disableDebugTracing();
}
@Test
@PortraitLandscape
public void testDragShortcut() throws Throwable {
+ mLauncher.enableDebugTracing();
// 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
@@ -338,6 +343,7 @@
} finally {
allApps.unfreeze();
}
+ mLauncher.disableDebugTracing();
}
public static String getAppPackageName() {
diff --git a/tests/src/com/android/launcher3/util/Wait.java b/tests/src/com/android/launcher3/util/Wait.java
index 593cce8..899686b 100644
--- a/tests/src/com/android/launcher3/util/Wait.java
+++ b/tests/src/com/android/launcher3/util/Wait.java
@@ -1,6 +1,7 @@
package com.android.launcher3.util;
import android.os.SystemClock;
+import android.util.Log;
import org.junit.Assert;
@@ -16,7 +17,9 @@
}
public static void atMost(String message, Condition condition, long timeout, long sleepMillis) {
- long endTime = SystemClock.uptimeMillis() + timeout;
+ final long startTime = SystemClock.uptimeMillis();
+ long endTime = startTime + timeout;
+ Log.d("Wait", "atMost: " + startTime + " - " + endTime);
while (SystemClock.uptimeMillis() < endTime) {
try {
if (condition.isTrue()) {
@@ -36,6 +39,7 @@
} catch (Throwable t) {
throw new RuntimeException(t);
}
+ Log.d("Wait", "atMost: timed out: " + SystemClock.uptimeMillis());
Assert.fail(message);
}
}
diff --git a/tests/src/com/android/launcher3/util/rule/FailureWatcher.java b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
index eef2f24..e7a2bca 100644
--- a/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
+++ b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
@@ -15,7 +15,6 @@
public class FailureWatcher extends TestWatcher {
private static final String TAG = "FailureWatcher";
- private static int sScreenshotCount = 0;
final private UiDevice mDevice;
public FailureWatcher(UiDevice device) {
@@ -40,7 +39,8 @@
protected void failed(Throwable e, Description description) {
if (mDevice == null) return;
final String pathname = getInstrumentation().getTargetContext().
- getFilesDir().getPath() + "/TaplTestScreenshot" + sScreenshotCount++ + ".png";
+ getFilesDir().getPath() + "/TestScreenshot-" + description.getMethodName()
+ + ".png";
Log.e(TAG, "Failed test " + description.getMethodName() +
", screenshot will be saved to " + pathname +
", track trace is below, UI object dump is further below:\n" +
diff --git a/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java b/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java
index 2042403..62fe26d 100644
--- a/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java
+++ b/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java
@@ -19,6 +19,7 @@
import android.app.Application;
import android.app.Application.ActivityLifecycleCallbacks;
import android.os.Bundle;
+
import androidx.test.InstrumentationRegistry;
import com.android.launcher3.Launcher;
@@ -84,19 +85,27 @@
}
@Override
- public void onActivityStarted(Activity activity) { }
+ public void onActivityStarted(Activity activity) {
+ if (activity instanceof Launcher) {
+ mActivity.getRotationHelper().forceAllowRotationForTesting(true);
+ }
+ }
@Override
- public void onActivityResumed(Activity activity) { }
+ public void onActivityResumed(Activity activity) {
+ }
@Override
- public void onActivityPaused(Activity activity) { }
+ public void onActivityPaused(Activity activity) {
+ }
@Override
- public void onActivityStopped(Activity activity) { }
+ public void onActivityStopped(Activity activity) {
+ }
@Override
- public void onActivitySaveInstanceState(Activity activity, Bundle bundle) { }
+ public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
+ }
@Override
public void onActivityDestroyed(Activity activity) {
diff --git a/tests/tapl/com/android/launcher3/tapl/AllApps.java b/tests/tapl/com/android/launcher3/tapl/AllApps.java
index 9ff354a..f070280 100644
--- a/tests/tapl/com/android/launcher3/tapl/AllApps.java
+++ b/tests/tapl/com/android/launcher3/tapl/AllApps.java
@@ -120,7 +120,7 @@
mLauncher.assertTrue("Unable to scroll to a clickable icon: " + appName,
hasClickableIcon(allAppsContainer, appListRecycler, appIconSelector));
- final UiObject2 appIcon = mLauncher.getObjectInContainer(appListRecycler,
+ final UiObject2 appIcon = mLauncher.waitForObjectInContainer(appListRecycler,
appIconSelector);
return new AppIcon(mLauncher, appIcon);
}
diff --git a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
index bbd2c29..25e6e8c 100644
--- a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
+++ b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
@@ -74,7 +74,7 @@
flingForward();
}
- mLauncher.getObjectInContainer(verifyActiveContainer(), clearAllSelector).click();
+ mLauncher.waitForObjectInContainer(verifyActiveContainer(), clearAllSelector).click();
try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
"dismissed all tasks")) {
return new Workspace(mLauncher);
diff --git a/tests/tapl/com/android/launcher3/tapl/Launchable.java b/tests/tapl/com/android/launcher3/tapl/Launchable.java
index 82af7b0..df80a51 100644
--- a/tests/tapl/com/android/launcher3/tapl/Launchable.java
+++ b/tests/tapl/com/android/launcher3/tapl/Launchable.java
@@ -16,6 +16,8 @@
package com.android.launcher3.tapl;
+import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
+
import android.graphics.Point;
import androidx.test.uiautomator.By;
@@ -23,13 +25,10 @@
import androidx.test.uiautomator.UiObject2;
import androidx.test.uiautomator.Until;
-import com.android.launcher3.testing.TestProtocol;
-
/**
* Ancestor for AppIcon and AppMenuItem.
*/
abstract class Launchable {
- private static final int WAIT_TIME_MS = 60000;
protected final LauncherInstrumentation mLauncher;
protected final UiObject2 mObject;
@@ -53,9 +52,12 @@
private Background launch(BySelector selector) {
LauncherInstrumentation.log("Launchable.launch before click " +
mObject.getVisibleCenter() + " in " + mObject.getVisibleBounds());
- mLauncher.assertTrue(
- "Launching an app didn't open a new window: " + mObject.getText(),
- mObject.clickAndWait(Until.newWindow(), WAIT_TIME_MS));
+
+ mLauncher.executeAndWaitForEvent(
+ () -> mObject.click(),
+ event -> event.getEventType() == TYPE_WINDOW_STATE_CHANGED,
+ "Launching an app didn't open a new window: " + mObject.getText());
+
mLauncher.assertTrue(
"App didn't start: " + selector,
mLauncher.getDevice().wait(Until.hasObject(selector),
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index fe7401c..34879a9 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -124,7 +124,7 @@
private static final String APPS_RES_ID = "apps_view";
private static final String OVERVIEW_RES_ID = "overview_panel";
private static final String WIDGETS_RES_ID = "widgets_list_view";
- public static final int WAIT_TIME_MS = 60000;
+ public static final int WAIT_TIME_MS = 10000;
private static final String SYSTEMUI_PACKAGE = "com.android.systemui";
private static WeakReference<VisibleContainer> sActiveContainer = new WeakReference<>(null);
@@ -178,6 +178,7 @@
PackageManager pm = getContext().getPackageManager();
ProviderInfo pi = pm.resolveContentProvider(
testProviderAuthority, MATCH_ALL | MATCH_DISABLED_COMPONENTS);
+ assertNotNull("Cannot find content provider for " + testProviderAuthority, pi);
ComponentName cn = new ComponentName(pi.packageName, pi.name);
if (pm.getComponentEnabledSetting(cn) != COMPONENT_ENABLED_STATE_ENABLED) {
@@ -678,13 +679,6 @@
}
@NonNull
- UiObject2 getObjectInContainer(UiObject2 container, BySelector selector) {
- final UiObject2 object = container.findObject(selector);
- assertNotNull("Can't find an object with selector: " + selector, object);
- return object;
- }
-
- @NonNull
List<UiObject2> getObjectsInContainer(UiObject2 container, String resName) {
return container.findObjects(getLauncherObjectSelector(resName));
}
@@ -962,4 +956,9 @@
public void disableDebugTracing() {
getTestInfo(TestProtocol.REQUEST_DISABLE_DEBUG_TRACING);
}
+
+ public long getAllocatedMemory() {
+ return getTestInfo(TestProtocol.REQUEST_ALLOCATED_MEMORY).
+ getLong(TestProtocol.TEST_INFO_RESPONSE_FIELD);
+ }
}
\ No newline at end of file
diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
index 6e33322..91f0fc4 100644
--- a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
+++ b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
@@ -16,18 +16,16 @@
package com.android.launcher3.tapl;
+import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
+
import android.graphics.Rect;
import androidx.test.uiautomator.UiObject2;
-import androidx.test.uiautomator.Until;
-
-import com.android.launcher3.testing.TestProtocol;
/**
* A recent task in the overview panel carousel.
*/
public final class OverviewTask {
- private static final long WAIT_TIME_MS = 60000;
private final LauncherInstrumentation mLauncher;
private final UiObject2 mTask;
private final BaseOverview mOverview;
@@ -66,9 +64,11 @@
verifyActiveContainer();
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"clicking an overview task")) {
- mLauncher.assertTrue("Launching task didn't open a new window: " +
- mTask.getParent().getContentDescription(),
- mTask.clickAndWait(Until.newWindow(), WAIT_TIME_MS));
+ mLauncher.executeAndWaitForEvent(
+ () -> mTask.click(),
+ event -> event.getEventType() == TYPE_WINDOW_STATE_CHANGED,
+ "Launching task didn't open a new window: " +
+ mTask.getParent().getContentDescription());
}
return new Background(mLauncher);
}
diff --git a/tests/tapl/com/android/launcher3/tapl/TestHelpers.java b/tests/tapl/com/android/launcher3/tapl/TestHelpers.java
index 399c59d..a089a52 100644
--- a/tests/tapl/com/android/launcher3/tapl/TestHelpers.java
+++ b/tests/tapl/com/android/launcher3/tapl/TestHelpers.java
@@ -109,7 +109,7 @@
DropBoxManager.Entry entry;
StringBuilder errorDetails = new StringBuilder();
while (null != (entry = dropbox.getNextEntry(label, timestamp))) {
- if (errorDetails.length() != 0) errorDetails.append("------------------------------");
+ errorDetails.append("------------------------------\n");
timestamp = entry.getTimeMillis();
errorDetails.append(new Date(timestamp));
errorDetails.append(": ");
diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java
index 07f8b64..639902f 100644
--- a/tests/tapl/com/android/launcher3/tapl/Workspace.java
+++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java
@@ -108,10 +108,13 @@
*/
@NonNull
public AppIcon getWorkspaceAppIcon(String appName) {
- return new AppIcon(mLauncher,
- mLauncher.getObjectInContainer(
- verifyActiveContainer(),
- AppIcon.getAppIconSelector(appName, mLauncher)));
+ try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "want to get a workspace icon")) {
+ return new AppIcon(mLauncher,
+ mLauncher.waitForObjectInContainer(
+ verifyActiveContainer(),
+ AppIcon.getAppIconSelector(appName, mLauncher)));
+ }
}
/**
@@ -142,13 +145,13 @@
@NonNull
public AppIcon getHotseatAppIcon(String appName) {
- return new AppIcon(mLauncher, mLauncher.getObjectInContainer(
+ return new AppIcon(mLauncher, mLauncher.waitForObjectInContainer(
mHotseat, AppIcon.getAppIconSelector(appName, mLauncher)));
}
@NonNull
public Folder getHotseatFolder(String appName) {
- return new Folder(mLauncher, mLauncher.getObjectInContainer(
+ return new Folder(mLauncher, mLauncher.waitForObjectInContainer(
mHotseat, Folder.getSelector(appName, mLauncher)));
}