Merge "Fixing some Launcher crashes because of using old model data even after launcher has reloaded" into ub-launcher3-master
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java
index 50cc4da..81ff0c7 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java
@@ -62,7 +62,6 @@
if (swipeUpToHome) {
list.add(new FlingAndHoldTouchController(launcher));
- list.add(new OverviewToAllAppsTouchController(launcher));
} else {
if (launcher.getDeviceProfile().isVerticalBarLayout()) {
list.add(new OverviewToAllAppsTouchController(launcher));
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/AssistantTouchConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/AssistantTouchConsumer.java
index e02c696..109a4c5 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/AssistantTouchConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/AssistantTouchConsumer.java
@@ -78,6 +78,11 @@
}
@Override
+ public int getType() {
+ return TYPE_ASSISTANT;
+ }
+
+ @Override
public void onMotionEvent(MotionEvent ev) {
// TODO add logging
switch (ev.getActionMasked()) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/DeviceLockedInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/DeviceLockedInputConsumer.java
index 047f34c..d919a3e 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/DeviceLockedInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/DeviceLockedInputConsumer.java
@@ -31,6 +31,11 @@
}
@Override
+ public int getType() {
+ return TYPE_DEVICE_LOCKED;
+ }
+
+ @Override
public void onMotionEvent(MotionEvent ev) {
// For now, just start the home intent so user is prompted to unlock the device.
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/InputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/InputConsumer.java
index 8dfb9ab..ad9fe78 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/InputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/InputConsumer.java
@@ -23,7 +23,16 @@
@TargetApi(Build.VERSION_CODES.O)
public interface InputConsumer {
- InputConsumer NO_OP = new InputConsumer() { };
+
+ int TYPE_NO_OP = 0;
+ int TYPE_OVERVIEW = 1;
+ int TYPE_OTHER_ACTIVITY = 2;
+ int TYPE_ASSISTANT = 3;
+ int TYPE_DEVICE_LOCKED = 4;
+
+ InputConsumer NO_OP = () -> TYPE_NO_OP;
+
+ int getType();
default boolean isActive() {
return false;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java
index 67bfeaa..e3afb92 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java
@@ -148,6 +148,11 @@
}
@Override
+ public int getType() {
+ return TYPE_OTHER_ACTIVITY;
+ }
+
+ @Override
public void onMotionEvent(MotionEvent ev) {
if (mVelocityTracker == null) {
return;
@@ -225,7 +230,7 @@
mTouchSlop) {
mPassedTouchSlop = true;
- TOUCH_INTERACTION_LOG.startQuickStep();
+ TOUCH_INTERACTION_LOG.addLog("startQuickstep");
if (mIsDeferredDownTarget) {
// Deferred gesture, start the animation and gesture tracking once
// we pass the actual touch slop
@@ -288,7 +293,7 @@
}
private void startTouchTrackingForWindowAnimation(long touchTimeMs) {
- TOUCH_INTERACTION_LOG.startRecentsAnimation();
+ TOUCH_INTERACTION_LOG.addLog("startRecentsAnimation");
RecentsAnimationListenerSet listenerSet = mSwipeSharedState.getActiveListener();
final WindowTransformSwipeHandler handler = new WindowTransformSwipeHandler(
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewInputConsumer.java
index 28c4db4..cce5cb3 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewInputConsumer.java
@@ -60,6 +60,11 @@
}
@Override
+ public int getType() {
+ return TYPE_OVERVIEW;
+ }
+
+ @Override
public void onMotionEvent(MotionEvent ev) {
if (mInvalidated) {
return;
@@ -120,7 +125,7 @@
OverviewCallbacks.get(mActivity).closeAllWindows();
ActivityManagerWrapper.getInstance()
.closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
- TOUCH_INTERACTION_LOG.startQuickStep();
+ TOUCH_INTERACTION_LOG.addLog("startQuickstep");
}
mTrackingStarted = true;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionLog.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionLog.java
deleted file mode 100644
index 4b660d4..0000000
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionLog.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.quickstep;
-
-import android.view.MotionEvent;
-import java.io.PrintWriter;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.LinkedList;
-
-/**
- * Keeps track of debugging logs for a particular quickstep gesture.
- */
-public class TouchInteractionLog {
-
- // The number of gestures to log
- private static final int MAX_NUM_LOG_GESTURES = 5;
-
- private final Calendar mCalendar = Calendar.getInstance();
- private final SimpleDateFormat mDateFormat = new SimpleDateFormat("MMM dd - kk:mm:ss:SSS");
- private final LinkedList<ArrayList<String>> mGestureLogs = new LinkedList<>();
-
- public void prepareForNewGesture() {
- mGestureLogs.add(new ArrayList<>());
- while (mGestureLogs.size() > MAX_NUM_LOG_GESTURES) {
- mGestureLogs.pop();
- }
- getCurrentLog().add("[" + mDateFormat.format(mCalendar.getTime()) + "]");
- }
-
- public void setInputConsumer(InputConsumer consumer) {
- getCurrentLog().add("tc=" + consumer.getClass().getSimpleName());
- }
-
- public void addMotionEvent(MotionEvent event) {
- getCurrentLog().add("ev=" + event.getActionMasked());
- }
-
- public void startQuickStep() {
- getCurrentLog().add("qstStart");
- }
-
- public void startRecentsAnimation() {
- getCurrentLog().add("raStart");
- }
-
- public void startRecentsAnimationCallback(int numTargets) {
- getCurrentLog().add("raStartCb=" + numTargets);
- }
-
- public void cancelRecentsAnimation() {
- getCurrentLog().add("raCancel");
- }
-
- public void finishRecentsAnimation(boolean toHome) {
- getCurrentLog().add("raFinish=" + toHome);
- }
-
- public void dump(PrintWriter pw) {
- pw.println("TouchInteractionLog {");
- for (ArrayList<String> gesture : mGestureLogs) {
- pw.print(" ");
- for (String log : gesture) {
- pw.print(log + " ");
- }
- pw.println();
- }
- pw.println("}");
- }
-
- private ArrayList<String> getCurrentLog() {
- return mGestureLogs.getLast();
- }
-}
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 d1d0e86..a3c3ff9 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
@@ -45,6 +45,7 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.logging.EventLogArray;
import com.android.launcher3.util.LooperExecutor;
import com.android.launcher3.util.UiThreadHelper;
import com.android.systemui.shared.recents.IOverviewProxy;
@@ -70,7 +71,8 @@
public static final LooperExecutor BACKGROUND_EXECUTOR =
new LooperExecutor(UiThreadHelper.getBackgroundLooper());
- public static final TouchInteractionLog TOUCH_INTERACTION_LOG = new TouchInteractionLog();
+ public static final EventLogArray TOUCH_INTERACTION_LOG =
+ new EventLogArray("touch_interaction_log", 40);
public static final int EDGE_NAV_BAR = 1 << 8;
@@ -281,15 +283,13 @@
return;
}
MotionEvent event = (MotionEvent) ev;
+ TOUCH_INTERACTION_LOG.addLog("onMotionEvent", event.getActionMasked());
if (event.getAction() == ACTION_DOWN) {
- TOUCH_INTERACTION_LOG.prepareForNewGesture();
boolean useSharedState = mConsumer.isActive();
mConsumer.onConsumerAboutToBeSwitched();
mConsumer = newConsumer(useSharedState, event);
- TOUCH_INTERACTION_LOG.setInputConsumer(mConsumer);
+ TOUCH_INTERACTION_LOG.addLog("setInputConsumer", mConsumer.getType());
}
- TOUCH_INTERACTION_LOG.addMotionEvent(event);
-
mConsumer.onMotionEvent(event);
}
@@ -342,6 +342,6 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- TOUCH_INTERACTION_LOG.dump(pw);
+ TOUCH_INTERACTION_LOG.dump("", pw);
}
}
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 fa827e7..7dc58a5 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -671,7 +671,7 @@
initTransitionEndpoints(dp);
mRecentsAnimationWrapper.setController(targetSet);
- TOUCH_INTERACTION_LOG.startRecentsAnimationCallback(targetSet.apps.length);
+ TOUCH_INTERACTION_LOG.addLog("startRecentsAnimationCallback", targetSet.apps.length);
setStateOnUiThread(STATE_APP_CONTROLLER_RECEIVED);
mPassedOverviewThreshold = false;
@@ -682,7 +682,7 @@
mRecentsAnimationWrapper.setController(null);
mActivityInitListener.unregister();
setStateOnUiThread(STATE_GESTURE_CANCELLED | STATE_HANDLER_INVALIDATED);
- TOUCH_INTERACTION_LOG.cancelRecentsAnimation();
+ TOUCH_INTERACTION_LOG.addLog("cancelRecentsAnimation");
}
@UiThread
@@ -1025,7 +1025,7 @@
@UiThread
private void resumeLastTask() {
mRecentsAnimationWrapper.finish(false /* toRecents */, null);
- TOUCH_INTERACTION_LOG.finishRecentsAnimation(false);
+ TOUCH_INTERACTION_LOG.addLog("finishRecentsAnimation", false);
}
@UiThread
@@ -1043,7 +1043,7 @@
mMainThreadHandler);
});
}
- TOUCH_INTERACTION_LOG.finishRecentsAnimation(false);
+ TOUCH_INTERACTION_LOG.addLog("finishRecentsAnimation", false);
doLogGesture(NEW_TASK);
}
@@ -1152,7 +1152,7 @@
() -> setStateOnUiThread(STATE_CURRENT_TASK_FINISHED));
}
}
- TOUCH_INTERACTION_LOG.finishRecentsAnimation(true);
+ TOUCH_INTERACTION_LOG.addLog("finishRecentsAnimation", true);
}
private void finishCurrentTransitionToHome() {
@@ -1160,7 +1160,7 @@
mRecentsAnimationWrapper.finish(true /* toRecents */,
() -> setStateOnUiThread(STATE_CURRENT_TASK_FINISHED));
}
- TOUCH_INTERACTION_LOG.finishRecentsAnimation(true);
+ TOUCH_INTERACTION_LOG.addLog("finishRecentsAnimation", true);
doLogGesture(HOME);
}
diff --git a/res/drawable/horizontal_ellipsis.xml b/res/drawable/horizontal_ellipsis.xml
index ad08529..65e958d 100644
--- a/res/drawable/horizontal_ellipsis.xml
+++ b/res/drawable/horizontal_ellipsis.xml
@@ -22,6 +22,6 @@
android:tint="?android:attr/textColorSecondary" >
<path
- android:pathData="M6 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"
+ android:pathData="M6 10c-1.1 0-2 0.9-2 2s0.9 2 2 2 2-0.9 2-2-0.9-2-2-2zm12 0c-1.1 0-2 0.9-2 2s0.9 2 2 2 2-0.9 2-2-0.9-2-2-2zm-6 0c-1.1 0-2 0.9-2 2s0.9 2 2 2 2-0.9 2-2-0.9-2-2-2z"
android:fillColor="@android:color/white" />
</vector>
\ No newline at end of file
diff --git a/src/com/android/launcher3/AutoInstallsLayout.java b/src/com/android/launcher3/AutoInstallsLayout.java
index e5b1448..62bc53a 100644
--- a/src/com/android/launcher3/AutoInstallsLayout.java
+++ b/src/com/android/launcher3/AutoInstallsLayout.java
@@ -24,7 +24,6 @@
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
-import android.content.res.XmlResourceParser;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.drawable.Drawable;
import android.net.Uri;
@@ -33,9 +32,11 @@
import android.os.Process;
import android.text.TextUtils;
import android.util.ArrayMap;
+import android.util.AttributeSet;
import android.util.Log;
import android.util.Pair;
import android.util.Patterns;
+import android.util.Xml;
import com.android.launcher3.LauncherProvider.SqlArguments;
import com.android.launcher3.LauncherSettings.Favorites;
@@ -149,9 +150,6 @@
private static final String HOTSEAT_CONTAINER_NAME =
Favorites.containerToString(Favorites.CONTAINER_HOTSEAT);
- private static final String ACTION_APPWIDGET_DEFAULT_WORKSPACE_CONFIGURE =
- "com.android.launcher.action.APPWIDGET_DEFAULT_WORKSPACE_CONFIGURE";
-
@Thunk final Context mContext;
@Thunk final AppWidgetHost mAppWidgetHost;
protected final LayoutParserCallback mCallback;
@@ -207,7 +205,7 @@
*/
protected int parseLayout(int layoutId, IntArray screenIds)
throws XmlPullParserException, IOException {
- XmlResourceParser parser = mSourceRes.getXml(layoutId);
+ XmlPullParser parser = mSourceRes.getXml(layoutId);
beginDocument(parser, mRootTag);
final int depth = parser.getDepth();
int type;
@@ -228,7 +226,7 @@
* Parses container and screenId attribute from the current tag, and puts it in the out.
* @param out array of size 2.
*/
- protected void parseContainerAndScreen(XmlResourceParser parser, int[] out) {
+ protected void parseContainerAndScreen(XmlPullParser parser, int[] out) {
if (HOTSEAT_CONTAINER_NAME.equals(getAttributeValue(parser, ATTR_CONTAINER))) {
out[0] = Favorites.CONTAINER_HOTSEAT;
// Hack: hotseat items are stored using screen ids
@@ -243,7 +241,7 @@
* Parses the current node and returns the number of elements added.
*/
protected int parseAndAddNode(
- XmlResourceParser parser, ArrayMap<String, TagParser> tagParserMap, IntArray screenIds)
+ XmlPullParser parser, ArrayMap<String, TagParser> tagParserMap, IntArray screenIds)
throws XmlPullParserException, IOException {
if (TAG_INCLUDE.equals(parser.getName())) {
@@ -324,7 +322,7 @@
* Parses the tag and adds to the db
* @return the id of the row added or -1;
*/
- int parseAndAdd(XmlResourceParser parser)
+ int parseAndAdd(XmlPullParser parser)
throws XmlPullParserException, IOException;
}
@@ -334,7 +332,7 @@
protected class AppShortcutParser implements TagParser {
@Override
- public int parseAndAdd(XmlResourceParser parser) {
+ public int parseAndAdd(XmlPullParser parser) {
final String packageName = getAttributeValue(parser, ATTR_PACKAGE_NAME);
final String className = getAttributeValue(parser, ATTR_CLASS_NAME);
@@ -371,7 +369,7 @@
/**
* Helper method to allow extending the parser capabilities
*/
- protected int invalidPackageOrClass(XmlResourceParser parser) {
+ protected int invalidPackageOrClass(XmlPullParser parser) {
Log.w(TAG, "Skipping invalid <favorite> with no component");
return -1;
}
@@ -383,7 +381,7 @@
protected class AutoInstallParser implements TagParser {
@Override
- public int parseAndAdd(XmlResourceParser parser) {
+ public int parseAndAdd(XmlPullParser parser) {
final String packageName = getAttributeValue(parser, ATTR_PACKAGE_NAME);
final String className = getAttributeValue(parser, ATTR_CLASS_NAME);
if (TextUtils.isEmpty(packageName) || TextUtils.isEmpty(className)) {
@@ -414,7 +412,7 @@
}
@Override
- public int parseAndAdd(XmlResourceParser parser) {
+ public int parseAndAdd(XmlPullParser parser) {
final int titleResId = getAttributeResourceValue(parser, ATTR_TITLE, 0);
final int iconId = getAttributeResourceValue(parser, ATTR_ICON, 0);
@@ -449,7 +447,7 @@
intent, Favorites.ITEM_TYPE_SHORTCUT);
}
- protected Intent parseIntent(XmlResourceParser parser) {
+ protected Intent parseIntent(XmlPullParser parser) {
final String url = getAttributeValue(parser, ATTR_URL);
if (TextUtils.isEmpty(url) || !Patterns.WEB_URL.matcher(url).matches()) {
if (LOGD) Log.d(TAG, "Ignoring shortcut, invalid url: " + url);
@@ -470,7 +468,7 @@
protected class PendingWidgetParser implements TagParser {
@Override
- public int parseAndAdd(XmlResourceParser parser)
+ public int parseAndAdd(XmlPullParser parser)
throws XmlPullParserException, IOException {
final String packageName = getAttributeValue(parser, ATTR_PACKAGE_NAME);
final String className = getAttributeValue(parser, ATTR_CLASS_NAME);
@@ -541,7 +539,7 @@
}
@Override
- public int parseAndAdd(XmlResourceParser parser)
+ public int parseAndAdd(XmlPullParser parser)
throws XmlPullParserException, IOException {
final String title;
final int titleResId = getAttributeResourceValue(parser, ATTR_TITLE, 0);
@@ -649,7 +647,7 @@
* Return attribute value, attempting launcher-specific namespace first
* before falling back to anonymous attribute.
*/
- protected static String getAttributeValue(XmlResourceParser parser, String attribute) {
+ protected static String getAttributeValue(XmlPullParser parser, String attribute) {
String value = parser.getAttributeValue(
"http://schemas.android.com/apk/res-auto/com.android.launcher3", attribute);
if (value == null) {
@@ -662,13 +660,14 @@
* Return attribute resource value, attempting launcher-specific namespace
* first before falling back to anonymous attribute.
*/
- protected static int getAttributeResourceValue(XmlResourceParser parser, String attribute,
+ protected static int getAttributeResourceValue(XmlPullParser parser, String attribute,
int defaultValue) {
- int value = parser.getAttributeResourceValue(
+ AttributeSet attrs = Xml.asAttributeSet(parser);
+ int value = attrs.getAttributeResourceValue(
"http://schemas.android.com/apk/res-auto/com.android.launcher3", attribute,
defaultValue);
if (value == defaultValue) {
- value = parser.getAttributeResourceValue(null, attribute, defaultValue);
+ value = attrs.getAttributeResourceValue(null, attribute, defaultValue);
}
return value;
}
diff --git a/src/com/android/launcher3/DefaultLayoutParser.java b/src/com/android/launcher3/DefaultLayoutParser.java
index 44830e8..75297f6 100644
--- a/src/com/android/launcher3/DefaultLayoutParser.java
+++ b/src/com/android/launcher3/DefaultLayoutParser.java
@@ -10,7 +10,6 @@
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
-import android.content.res.XmlResourceParser;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -76,7 +75,7 @@
}
@Override
- protected void parseContainerAndScreen(XmlResourceParser parser, int[] out) {
+ protected void parseContainerAndScreen(XmlPullParser parser, int[] out) {
out[0] = LauncherSettings.Favorites.CONTAINER_DESKTOP;
String strContainer = getAttributeValue(parser, ATTR_CONTAINER);
if (strContainer != null) {
@@ -91,7 +90,7 @@
public class AppShortcutWithUriParser extends AppShortcutParser {
@Override
- protected int invalidPackageOrClass(XmlResourceParser parser) {
+ protected int invalidPackageOrClass(XmlPullParser parser) {
final String uri = getAttributeValue(parser, ATTR_URI);
if (TextUtils.isEmpty(uri)) {
Log.e(TAG, "Skipping invalid <favorite> with no component or uri");
@@ -185,7 +184,7 @@
}
@Override
- protected Intent parseIntent(XmlResourceParser parser) {
+ protected Intent parseIntent(XmlPullParser parser) {
String uri = null;
try {
uri = getAttributeValue(parser, ATTR_URI);
@@ -205,7 +204,7 @@
private final AppShortcutWithUriParser mChildParser = new AppShortcutWithUriParser();
@Override
- public int parseAndAdd(XmlResourceParser parser) throws XmlPullParserException,
+ public int parseAndAdd(XmlPullParser parser) throws XmlPullParserException,
IOException {
final int groupDepth = parser.getDepth();
int type;
@@ -233,7 +232,7 @@
@Thunk class PartnerFolderParser implements TagParser {
@Override
- public int parseAndAdd(XmlResourceParser parser) throws XmlPullParserException,
+ public int parseAndAdd(XmlPullParser parser) throws XmlPullParserException,
IOException {
// Folder contents come from an external XML resource
final Partner partner = Partner.get(mPackageManager);
@@ -242,7 +241,7 @@
final int resId = partnerRes.getIdentifier(Partner.RES_FOLDER,
"xml", partner.getPackageName());
if (resId != 0) {
- final XmlResourceParser partnerParser = partnerRes.getXml(resId);
+ final XmlPullParser partnerParser = partnerRes.getXml(resId);
beginDocument(partnerParser, TAG_FOLDER);
FolderParser folderParser = new FolderParser(getFolderElementsMap(partnerRes));
@@ -259,7 +258,7 @@
@Thunk class MyFolderParser extends FolderParser {
@Override
- public int parseAndAdd(XmlResourceParser parser) throws XmlPullParserException,
+ public int parseAndAdd(XmlPullParser parser) throws XmlPullParserException,
IOException {
final int resId = getAttributeResourceValue(parser, ATTR_FOLDER_ITEMS, 0);
if (resId != 0) {
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 00da6fa..7fa1aa0 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -1027,7 +1027,8 @@
if (overScrollAmount < 0) {
super.scrollTo(overScrollAmount, getScrollY());
} else {
- super.scrollTo(mMaxScrollX + overScrollAmount, getScrollY());
+ int x = Math.max(0, Math.min(getScrollX(), mMaxScrollX));
+ super.scrollTo(x + overScrollAmount, getScrollY());
}
invalidate();
}
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index c3edfe5..e699500 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -593,8 +593,9 @@
int viewLocationTop = rect.top;
if (isBubbleTextView && !fromDeepShortcutView) {
- BubbleTextView btv = (BubbleTextView) v;
- btv.getIconBounds(rect);
+ ((BubbleTextView) v).getIconBounds(rect);
+ } else if (isFolderIcon) {
+ ((FolderIcon) v).getPreviewBounds(rect);
} else {
rect.set(0, 0, rect.width(), rect.height());
}
@@ -616,14 +617,14 @@
* eg {@link LauncherActivityInfo} or {@link ShortcutInfoCompat}.
*/
public static Drawable getFullDrawable(Launcher launcher, ItemInfo info, int width, int height,
- Object[] outObj) {
+ boolean flattenDrawable, Object[] outObj) {
LauncherAppState appState = LauncherAppState.getInstance(launcher);
if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
LauncherActivityInfo activityInfo = LauncherAppsCompat.getInstance(launcher)
.resolveActivity(info.getIntent(), info.user);
outObj[0] = activityInfo;
return (activityInfo != null) ? appState.getIconCache()
- .getFullResIcon(activityInfo, false) : null;
+ .getFullResIcon(activityInfo, flattenDrawable) : null;
} else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
if (info instanceof PendingAddShortcutInfo) {
ShortcutConfigActivityInfo activityInfo =
diff --git a/src/com/android/launcher3/config/BaseFlags.java b/src/com/android/launcher3/config/BaseFlags.java
index 8c57f46..b350767 100644
--- a/src/com/android/launcher3/config/BaseFlags.java
+++ b/src/com/android/launcher3/config/BaseFlags.java
@@ -116,7 +116,7 @@
"ENABLE_HINTS_IN_OVERVIEW", false,
"Show chip hints and gleams on the overview screen");
- public static final TogglableFlag ENABLE_ASSISTANT_GESTURE = new TogglableFlag(
+ public static final TogglableFlag ENABLE_ASSISTANT_GESTURE = new ToggleableGlobalSettingsFlag(
"ENABLE_ASSISTANT_GESTURE", false,
"Enable swipe up from the bottom right corner to start assistant");
diff --git a/src/com/android/launcher3/dragndrop/DragView.java b/src/com/android/launcher3/dragndrop/DragView.java
index 8a27f9d..bdbea29 100644
--- a/src/com/android/launcher3/dragndrop/DragView.java
+++ b/src/com/android/launcher3/dragndrop/DragView.java
@@ -199,7 +199,8 @@
Object[] outObj = new Object[1];
int w = mBitmap.getWidth();
int h = mBitmap.getHeight();
- Drawable dr = Utilities.getFullDrawable(mLauncher, info, w, h, outObj);
+ Drawable dr = Utilities.getFullDrawable(mLauncher, info, w, h,
+ false /* flattenDrawable */, outObj);
if (dr instanceof AdaptiveIconDrawable) {
int blurMargin = (int) mLauncher.getResources()
diff --git a/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java b/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java
index 794ab4e..5e41bb7 100644
--- a/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java
+++ b/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java
@@ -36,6 +36,7 @@
import com.android.launcher3.R;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.folder.PreviewBackground;
+import com.android.launcher3.graphics.ShiftedBitmapDrawable;
import com.android.launcher3.icons.BitmapRenderer;
import com.android.launcher3.util.Preconditions;
@@ -133,39 +134,4 @@
return new FolderAdaptiveIcon(new ColorDrawable(bg.getBgColor()), foreground, badge, mask);
}
-
- /**
- * A simple drawable which draws a bitmap at a fixed position irrespective of the bounds
- */
- private static class ShiftedBitmapDrawable extends Drawable {
-
- private final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
- private final Bitmap mBitmap;
- private final float mShiftX;
- private final float mShiftY;
-
- ShiftedBitmapDrawable(Bitmap bitmap, float shiftX, float shiftY) {
- mBitmap = bitmap;
- mShiftX = shiftX;
- mShiftY = shiftY;
- }
-
- @Override
- public void draw(Canvas canvas) {
- canvas.drawBitmap(mBitmap, mShiftX, mShiftY, mPaint);
- }
-
- @Override
- public void setAlpha(int i) { }
-
- @Override
- public void setColorFilter(ColorFilter colorFilter) {
- mPaint.setColorFilter(colorFilter);
- }
-
- @Override
- public int getOpacity() {
- return PixelFormat.TRANSLUCENT;
- }
- }
}
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index 30dbe69..67495ea 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -189,6 +189,10 @@
return icon;
}
+ public void getPreviewBounds(Rect outBounds) {
+ mBackground.getBounds(outBounds);
+ }
+
public Folder getFolder() {
return mFolder;
}
diff --git a/src/com/android/launcher3/folder/PreviewBackground.java b/src/com/android/launcher3/folder/PreviewBackground.java
index fd4774f..ac908f4 100644
--- a/src/com/android/launcher3/folder/PreviewBackground.java
+++ b/src/com/android/launcher3/folder/PreviewBackground.java
@@ -33,6 +33,7 @@
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RadialGradient;
+import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.Shader;
import android.util.Property;
@@ -154,6 +155,14 @@
invalidate();
}
+ void getBounds(Rect outBounds) {
+ int top = basePreviewOffsetY;
+ int left = basePreviewOffsetX;
+ int right = left + previewSize;
+ int bottom = top + previewSize;
+ outBounds.set(left, top, right, bottom);
+ }
+
int getRadius() {
return previewSize / 2;
}
diff --git a/src/com/android/launcher3/graphics/ShiftedBitmapDrawable.java b/src/com/android/launcher3/graphics/ShiftedBitmapDrawable.java
new file mode 100644
index 0000000..52d45bb
--- /dev/null
+++ b/src/com/android/launcher3/graphics/ShiftedBitmapDrawable.java
@@ -0,0 +1,74 @@
+/*
+ * 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 android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.drawable.Drawable;
+
+/**
+ * A simple drawable which draws a bitmap at a fixed position irrespective of the bounds
+ */
+public class ShiftedBitmapDrawable extends Drawable {
+
+ private final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
+ private final Bitmap mBitmap;
+ private float mShiftX;
+ private float mShiftY;
+
+ public ShiftedBitmapDrawable(Bitmap bitmap, float shiftX, float shiftY) {
+ mBitmap = bitmap;
+ mShiftX = shiftX;
+ mShiftY = shiftY;
+ }
+
+ public float getShiftX() {
+ return mShiftX;
+ }
+
+ public float getShiftY() {
+ return mShiftY;
+ }
+
+ public void setShiftX(float shiftX) {
+ mShiftX = shiftX;
+ }
+
+ public void setShiftY(float shiftY) {
+ mShiftY = shiftY;
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ canvas.drawBitmap(mBitmap, mShiftX, mShiftY, mPaint);
+ }
+
+ @Override
+ public void setAlpha(int i) { }
+
+ @Override
+ public void setColorFilter(ColorFilter colorFilter) {
+ mPaint.setColorFilter(colorFilter);
+ }
+
+ @Override
+ public int getOpacity() {
+ return PixelFormat.TRANSLUCENT;
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/launcher3/logging/EventLogArray.java b/src/com/android/launcher3/logging/EventLogArray.java
new file mode 100644
index 0000000..bfb3792
--- /dev/null
+++ b/src/com/android/launcher3/logging/EventLogArray.java
@@ -0,0 +1,136 @@
+/*
+ * 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.logging;
+
+
+import java.io.PrintWriter;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+/**
+ * A utility class to record and log events. Events are stored in a fixed size array and old logs
+ * are purged as new events come.
+ */
+public class EventLogArray {
+
+ private static final int TYPE_ONE_OFF = 0;
+ private static final int TYPE_FLOAT = 1;
+ private static final int TYPE_INTEGER = 2;
+ private static final int TYPE_BOOL_TRUE = 3;
+ private static final int TYPE_BOOL_FALSE = 4;
+
+ private final String name;
+ private final EventEntry[] logs;
+ private int nextIndex;
+
+ public EventLogArray(String name, int size) {
+ this.name = name;
+ logs = new EventEntry[size];
+ nextIndex = 0;
+ }
+
+ public void addLog(String event) {
+ addLog(TYPE_ONE_OFF, event, 0);
+ }
+
+ public void addLog(String event, int extras) {
+ addLog(TYPE_INTEGER, event, extras);
+ }
+
+ public void addLog(String event, float extras) {
+ addLog(TYPE_FLOAT, event, extras);
+ }
+
+ public void addLog(String event, boolean extras) {
+ addLog(extras ? TYPE_BOOL_TRUE : TYPE_BOOL_FALSE, event, 0);
+ }
+
+ private void addLog(int type, String event, float extras) {
+ // Merge the logs if its a duplicate
+ int last = (nextIndex + logs.length - 1) % logs.length;
+ int secondLast = (nextIndex + logs.length - 2) % logs.length;
+ if (isEntrySame(logs[last], type, event) && isEntrySame(logs[secondLast], type, event)) {
+ logs[last].update(type, event, extras);
+ logs[secondLast].duplicateCount++;
+ return;
+ }
+
+ if (logs[nextIndex] == null) {
+ logs[nextIndex] = new EventEntry();
+ }
+ logs[nextIndex].update(type, event, extras);
+ nextIndex = (nextIndex + 1) % logs.length;
+ }
+
+ public void dump(String prefix, PrintWriter writer) {
+ writer.println(prefix + name + " event history:");
+ SimpleDateFormat sdf = new SimpleDateFormat(" HH:mm:ss.SSSZ ", Locale.US);
+ Date date = new Date();
+
+ for (int i = 0; i < logs.length; i++) {
+ EventEntry log = logs[(nextIndex + logs.length - i - 1) % logs.length];
+ if (log == null) {
+ continue;
+ }
+ date.setTime(log.time);
+
+ StringBuilder msg = new StringBuilder(prefix).append(sdf.format(date))
+ .append(log.event);
+ switch (log.type) {
+ case TYPE_BOOL_FALSE:
+ msg.append(": false");
+ break;
+ case TYPE_BOOL_TRUE:
+ msg.append(": true");
+ break;
+ case TYPE_FLOAT:
+ msg.append(": ").append(log.extras);
+ break;
+ case TYPE_INTEGER:
+ msg.append(": ").append((int) log.extras);
+ break;
+ default: // fall out
+ }
+ if (log.duplicateCount > 0) {
+ msg.append(" & ").append(log.duplicateCount).append(" similar events");
+ }
+ writer.println(msg);
+ }
+ }
+
+ private boolean isEntrySame(EventEntry entry, int type, String event) {
+ return entry != null && entry.type == type && entry.event.equals(event);
+ }
+
+ /** A single event entry. */
+ private static class EventEntry {
+
+ private int type;
+ private String event;
+ private float extras;
+ private long time;
+ private int duplicateCount;
+
+ public void update(int type, String event, float extras) {
+ this.type = type;
+ this.event = event;
+ this.extras = extras;
+ time = System.currentTimeMillis();
+ duplicateCount = 0;
+ }
+ }
+}
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index 2b9e7b6..23ddd98 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -43,7 +43,9 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.dragndrop.DragLayer;
+import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.folder.FolderShape;
+import com.android.launcher3.graphics.ShiftedBitmapDrawable;
import com.android.launcher3.icons.LauncherIcons;
import androidx.annotation.Nullable;
@@ -57,6 +59,8 @@
public class FloatingIconView extends View implements Animator.AnimatorListener, ClipPathView {
+ private static final Rect sTmpRect = new Rect();
+
private Runnable mStartRunnable;
private Runnable mEndRunnable;
@@ -181,10 +185,11 @@
}
@WorkerThread
- private void getIcon(Launcher launcher, ItemInfo info, boolean useDrawableAsIs,
+ private void getIcon(Launcher launcher, View v, ItemInfo info, boolean useDrawableAsIs,
float aspectRatio) {
final LayoutParams lp = (LayoutParams) getLayoutParams();
- mDrawable = Utilities.getFullDrawable(launcher, info, lp.width, lp.height, new Object[1]);
+ mDrawable = Utilities.getFullDrawable(launcher, info, lp.width, lp.height, useDrawableAsIs,
+ new Object[1]);
if (ADAPTIVE_ICON_WINDOW_ANIM.get() && !useDrawableAsIs
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
@@ -205,6 +210,12 @@
int offset = getOffsetForAdaptiveIconBounds();
mFinalDrawableBounds.set(offset, offset, lp.width - offset, mOriginalHeight - offset);
+ if (mForeground instanceof ShiftedBitmapDrawable && v instanceof FolderIcon) {
+ ShiftedBitmapDrawable sbd = (ShiftedBitmapDrawable) mForeground;
+ ((FolderIcon) v).getPreviewBounds(sTmpRect);
+ sbd.setShiftX(sbd.getShiftX() - sTmpRect.left);
+ sbd.setShiftY(sbd.getShiftY() - sTmpRect.top);
+ }
mForeground.setBounds(mFinalDrawableBounds);
mBackground.setBounds(mFinalDrawableBounds);
@@ -323,8 +334,8 @@
// Must be called after matchPositionOf so that we know what size to load.
if (originalView.getTag() instanceof ItemInfo) {
new Handler(LauncherModel.getWorkerLooper()).postAtFrontOfQueue(() -> {
- view.getIcon(launcher, (ItemInfo) originalView.getTag(), useDrawableAsIs,
- aspectRatio);
+ view.getIcon(launcher, originalView, (ItemInfo) originalView.getTag(),
+ useDrawableAsIs, aspectRatio);
});
}