Merge "Removing extraction service and palette api dependency" into ub-launcher3-master
diff --git a/res/layout/app_widget_resize_frame.xml b/res/layout/app_widget_resize_frame.xml
index 874fecc..12561b6 100644
--- a/res/layout/app_widget_resize_frame.xml
+++ b/res/layout/app_widget_resize_frame.xml
@@ -21,42 +21,47 @@
android:background="@drawable/widget_resize_shadow"
android:foreground="@drawable/widget_resize_frame"
android:foregroundTint="?attr/workspaceTextColor"
- android:padding="0dp" >
+ android:padding="0dp">
- <!-- Left -->
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="left|center_vertical"
- android:layout_marginLeft="@dimen/widget_handle_margin"
- android:src="@drawable/ic_widget_resize_handle"
- android:tint="?attr/workspaceTextColor" />
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
- <!-- Top -->
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="top|center_horizontal"
- android:layout_marginTop="@dimen/widget_handle_margin"
- android:src="@drawable/ic_widget_resize_handle"
- android:tint="?attr/workspaceTextColor" />
+ <!-- Left -->
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="left|center_vertical"
+ android:layout_marginLeft="@dimen/widget_handle_margin"
+ android:src="@drawable/ic_widget_resize_handle"
+ android:tint="?attr/workspaceTextColor" />
- <!-- Right -->
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="right|center_vertical"
- android:layout_marginRight="@dimen/widget_handle_margin"
- android:src="@drawable/ic_widget_resize_handle"
- android:tint="?attr/workspaceTextColor" />
+ <!-- Top -->
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top|center_horizontal"
+ android:layout_marginTop="@dimen/widget_handle_margin"
+ android:src="@drawable/ic_widget_resize_handle"
+ android:tint="?attr/workspaceTextColor" />
- <!-- Bottom -->
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom|center_horizontal"
- android:layout_marginBottom="@dimen/widget_handle_margin"
- android:src="@drawable/ic_widget_resize_handle"
- android:tint="?attr/workspaceTextColor" />
+ <!-- Right -->
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="right|center_vertical"
+ android:layout_marginRight="@dimen/widget_handle_margin"
+ android:src="@drawable/ic_widget_resize_handle"
+ android:tint="?attr/workspaceTextColor" />
+ <!-- Bottom -->
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom|center_horizontal"
+ android:layout_marginBottom="@dimen/widget_handle_margin"
+ android:src="@drawable/ic_widget_resize_handle"
+ android:tint="?attr/workspaceTextColor" />
+
+ </FrameLayout>
</com.android.launcher3.AppWidgetResizeFrame>
\ No newline at end of file
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 34385b0..e87397b 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -123,6 +123,7 @@
<attr name="iconTextSize" format="float" />
<attr name="defaultLayoutId" format="reference" />
+ <attr name="demoModeLayoutId" format="reference" />
</declare-styleable>
<declare-styleable name="CellLayout">
diff --git a/src/com/android/launcher3/AbstractFloatingView.java b/src/com/android/launcher3/AbstractFloatingView.java
index 597e937..4996818 100644
--- a/src/com/android/launcher3/AbstractFloatingView.java
+++ b/src/com/android/launcher3/AbstractFloatingView.java
@@ -25,6 +25,8 @@
import android.widget.LinearLayout;
import com.android.launcher3.dragndrop.DragLayer;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
+import com.android.launcher3.util.TouchController;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -32,18 +34,20 @@
/**
* Base class for a View which shows a floating UI on top of the launcher UI.
*/
-public abstract class AbstractFloatingView extends LinearLayout {
+public abstract class AbstractFloatingView extends LinearLayout implements TouchController {
@IntDef(flag = true, value = {
TYPE_FOLDER,
TYPE_POPUP_CONTAINER_WITH_ARROW,
- TYPE_WIDGETS_BOTTOM_SHEET
+ TYPE_WIDGETS_BOTTOM_SHEET,
+ TYPE_WIDGET_RESIZE_FRAME
})
@Retention(RetentionPolicy.SOURCE)
public @interface FloatingViewType {}
public static final int TYPE_FOLDER = 1 << 0;
public static final int TYPE_POPUP_CONTAINER_WITH_ARROW = 1 << 1;
public static final int TYPE_WIDGETS_BOTTOM_SHEET = 1 << 2;
+ public static final int TYPE_WIDGET_RESIZE_FRAME = 1 << 3;
protected boolean mIsOpen;
@@ -72,21 +76,7 @@
protected abstract void handleClose(boolean animate);
- /**
- * If the view is current handling keyboard, return the active target, null otherwise
- */
- public ExtendedEditText getActiveTextView() {
- return null;
- }
-
-
- /**
- * Any additional view (outside of this container) where touch should be allowed while this
- * view is visible.
- */
- public View getExtendedTouchView() {
- return null;
- }
+ public abstract void logActionCommand(int command);
public final boolean isOpen() {
return mIsOpen;
@@ -97,6 +87,16 @@
protected abstract boolean isOfType(@FloatingViewType int type);
+ public void onBackPressed() {
+ logActionCommand(Action.Command.BACK);
+ close(true);
+ }
+
+ @Override
+ public boolean onControllerTouchEvent(MotionEvent ev) {
+ return false;
+ }
+
protected static <T extends AbstractFloatingView> T getOpenView(
Launcher launcher, @FloatingViewType int type) {
DragLayer dragLayer = launcher.getDragLayer();
@@ -139,8 +139,6 @@
public static AbstractFloatingView getTopOpenView(Launcher launcher) {
return getOpenView(launcher, TYPE_FOLDER | TYPE_POPUP_CONTAINER_WITH_ARROW
- | TYPE_WIDGETS_BOTTOM_SHEET);
+ | TYPE_WIDGETS_BOTTOM_SHEET | TYPE_WIDGET_RESIZE_FRAME);
}
-
- public abstract int getLogContainerType();
}
diff --git a/src/com/android/launcher3/AppInfo.java b/src/com/android/launcher3/AppInfo.java
index 3da1996..7d2f753 100644
--- a/src/com/android/launcher3/AppInfo.java
+++ b/src/com/android/launcher3/AppInfo.java
@@ -19,6 +19,7 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ApplicationInfo;
import android.content.pm.LauncherActivityInfo;
import android.os.UserHandle;
@@ -31,6 +32,10 @@
*/
public class AppInfo extends ItemInfoWithIcon {
+ public static final int FLAG_SYSTEM_UNKNOWN = 0;
+ public static final int FLAG_SYSTEM_YES = 1 << 0;
+ public static final int FLAG_SYSTEM_NO = 1 << 1;
+
/**
* The intent used to start the application.
*/
@@ -43,6 +48,11 @@
*/
public int isDisabled = ShortcutInfo.DEFAULT;
+ /**
+ * Stores if the app is a system app or not.
+ */
+ public int isSystemApp;
+
public AppInfo() {
itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
}
@@ -71,6 +81,10 @@
}
intent = makeLaunchIntent(info);
+
+ isSystemApp = (info.getApplicationInfo().flags & ApplicationInfo.FLAG_SYSTEM) == 0
+ ? FLAG_SYSTEM_NO : FLAG_SYSTEM_YES;
+
}
public AppInfo(AppInfo info) {
@@ -79,6 +93,7 @@
title = Utilities.trim(info.title);
intent = new Intent(info.intent);
isDisabled = info.isDisabled;
+ isSystemApp = info.isSystemApp;
}
@Override
diff --git a/src/com/android/launcher3/AppWidgetResizeFrame.java b/src/com/android/launcher3/AppWidgetResizeFrame.java
index d0b1c30..1e95333 100644
--- a/src/com/android/launcher3/AppWidgetResizeFrame.java
+++ b/src/com/android/launcher3/AppWidgetResizeFrame.java
@@ -14,15 +14,13 @@
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
-import android.widget.FrameLayout;
+import android.view.ViewGroup;
import com.android.launcher3.accessibility.DragViewStateAnnouncer;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.util.FocusLogic;
-import com.android.launcher3.util.TouchController;
-public class AppWidgetResizeFrame extends FrameLayout
- implements View.OnKeyListener, TouchController {
+public class AppWidgetResizeFrame extends AbstractFloatingView implements View.OnKeyListener {
private static final int SNAP_DURATION = 150;
private static final float DIMMED_HANDLE_ALPHA = 0f;
private static final float RESIZE_THRESHOLD = 0.66f;
@@ -108,12 +106,28 @@
protected void onFinishInflate() {
super.onFinishInflate();
+ ViewGroup content = (ViewGroup) getChildAt(0);
for (int i = 0; i < HANDLE_COUNT; i ++) {
- mDragHandles[i] = getChildAt(i);
+ mDragHandles[i] = content.getChildAt(i);
}
}
- public void setupForWidget(LauncherAppWidgetHostView widgetView, CellLayout cellLayout,
+ public static void showForWidget(LauncherAppWidgetHostView widget, CellLayout cellLayout) {
+ Launcher launcher = Launcher.getLauncher(cellLayout.getContext());
+ AbstractFloatingView.closeAllOpenViews(launcher);
+
+ DragLayer dl = launcher.getDragLayer();
+ AppWidgetResizeFrame frame = (AppWidgetResizeFrame) launcher.getLayoutInflater()
+ .inflate(R.layout.app_widget_resize_frame, dl, false);
+ frame.setupForWidget(widget, cellLayout, dl);
+ ((DragLayer.LayoutParams) frame.getLayoutParams()).customPosition = true;
+
+ dl.addView(frame);
+ frame.mIsOpen = true;
+ frame.snapToWidget(false);
+ }
+
+ private void setupForWidget(LauncherAppWidgetHostView widgetView, CellLayout cellLayout,
DragLayer dragLayer) {
mCellLayout = cellLayout;
mWidgetView = widgetView;
@@ -384,7 +398,7 @@
out.bottom = out.top + height;
}
- public void snapToWidget(boolean animate) {
+ private void snapToWidget(boolean animate) {
getSnappedRectRelativeToDragLayer(sTmpRect);
int newWidth = sTmpRect.width();
int newHeight = sTmpRect.height();
@@ -448,7 +462,7 @@
public boolean onKey(View v, int keyCode, KeyEvent event) {
// Clear the frame and give focus to the widget host view when a directional key is pressed.
if (FocusLogic.shouldConsume(keyCode)) {
- mDragLayer.clearResizeFrame();
+ close(false);
mWidgetView.requestFocus();
return true;
}
@@ -498,9 +512,25 @@
if (ev.getAction() == MotionEvent.ACTION_DOWN && handleTouchDown(ev)) {
return true;
}
+ close(false);
return false;
}
+ @Override
+ protected void handleClose(boolean animate) {
+ mDragLayer.removeView(this);
+ }
+
+ @Override
+ public void logActionCommand(int command) {
+ // TODO: Log this case.
+ }
+
+ @Override
+ protected boolean isOfType(int type) {
+ return (type & TYPE_WIDGET_RESIZE_FRAME) != 0;
+ }
+
/**
* A mutable class for describing the range of two int values.
*/
diff --git a/src/com/android/launcher3/ExtendedEditText.java b/src/com/android/launcher3/ExtendedEditText.java
index 596aa8f..403c8b8 100644
--- a/src/com/android/launcher3/ExtendedEditText.java
+++ b/src/com/android/launcher3/ExtendedEditText.java
@@ -16,12 +16,16 @@
package com.android.launcher3;
import android.content.Context;
+import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.DragEvent;
import android.view.KeyEvent;
+import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
+import com.android.launcher3.util.UiThreadHelper;
+
/**
* The edit text that reports back when the back key has been pressed.
@@ -102,8 +106,7 @@
}
public void dispatchBackKey() {
- ((InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE))
- .hideSoftInputFromWindow(getWindowToken(), 0);
+ UiThreadHelper.hideKeyboardAsync(getContext(), getWindowToken());
if (mBackKeyListener != null) {
mBackKeyListener.onBackKey();
}
@@ -121,4 +124,17 @@
public boolean isSuggestionsEnabled() {
return !mForceDisableSuggestions && super.isSuggestionsEnabled();
}
+
+ public void reset() {
+ if (!TextUtils.isEmpty(getText())) {
+ setText("");
+ }
+ if (isFocused()) {
+ View nextFocus = focusSearch(View.FOCUS_DOWN);
+ if (nextFocus != null) {
+ nextFocus.requestFocus();
+ }
+ }
+ UiThreadHelper.hideKeyboardAsync(getContext(), getWindowToken());
+ }
}
diff --git a/src/com/android/launcher3/FirstFrameAnimatorHelper.java b/src/com/android/launcher3/FirstFrameAnimatorHelper.java
index 3cbc989..cea7e43 100644
--- a/src/com/android/launcher3/FirstFrameAnimatorHelper.java
+++ b/src/com/android/launcher3/FirstFrameAnimatorHelper.java
@@ -24,6 +24,7 @@
import android.view.ViewPropertyAnimator;
import android.view.ViewTreeObserver;
import com.android.launcher3.util.Thunk;
+import com.android.launcher3.util.TraceHelper;
/*
* This is a helper class that listens to updates from the corresponding animation.
@@ -71,15 +72,12 @@
if (sGlobalDrawListener != null) {
view.getViewTreeObserver().removeOnDrawListener(sGlobalDrawListener);
}
+
+ TraceHelper.beginSection("TICK");
sGlobalDrawListener = new ViewTreeObserver.OnDrawListener() {
- private long mTime = System.currentTimeMillis();
public void onDraw() {
sGlobalFrameCounter++;
- if (DEBUG) {
- long newTime = System.currentTimeMillis();
- Log.d(TAG, "TICK " + (newTime - mTime));
- mTime = newTime;
- }
+ TraceHelper.partitionSection("TICK", "Frame drawn");
}
};
view.getViewTreeObserver().addOnDrawListener(sGlobalDrawListener);
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index d7bebd1..7a43198 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -85,7 +85,9 @@
* Number of icons inside the hotseat area.
*/
public int numHotseatIcons;
+
int defaultLayoutId;
+ int demoModeLayoutId;
public DeviceProfile landscapeProfile;
public DeviceProfile portraitProfile;
@@ -99,11 +101,11 @@
this(p.name, p.minWidthDps, p.minHeightDps, p.numRows, p.numColumns,
p.numFolderRows, p.numFolderColumns, p.minAllAppsPredictionColumns,
p.iconSize, p.landscapeIconSize, p.iconTextSize, p.numHotseatIcons,
- p.defaultLayoutId);
+ p.defaultLayoutId, p.demoModeLayoutId);
}
InvariantDeviceProfile(String n, float w, float h, int r, int c, int fr, int fc, int maapc,
- float is, float lis, float its, int hs, int dlId) {
+ float is, float lis, float its, int hs, int dlId, int dmlId) {
name = n;
minWidthDps = w;
minHeightDps = h;
@@ -117,6 +119,7 @@
iconTextSize = its;
numHotseatIcons = hs;
defaultLayoutId = dlId;
+ demoModeLayoutId = dmlId;
}
@TargetApi(23)
@@ -144,6 +147,7 @@
numColumns = closestProfile.numColumns;
numHotseatIcons = closestProfile.numHotseatIcons;
defaultLayoutId = closestProfile.defaultLayoutId;
+ demoModeLayoutId = closestProfile.demoModeLayoutId;
numFolderRows = closestProfile.numFolderRows;
numFolderColumns = closestProfile.numFolderColumns;
minAllAppsPredictionColumns = closestProfile.minAllAppsPredictionColumns;
@@ -208,7 +212,8 @@
a.getFloat(R.styleable.InvariantDeviceProfile_landscapeIconSize, iconSize),
a.getFloat(R.styleable.InvariantDeviceProfile_iconTextSize, 0),
a.getInt(R.styleable.InvariantDeviceProfile_numHotseatIcons, numColumns),
- a.getResourceId(R.styleable.InvariantDeviceProfile_defaultLayoutId, 0)));
+ a.getResourceId(R.styleable.InvariantDeviceProfile_defaultLayoutId, 0),
+ a.getResourceId(R.styleable.InvariantDeviceProfile_demoModeLayoutId, 0)));
a.recycle();
}
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index b1b8566..4cc6f89 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -56,8 +56,6 @@
import android.os.Handler;
import android.os.Process;
import android.os.StrictMode;
-import android.os.SystemClock;
-import android.os.Trace;
import android.os.UserHandle;
import android.support.annotation.Nullable;
import android.text.Selection;
@@ -94,6 +92,7 @@
import com.android.launcher3.compat.AppWidgetManagerCompat;
import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.LauncherAppsCompatVO;
+import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragLayer;
@@ -132,6 +131,8 @@
import com.android.launcher3.util.TestingUtils;
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.Thunk;
+import com.android.launcher3.util.TraceHelper;
+import com.android.launcher3.util.UiThreadHelper;
import com.android.launcher3.util.ViewOnDrawExecutor;
import com.android.launcher3.widget.PendingAddShortcutInfo;
import com.android.launcher3.widget.PendingAddWidgetInfo;
@@ -160,9 +161,7 @@
public static final String TAG = "Launcher";
static final boolean LOGD = false;
- static final boolean DEBUG_WIDGETS = false;
static final boolean DEBUG_STRICT_MODE = false;
- static final boolean DEBUG_RESUME_TIME = false;
private static final int REQUEST_CREATE_SHORTCUT = 1;
private static final int REQUEST_CREATE_APPWIDGET = 5;
@@ -348,9 +347,7 @@
.penaltyDeath()
.build());
}
- if (LauncherAppState.PROFILE_STARTUP) {
- Trace.beginSection("Launcher-onCreate");
- }
+ TraceHelper.beginSection("Launcher-onCreate");
if (mLauncherCallbacks != null) {
mLauncherCallbacks.preOnCreate();
@@ -361,6 +358,7 @@
overrideTheme(wallpaperColorInfo.isDark(), wallpaperColorInfo.supportsDarkText());
super.onCreate(savedInstanceState);
+ TraceHelper.partitionSection("Launcher-onCreate", "super call");
LauncherAppState app = LauncherAppState.getInstance(this);
@@ -410,10 +408,6 @@
restoreState(savedInstanceState);
- if (LauncherAppState.PROFILE_STARTUP) {
- Trace.endSection();
- }
-
// We only load the page synchronously if the user rotates (or triggers a
// configuration change) while launcher is in the foreground
int currentScreen = PagedView.INVALID_RESTORE_PAGE;
@@ -468,6 +462,8 @@
if (mLauncherCallbacks != null) {
mLauncherCallbacks.onCreate(savedInstanceState);
}
+
+ TraceHelper.endSection("Launcher-onCreate");
}
@Override
@@ -867,17 +863,13 @@
@Override
protected void onResume() {
- long startTime = 0;
- if (DEBUG_RESUME_TIME) {
- startTime = System.currentTimeMillis();
- Log.v(TAG, "Launcher.onResume()");
- }
-
+ TraceHelper.beginSection("ON_RESUME");
if (mLauncherCallbacks != null) {
mLauncherCallbacks.preOnResume();
}
-
super.onResume();
+ TraceHelper.partitionSection("ON_RESUME", "superCall");
+
getUserEventDispatcher().resetElapsedSessionMillis();
// Restore the previous launcher state
@@ -906,19 +898,10 @@
if (mBindOnResumeCallbacks.size() > 0) {
// We might have postponed some bind calls until onResume (see waitUntilResume) --
// execute them here
- long startTimeCallbacks = 0;
- if (DEBUG_RESUME_TIME) {
- startTimeCallbacks = System.currentTimeMillis();
- }
-
for (int i = 0; i < mBindOnResumeCallbacks.size(); i++) {
mBindOnResumeCallbacks.get(i).run();
}
mBindOnResumeCallbacks.clear();
- if (DEBUG_RESUME_TIME) {
- Log.d(TAG, "Time spent processing callbacks in onResume: " +
- (System.currentTimeMillis() - startTimeCallbacks));
- }
}
if (mOnResumeCallbacks.size() > 0) {
for (int i = 0; i < mOnResumeCallbacks.size(); i++) {
@@ -942,10 +925,6 @@
getWorkspace().reinflateWidgetsIfNecessary();
}
- if (DEBUG_RESUME_TIME) {
- Log.d(TAG, "Time spent in onResume: " + (System.currentTimeMillis() - startTime));
- }
-
updateInteraction(Workspace.State.NORMAL, mWorkspace.getState());
mWorkspace.onResume();
@@ -963,6 +942,7 @@
mLauncherCallbacks.onResume();
}
+ TraceHelper.endSection("ON_RESUME");
}
@Override
@@ -1092,9 +1072,6 @@
// Close any open floating view
AbstractFloatingView.closeAllOpenViews(this);
- // Stop resizing any widgets
- mWorkspace.exitWidgetResizeMode();
-
// Show the overview mode if we are on the workspace
if (mState == State.WORKSPACE && !mWorkspace.isInOverviewMode() &&
!mWorkspace.isSwitchingState()) {
@@ -1412,8 +1389,6 @@
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (Intent.ACTION_SCREEN_OFF.equals(action)) {
- mDragLayer.clearResizeFrame();
-
// Reset AllApps to its initial state only if we are not in the middle of
// processing a multi-step drop
if (mAppsView != null && mWidgetsView != null && mPendingRequestArgs == null) {
@@ -1554,10 +1529,7 @@
@Override
protected void onNewIntent(Intent intent) {
- long startTime = 0;
- if (DEBUG_RESUME_TIME) {
- startTime = System.currentTimeMillis();
- }
+ TraceHelper.beginSection("NEW_INTENT");
super.onNewIntent(intent);
boolean alreadyOnHome = mHasFocus && ((intent.getFlags() &
@@ -1578,17 +1550,9 @@
// Note: There should be at most one log per method call. This is enforced implicitly
// by using if-else statements.
UserEventDispatcher ued = getUserEventDispatcher();
-
- // TODO: Log this case.
- mWorkspace.exitWidgetResizeMode();
-
AbstractFloatingView topOpenView = AbstractFloatingView.getTopOpenView(this);
- if (topOpenView instanceof PopupContainerWithArrow) {
- ued.logActionCommand(Action.Command.HOME_INTENT,
- topOpenView.getExtendedTouchView(), ContainerType.DEEPSHORTCUTS);
- } else if (topOpenView instanceof Folder) {
- ued.logActionCommand(Action.Command.HOME_INTENT,
- ((Folder) topOpenView).getFolderIcon(), ContainerType.FOLDER);
+ if (topOpenView != null) {
+ topOpenView.logActionCommand(Action.Command.HOME_INTENT);
} else if (alreadyOnHome) {
ued.logActionCommand(Action.Command.HOME_INTENT,
mWorkspace.getState().containerType, mWorkspace.getCurrentPage());
@@ -1608,9 +1572,7 @@
final View v = getWindow().peekDecorView();
if (v != null && v.getWindowToken() != null) {
- InputMethodManager imm = (InputMethodManager) getSystemService(
- INPUT_METHOD_SERVICE);
- imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
+ UiThreadHelper.hideKeyboardAsync(this, v.getWindowToken());
}
// Reset the apps view
@@ -1654,9 +1616,7 @@
}
}
- if (DEBUG_RESUME_TIME) {
- Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));
- }
+ TraceHelper.endSection("NEW_INTENT");
}
@Override
@@ -2070,18 +2030,7 @@
UserEventDispatcher ued = getUserEventDispatcher();
AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(this);
if (topView != null) {
- if (topView.getActiveTextView() != null) {
- topView.getActiveTextView().dispatchBackKey();
- } else {
- if (topView instanceof PopupContainerWithArrow) {
- ued.logActionCommand(Action.Command.BACK,
- topView.getExtendedTouchView(), ContainerType.DEEPSHORTCUTS);
- } else if (topView instanceof Folder) {
- ued.logActionCommand(Action.Command.BACK,
- ((Folder) topView).getFolderIcon(), ContainerType.FOLDER);
- }
- topView.close(true);
- }
+ topView.onBackPressed();
} else if (isAppsViewVisible()) {
ued.logActionCommand(Action.Command.BACK, ContainerType.ALLAPPS);
showWorkspace(true);
@@ -2092,9 +2041,6 @@
ued.logActionCommand(Action.Command.BACK, ContainerType.OVERVIEW);
showWorkspace(true);
} else {
- // TODO: Log this case.
- mWorkspace.exitWidgetResizeMode();
-
// Back button is a no-op here, but give at least some feedback for the button press
mWorkspace.showOutlinesTemporarily();
}
@@ -3023,10 +2969,7 @@
* Implementation of the method from LauncherModel.Callbacks.
*/
public void startBinding() {
- if (LauncherAppState.PROFILE_STARTUP) {
- Trace.beginSection("Starting page bind");
- }
-
+ TraceHelper.beginSection("startBinding");
AbstractFloatingView.closeAllOpenViews(this);
setWorkspaceLoading(true);
@@ -3038,9 +2981,7 @@
if (mHotseat != null) {
mHotseat.resetLayout();
}
- if (LauncherAppState.PROFILE_STARTUP) {
- Trace.endSection();
- }
+ TraceHelper.endSection("startBinding");
}
@Override
@@ -3244,10 +3185,7 @@
return view;
}
- final long start = DEBUG_WIDGETS ? SystemClock.uptimeMillis() : 0;
- if (DEBUG_WIDGETS) {
- Log.d(TAG, "bindAppWidget: " + item);
- }
+ TraceHelper.beginSection("BIND_WIDGET");
final LauncherAppWidgetProviderInfo appWidgetInfo;
@@ -3265,11 +3203,9 @@
if (!item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) &&
(item.restoreStatus != LauncherAppWidgetInfo.RESTORE_COMPLETED)) {
if (appWidgetInfo == null) {
- if (DEBUG_WIDGETS) {
- Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId
- + " belongs to component " + item.providerName
- + ", as the provider is null");
- }
+ Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId
+ + " belongs to component " + item.providerName
+ + ", as the provider is null");
getModelWriter().deleteItemFromDatabase(item);
return null;
}
@@ -3330,11 +3266,6 @@
final AppWidgetHostView view;
if (item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {
- if (DEBUG_WIDGETS) {
- Log.d(TAG, "bindAppWidget: id=" + item.appWidgetId + " belongs to component "
- + appWidgetInfo.provider);
- }
-
// Verify that we own the widget
if (appWidgetInfo == null) {
FileLog.e(TAG, "Removing invalid widget: id=" + item.appWidgetId);
@@ -3350,10 +3281,7 @@
}
prepareAppWidget(view, item);
- if (DEBUG_WIDGETS) {
- Log.d(TAG, "bound widget id="+item.appWidgetId+" in "
- + (SystemClock.uptimeMillis()-start) + "ms");
- }
+ TraceHelper.endSection("BIND_WIDGET", "id=" + item.appWidgetId);
return view;
}
@@ -3439,9 +3367,7 @@
if (waitUntilResume(r)) {
return;
}
- if (LauncherAppState.PROFILE_STARTUP) {
- Trace.beginSection("Page bind completed");
- }
+ TraceHelper.beginSection("finishBindingItems");
mWorkspace.restoreInstanceStateForRemainingPages();
setWorkspaceLoading(false);
@@ -3460,9 +3386,7 @@
if (mLauncherCallbacks != null) {
mLauncherCallbacks.finishBindingItems(false);
}
- if (LauncherAppState.PROFILE_STARTUP) {
- Trace.endSection();
- }
+ TraceHelper.endSection("finishBindingItems");
}
private boolean canRunNewAppsAnimation() {
@@ -3732,7 +3656,8 @@
}
private boolean shouldShowDiscoveryBounce() {
- return mState == State.WORKSPACE && !mSharedPrefs.getBoolean(APPS_VIEW_SHOWN, false);
+ UserManagerCompat um = UserManagerCompat.getInstance(this);
+ return mState == State.WORKSPACE && !mSharedPrefs.getBoolean(APPS_VIEW_SHOWN, false) && !um.isDemoUser();
}
/**
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 5df2dad..dfb30fd 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -41,8 +41,6 @@
public class LauncherAppState {
- public static final boolean PROFILE_STARTUP = FeatureFlags.IS_DOGFOOD_BUILD;
-
// We do not need any synchronization for this variable as its only written on UI thread.
private static LauncherAppState INSTANCE;
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 6d158f7..25a698b 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -148,9 +148,6 @@
*/
protected synchronized void createDbIfNotExists() {
if (mOpenHelper == null) {
- if (LauncherAppState.PROFILE_STARTUP) {
- Trace.beginSection("Opening workspace DB");
- }
mOpenHelper = new DatabaseHelper(getContext(), mListenerHandler);
if (RestoreDbTask.isPending(getContext())) {
@@ -161,10 +158,6 @@
// executed again.
RestoreDbTask.setPending(getContext(), false);
}
-
- if (LauncherAppState.PROFILE_STARTUP) {
- Trace.endSection();
- }
}
}
@@ -538,7 +531,14 @@
}
private DefaultLayoutParser getDefaultLayoutParser(AppWidgetHost widgetHost) {
- int defaultLayout = LauncherAppState.getIDP(getContext()).defaultLayoutId;
+ InvariantDeviceProfile idp = LauncherAppState.getIDP(getContext());
+ int defaultLayout = idp.defaultLayoutId;
+
+ UserManagerCompat um = UserManagerCompat.getInstance(getContext());
+ if (um.isDemoUser() && idp.demoModeLayoutId != 0) {
+ defaultLayout = idp.demoModeLayoutId;
+ }
+
return new DefaultLayoutParser(getContext(), widgetHost,
mOpenHelper, getContext().getResources(), defaultLayout);
}
diff --git a/src/com/android/launcher3/UninstallDropTarget.java b/src/com/android/launcher3/UninstallDropTarget.java
index 84d6a9b..902fd34 100644
--- a/src/com/android/launcher3/UninstallDropTarget.java
+++ b/src/com/android/launcher3/UninstallDropTarget.java
@@ -21,6 +21,7 @@
public class UninstallDropTarget extends ButtonDropTarget {
private static final String TAG = "UninstallDropTarget";
+ private static Boolean sUninstallDisabled;
public UninstallDropTarget(Context context, AttributeSet attrs) {
this(context, attrs, 0);
@@ -48,13 +49,22 @@
}
public static boolean supportsDrop(Context context, ItemInfo info) {
- UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
- Bundle restrictions = userManager.getUserRestrictions();
- if (restrictions.getBoolean(UserManager.DISALLOW_APPS_CONTROL, false)
- || restrictions.getBoolean(UserManager.DISALLOW_UNINSTALL_APPS, false)) {
+ if (sUninstallDisabled == null) {
+ UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
+ Bundle restrictions = userManager.getUserRestrictions();
+ sUninstallDisabled = restrictions.getBoolean(UserManager.DISALLOW_APPS_CONTROL, false)
+ || restrictions.getBoolean(UserManager.DISALLOW_UNINSTALL_APPS, false);
+ }
+ if (sUninstallDisabled) {
return false;
}
+ if (info instanceof AppInfo) {
+ AppInfo appInfo = (AppInfo) info;
+ if (appInfo.isSystemApp != AppInfo.FLAG_SYSTEM_UNKNOWN) {
+ return (appInfo.isSystemApp & AppInfo.FLAG_SYSTEM_NO) != 0;
+ }
+ }
return getUninstallTarget(context, info) != null;
}
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index b6876f6..7167778 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -309,6 +309,9 @@
float highScore = -1;
int bestHue = -1;
+ int[] pixels = new int[samples];
+ int pixelCount = 0;
+
for (int y = 0; y < height; y += sampleStride) {
for (int x = 0; x < width; x += sampleStride) {
int argb = bitmap.getPixel(x, y);
@@ -326,6 +329,9 @@
// Defensively avoid array bounds violations.
continue;
}
+ if (pixelCount < samples) {
+ pixels[pixelCount++] = rgb;
+ }
float score = hsv[1] * hsv[2];
hueScoreHistogram[hue] += score;
if (hueScoreHistogram[hue] > highScore) {
@@ -335,31 +341,29 @@
}
}
- SparseArray<Float> rgbScores = new SparseArray<Float>();
+ SparseArray<Float> rgbScores = new SparseArray<>();
int bestColor = 0xff000000;
highScore = -1;
// Go back over the RGB colors that match the winning hue,
// creating a histogram of weighted s*v scores, for up to 100*100 [s,v] buckets.
// The highest-scoring RGB color wins.
- for (int y = 0; y < height; y += sampleStride) {
- for (int x = 0; x < width; x += sampleStride) {
- int rgb = bitmap.getPixel(x, y) | 0xff000000;
- Color.colorToHSV(rgb, hsv);
- int hue = (int) hsv[0];
- if (hue == bestHue) {
- float s = hsv[1];
- float v = hsv[2];
- int bucket = (int) (s * 100) + (int) (v * 10000);
- // Score by cumulative saturation * value.
- float score = s * v;
- Float oldTotal = rgbScores.get(bucket);
- float newTotal = oldTotal == null ? score : oldTotal + score;
- rgbScores.put(bucket, newTotal);
- if (newTotal > highScore) {
- highScore = newTotal;
- // All the colors in the winning bucket are very similar. Last in wins.
- bestColor = rgb;
- }
+ for (int i = 0; i < pixelCount; i++) {
+ int rgb = pixels[i];
+ Color.colorToHSV(rgb, hsv);
+ int hue = (int) hsv[0];
+ if (hue == bestHue) {
+ float s = hsv[1];
+ float v = hsv[2];
+ int bucket = (int) (s * 100) + (int) (v * 10000);
+ // Score by cumulative saturation * value.
+ float score = s * v;
+ Float oldTotal = rgbScores.get(bucket);
+ float newTotal = oldTotal == null ? score : oldTotal + score;
+ rgbScores.put(bucket, newTotal);
+ if (newTotal > highScore) {
+ highScore = newTotal;
+ // All the colors in the winning bucket are very similar. Last in wins.
+ bestColor = rgb;
}
}
}
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index c82731f..74c96a3 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -1593,11 +1593,6 @@
mOutlineProvider = outlineProvider;
}
- public void exitWidgetResizeMode() {
- DragLayer dragLayer = mLauncher.getDragLayer();
- dragLayer.clearResizeFrame();
- }
-
public void onStartReordering() {
super.onStartReordering();
// Reordering handles its own animations, disable the automatic ones.
@@ -2237,8 +2232,7 @@
mDelayedResizeRunnable = new Runnable() {
public void run() {
if (!isPageInTransition()) {
- DragLayer dragLayer = mLauncher.getDragLayer();
- dragLayer.addResizeFrame(hostView, cellLayout);
+ AppWidgetResizeFrame.showForWidget(hostView, cellLayout);
}
}
};
diff --git a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
index 63aa7be..bf03a0e 100644
--- a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
+++ b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
@@ -15,16 +15,13 @@
*/
package com.android.launcher3.allapps.search;
-import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.KeyEvent;
-import android.view.View;
import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputMethodManager;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
@@ -50,7 +47,6 @@
protected String mQuery;
protected SearchAlgorithm mSearchAlgorithm;
- protected InputMethodManager mInputMethodManager;
public void setVisibility(int visibility) {
mInput.setVisibility(visibility);
@@ -68,10 +64,6 @@
mInput.addTextChangedListener(this);
mInput.setOnEditorActionListener(this);
mInput.setOnBackKeyListener(this);
-
- mInputMethodManager = (InputMethodManager)
- mInput.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
-
mSearchAlgorithm = searchAlgorithm;
}
@@ -137,22 +129,9 @@
* Resets the search bar state.
*/
public void reset() {
- unfocusSearchField();
mCb.clearSearchResult();
- mInput.setText("");
+ mInput.reset();
mQuery = null;
- hideKeyboard();
- }
-
- protected void hideKeyboard() {
- mInputMethodManager.hideSoftInputFromWindow(mInput.getWindowToken(), 0);
- }
-
- protected void unfocusSearchField() {
- View nextFocus = mInput.focusSearch(View.FOCUS_DOWN);
- if (nextFocus != null) {
- nextFocus.requestFocus();
- }
}
/**
diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java
index b852714..a7ed87f 100644
--- a/src/com/android/launcher3/dragndrop/DragController.java
+++ b/src/com/android/launcher3/dragndrop/DragController.java
@@ -27,7 +27,6 @@
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
-import android.view.inputmethod.InputMethodManager;
import com.android.launcher3.DragSource;
import com.android.launcher3.DropTarget;
@@ -39,6 +38,7 @@
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.util.TouchController;
+import com.android.launcher3.util.UiThreadHelper;
import java.util.ArrayList;
@@ -138,8 +138,7 @@
}
// Hide soft keyboard, if visible
- mLauncher.getSystemService(InputMethodManager.class)
- .hideSoftInputFromWindow(mWindowToken, 0);
+ UiThreadHelper.hideKeyboardAsync(mLauncher, mWindowToken);
mOptions = options;
if (mOptions.systemDndStartPoint != null) {
diff --git a/src/com/android/launcher3/dragndrop/DragLayer.java b/src/com/android/launcher3/dragndrop/DragLayer.java
index fde7995..60ce3c3 100644
--- a/src/com/android/launcher3/dragndrop/DragLayer.java
+++ b/src/com/android/launcher3/dragndrop/DragLayer.java
@@ -24,13 +24,11 @@
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
-import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.Region;
import android.support.v4.graphics.ColorUtils;
import android.util.AttributeSet;
import android.view.KeyEvent;
-import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
@@ -42,13 +40,10 @@
import android.widget.TextView;
import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.AppWidgetResizeFrame;
import com.android.launcher3.CellLayout;
import com.android.launcher3.DropTargetBar;
-import com.android.launcher3.ExtendedEditText;
import com.android.launcher3.InsettableFrameLayout;
import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherAppWidgetHostView;
import com.android.launcher3.PinchToOverviewListener;
import com.android.launcher3.R;
import com.android.launcher3.ShortcutAndWidgetContainer;
@@ -59,11 +54,9 @@
import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.keyboard.ViewGroupFocusHelper;
-import com.android.launcher3.logging.LoggerUtils;
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.util.TouchController;
-import com.android.launcher3.widget.WidgetsBottomSheet;
import java.util.ArrayList;
@@ -81,10 +74,6 @@
private Launcher mLauncher;
- // Variables relating to resizing widgets
- private final boolean mIsRtl;
- private AppWidgetResizeFrame mCurrentResizeFrame;
-
// Variables relating to animation of views after drop
private ValueAnimator mDropAnim = null;
private final TimeInterpolator mCubicEaseOutInterpolator = new DecelerateInterpolator(1.5f);
@@ -105,7 +94,6 @@
private float mBackgroundAlpha = 0;
// Related to adjacent page hints
- private final Rect mScrollChildPosition = new Rect();
private final ViewGroupFocusHelper mFocusIndicatorHelper;
private final WallpaperColorInfo mWallpaperColorInfo;
@@ -129,7 +117,6 @@
setMotionEventSplittingEnabled(false);
setChildrenDrawingOrderEnabled(true);
- mIsRtl = Utilities.isRtl(getResources());
mFocusIndicatorHelper = new ViewGroupFocusHelper(this);
mWallpaperColorInfo = WallpaperColorInfo.getInstance(getContext());
}
@@ -159,10 +146,6 @@
? null : new PinchToOverviewListener(mLauncher);
}
- public boolean isEventOverPageIndicator(MotionEvent ev) {
- return isEventOverView(mLauncher.getWorkspace().getPageIndicator(), ev);
- }
-
public boolean isEventOverHotseat(MotionEvent ev) {
return isEventOverView(mLauncher.getHotseat(), ev);
}
@@ -180,36 +163,6 @@
return mHitRect.contains((int) ev.getX(), (int) ev.getY());
}
- private boolean handleTouchDown(MotionEvent ev, boolean intercept) {
- AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mLauncher);
- if (topView != null && intercept) {
- ExtendedEditText textView = topView.getActiveTextView();
- if (textView != null) {
- if (!isEventOverView(textView, ev)) {
- textView.dispatchBackKey();
- return true;
- }
- } else if (!isEventOverView(topView, ev)) {
- if (isInAccessibleDrag()) {
- // Do not close the container if in drag and drop.
- if (!isEventOverDropTargetBar(ev)) {
- return true;
- }
- } else {
- mLauncher.getUserEventDispatcher().logActionTapOutside(
- LoggerUtils.newContainerTarget(topView.getLogContainerType()));
- topView.close(true);
-
- // We let touches on the original icon go through so that users can launch
- // the app with one tap if they don't find a shortcut they want.
- View extendedTouch = topView.getExtendedTouchView();
- return extendedTouch == null || !isEventOverView(extendedTouch, ev);
- }
- }
- }
- return false;
- }
-
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
int action = ev.getAction();
@@ -219,9 +172,6 @@
// dray layer even if mAllAppsController is NOT the active controller.
// TODO: handle other input other than touch
mAllAppsController.cancelDiscoveryAnimation();
- if (handleTouchDown(ev, true)) {
- return true;
- }
} else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
if (mTouchCompleteListener != null) {
mTouchCompleteListener.onTouchComplete();
@@ -230,12 +180,10 @@
}
mActiveController = null;
- if (mCurrentResizeFrame != null
- && mCurrentResizeFrame.onControllerInterceptTouchEvent(ev)) {
- mActiveController = mCurrentResizeFrame;
+ AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mLauncher);
+ if (topView != null && topView.onControllerInterceptTouchEvent(ev)) {
+ mActiveController = topView;
return true;
- } else {
- clearResizeFrame();
}
if (mDragController.onControllerInterceptTouchEvent(ev)) {
@@ -248,12 +196,6 @@
return true;
}
- WidgetsBottomSheet widgetsBottomSheet = WidgetsBottomSheet.getOpen(mLauncher);
- if (widgetsBottomSheet != null && widgetsBottomSheet.onControllerInterceptTouchEvent(ev)) {
- mActiveController = widgetsBottomSheet;
- return true;
- }
-
if (mPinchListener != null && mPinchListener.onControllerInterceptTouchEvent(ev)) {
// Stop listening for scrolling etc. (onTouchEvent() handles the rest of the pinch.)
mActiveController = mPinchListener;
@@ -357,12 +299,7 @@
@Override
public boolean onTouchEvent(MotionEvent ev) {
int action = ev.getAction();
-
- if (action == MotionEvent.ACTION_DOWN) {
- if (handleTouchDown(ev, false)) {
- return true;
- }
- } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
+ if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
if (mTouchCompleteListener != null) {
mTouchCompleteListener.onTouchComplete();
}
@@ -542,25 +479,6 @@
}
}
- public void clearResizeFrame() {
- if (mCurrentResizeFrame != null) {
- removeView(mCurrentResizeFrame);
- mCurrentResizeFrame = null;
- }
- }
-
- public void addResizeFrame(LauncherAppWidgetHostView widget, CellLayout cellLayout) {
- clearResizeFrame();
-
- mCurrentResizeFrame = (AppWidgetResizeFrame) LayoutInflater.from(mLauncher)
- .inflate(R.layout.app_widget_resize_frame, this, false);
- mCurrentResizeFrame.setupForWidget(widget, cellLayout, this);
- ((LayoutParams) mCurrentResizeFrame.getLayoutParams()).customPosition = true;
-
- addView(mCurrentResizeFrame);
- mCurrentResizeFrame.snapToWidget(false);
- }
-
public void animateViewIntoPosition(DragView dragView, final int[] pos, float alpha,
float scaleX, float scaleY, int animationEndStyle, Runnable onFinishRunnable,
int duration) {
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 64a2dab..de4de36 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -32,6 +32,7 @@
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
+import android.view.MotionEvent;
import android.view.View;
import android.view.ViewDebug;
import android.view.accessibility.AccessibilityEvent;
@@ -66,6 +67,7 @@
import com.android.launcher3.dragndrop.DragController.DragListener;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.dragndrop.DragOptions;
+import com.android.launcher3.logging.LoggerUtils;
import com.android.launcher3.pageindicators.PageIndicatorDots;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
@@ -368,11 +370,6 @@
return false;
}
- @Override
- public ExtendedEditText getActiveTextView() {
- return isEditingName() ? mFolderName : null;
- }
-
public FolderIcon getFolderIcon() {
return mFolderIcon;
}
@@ -1532,7 +1529,45 @@
}
@Override
- public int getLogContainerType() {
- return ContainerType.FOLDER;
+ public void logActionCommand(int command) {
+ mLauncher.getUserEventDispatcher().logActionCommand(
+ command, getFolderIcon(), ContainerType.FOLDER);
+ }
+
+ @Override
+ public void onBackPressed() {
+ if (isEditingName()) {
+ mFolderName.dispatchBackKey();
+ } else {
+ super.onBackPressed();
+ }
+ }
+
+ @Override
+ public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
+ if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+ DragLayer dl = mLauncher.getDragLayer();
+
+ if (isEditingName()) {
+ if (!dl.isEventOverView(mFolderName, ev)) {
+ mFolderName.dispatchBackKey();
+ return true;
+ }
+ return false;
+ } else if (!dl.isEventOverView(this, ev)) {
+ if (mLauncher.getAccessibilityDelegate().isInAccessibleDrag()) {
+ // Do not close the container if in drag and drop.
+ if (!dl.isEventOverView(mLauncher.getDropTargetBar(), ev)) {
+ return true;
+ }
+ } else {
+ mLauncher.getUserEventDispatcher().logActionTapOutside(
+ LoggerUtils.newContainerTarget(ContainerType.FOLDER));
+ close(true);
+ return true;
+ }
+ }
+ }
+ return false;
}
}
diff --git a/src/com/android/launcher3/graphics/DragPreviewProvider.java b/src/com/android/launcher3/graphics/DragPreviewProvider.java
index 0989921..355c231 100644
--- a/src/com/android/launcher3/graphics/DragPreviewProvider.java
+++ b/src/com/android/launcher3/graphics/DragPreviewProvider.java
@@ -32,10 +32,10 @@
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppWidgetHostView;
-import com.android.launcher3.LauncherModel;
import com.android.launcher3.R;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.folder.FolderIcon;
+import com.android.launcher3.util.UiThreadHelper;
import java.nio.ByteBuffer;
@@ -151,7 +151,7 @@
}
mOutlineGeneratorCallback = new OutlineGeneratorCallback(preview);
- new Handler(LauncherModel.getWorkerLooper()).postAtFrontOfQueue(mOutlineGeneratorCallback);
+ new Handler(UiThreadHelper.getBackgroundLooper()).post(mOutlineGeneratorCallback);
}
protected static Rect getDrawableBounds(Drawable d) {
diff --git a/src/com/android/launcher3/logging/LoggerUtils.java b/src/com/android/launcher3/logging/LoggerUtils.java
index ebb69c4..81333b1 100644
--- a/src/com/android/launcher3/logging/LoggerUtils.java
+++ b/src/com/android/launcher3/logging/LoggerUtils.java
@@ -105,13 +105,13 @@
private static String getItemStr(Target t) {
String typeStr = getFieldName(t.itemType, ItemType.class);
if (t.packageNameHash != 0) {
- typeStr += ", packageHash=" + t.packageNameHash;
+ typeStr += ", packageHash=" + t.packageNameHash + ", predictiveRank=" + t.predictedRank;
}
if (t.componentHash != 0) {
- typeStr += ", componentHash=" + t.componentHash;
+ typeStr += ", componentHash=" + t.componentHash + ", predictiveRank=" + t.predictedRank;
}
if (t.intentHash != 0) {
- typeStr += ", intentHash=" + t.intentHash;
+ typeStr += ", intentHash=" + t.intentHash + ", predictiveRank=" + t.predictedRank;
}
return typeStr + ", grid(" + t.gridX + "," + t.gridY + "), span(" + t.spanX + "," + t.spanY
+ "), pageIdx=" + t.pageIndex;
@@ -125,9 +125,11 @@
public static Target newItemTarget(ItemInfo info) {
Target t = newTarget(Target.Type.ITEM);
+
switch (info.itemType) {
case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
t.itemType = ItemType.APP_ICON;
+ t.predictedRank = -100; // Never assigned
break;
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
t.itemType = ItemType.SHORTCUT;
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index e1b208a..5386fb4 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -66,6 +66,7 @@
import com.android.launcher3.util.MultiHashMap;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.Provider;
+import com.android.launcher3.util.TraceHelper;
import java.util.ArrayList;
import java.util.Collections;
@@ -85,7 +86,6 @@
* - deep shortcuts within apps
*/
public class LoaderTask implements Runnable {
- private static final boolean DEBUG_LOADERS = false;
private static final String TAG = "LoaderTask";
private final LauncherAppState mApp;
@@ -142,73 +142,64 @@
}
}
+ TraceHelper.beginSection(TAG);
try (LauncherModel.LoaderTransaction transaction = mApp.getModel().beginLoader(this)) {
- long now = 0;
- if (DEBUG_LOADERS) Log.d(TAG, "step 1.1: loading workspace");
+ TraceHelper.partitionSection(TAG, "step 1.1: loading workspace");
loadWorkspace();
verifyNotStopped();
- if (DEBUG_LOADERS) Log.d(TAG, "step 1.2: bind workspace workspace");
+ TraceHelper.partitionSection(TAG, "step 1.2: bind workspace workspace");
mResults.bindWorkspace();
// Take a break
- if (DEBUG_LOADERS) {
- Log.d(TAG, "step 1 completed, wait for idle");
- now = SystemClock.uptimeMillis();
- }
+ TraceHelper.partitionSection(TAG, "step 1 completed, wait for idle");
waitForIdle();
- if (DEBUG_LOADERS) Log.d(TAG, "Waited " + (SystemClock.uptimeMillis() - now) + "ms");
verifyNotStopped();
// second step
- if (DEBUG_LOADERS) Log.d(TAG, "step 2.1: loading all apps");
+ TraceHelper.partitionSection(TAG, "step 2.1: loading all apps");
loadAllApps();
- if (DEBUG_LOADERS) Log.d(TAG, "step 2.2: Binding all apps");
+ TraceHelper.partitionSection(TAG, "step 2.2: Binding all apps");
verifyNotStopped();
mResults.bindAllApps();
verifyNotStopped();
- if (DEBUG_LOADERS) Log.d(TAG, "step 2.3: Update icon cache");
+ TraceHelper.partitionSection(TAG, "step 2.3: Update icon cache");
updateIconCache();
// Take a break
- if (DEBUG_LOADERS) {
- Log.d(TAG, "step 2 completed, wait for idle");
- now = SystemClock.uptimeMillis();
- }
+ TraceHelper.partitionSection(TAG, "step 2 completed, wait for idle");
waitForIdle();
- if (DEBUG_LOADERS) Log.d(TAG, "Waited " + (SystemClock.uptimeMillis() - now) + "ms");
verifyNotStopped();
// third step
- if (DEBUG_LOADERS) Log.d(TAG, "step 3.1: loading deep shortcuts");
+ TraceHelper.partitionSection(TAG, "step 3.1: loading deep shortcuts");
loadDeepShortcuts();
verifyNotStopped();
- if (DEBUG_LOADERS) Log.d(TAG, "step 3.2: bind deep shortcuts");
+ TraceHelper.partitionSection(TAG, "step 3.2: bind deep shortcuts");
mResults.bindDeepShortcuts();
// Take a break
- if (DEBUG_LOADERS) Log.d(TAG, "step 3 completed, wait for idle");
+ TraceHelper.partitionSection(TAG, "step 3 completed, wait for idle");
waitForIdle();
verifyNotStopped();
// fourth step
- if (DEBUG_LOADERS) Log.d(TAG, "step 4.1: loading widgets");
+ TraceHelper.partitionSection(TAG, "step 4.1: loading widgets");
mBgDataModel.widgetsModel.update(mApp, null);
verifyNotStopped();
- if (DEBUG_LOADERS) Log.d(TAG, "step 4.2: Binding widgets");
+ TraceHelper.partitionSection(TAG, "step 4.2: Binding widgets");
mResults.bindWidgets();
transaction.commit();
} catch (CancellationException e) {
// Loader stopped, ignore
- if (DEBUG_LOADERS) {
- Log.d(TAG, "Loader cancelled", e);
- }
+ TraceHelper.partitionSection(TAG, "Cancelled");
}
+ TraceHelper.endSection(TAG);
}
public synchronized void stopLocked() {
@@ -217,10 +208,6 @@
}
private void loadWorkspace() {
- if (LauncherAppState.PROFILE_STARTUP) {
- Trace.beginSection("Loading Workspace");
- }
-
final Context context = mApp.getContext();
final ContentResolver contentResolver = context.getContentResolver();
final PackageManagerHelper pmHelper = new PackageManagerHelper(context);
@@ -766,9 +753,6 @@
LauncherModel.updateWorkspaceScreenOrder(context, mBgDataModel.workspaceScreens);
}
}
- if (LauncherAppState.PROFILE_STARTUP) {
- Trace.endSection();
- }
}
private void updateIconCache() {
@@ -793,21 +777,13 @@
}
private void loadAllApps() {
- final long loadTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
-
final List<UserHandle> profiles = mUserManager.getUserProfiles();
// Clear the list of apps
mBgAllAppsList.clear();
for (UserHandle user : profiles) {
// Query for the set of apps
- final long qiaTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
final List<LauncherActivityInfo> apps = mLauncherApps.getActivityList(null, user);
- if (DEBUG_LOADERS) {
- Log.d(TAG, "getActivityList took "
- + (SystemClock.uptimeMillis()-qiaTime) + "ms for user " + user);
- Log.d(TAG, "getActivityList got " + apps.size() + " apps for user " + user);
- }
// Fail if we don't have any apps
// TODO: Fix this. Only fail for the current user.
if (apps == null || apps.isEmpty()) {
@@ -834,10 +810,6 @@
}
mBgAllAppsList.added = new ArrayList<>();
- if (DEBUG_LOADERS) {
- Log.d(TAG, "All apps loaded in in "
- + (SystemClock.uptimeMillis() - loadTime) + "ms");
- }
}
private void loadDeepShortcuts() {
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index 8441598..409e5ae 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -16,6 +16,11 @@
package com.android.launcher3.popup;
+import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS_IF_NOTIFICATIONS;
+import static com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
+import static com.android.launcher3.userevent.nano.LauncherLogProto.ItemType;
+import static com.android.launcher3.userevent.nano.LauncherLogProto.Target;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
@@ -66,6 +71,7 @@
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.graphics.IconPalette;
import com.android.launcher3.graphics.TriangleShape;
+import com.android.launcher3.logging.LoggerUtils;
import com.android.launcher3.notification.NotificationItemView;
import com.android.launcher3.notification.NotificationKeyData;
import com.android.launcher3.shortcuts.DeepShortcutManager;
@@ -81,11 +87,6 @@
import java.util.Map;
import java.util.Set;
-import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS_IF_NOTIFICATIONS;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.ItemType;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.Target;
-
/**
* A container for shortcuts to deep links within apps.
*/
@@ -593,11 +594,6 @@
return arrowView;
}
- @Override
- public View getExtendedTouchView() {
- return mOriginalIcon;
- }
-
/**
* Determines when the deferred drag should be started.
*
@@ -950,7 +946,25 @@
}
@Override
- public int getLogContainerType() {
- return ContainerType.DEEPSHORTCUTS;
+ public void logActionCommand(int command) {
+ mLauncher.getUserEventDispatcher().logActionCommand(
+ command, mOriginalIcon, ContainerType.DEEPSHORTCUTS);
+ }
+
+ @Override
+ public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
+ if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+ DragLayer dl = mLauncher.getDragLayer();
+ if (!dl.isEventOverView(this, ev)) {
+ mLauncher.getUserEventDispatcher().logActionTapOutside(
+ LoggerUtils.newContainerTarget(ContainerType.DEEPSHORTCUTS));
+ close(true);
+
+ // We let touches on the original icon go through so that users can launch
+ // the app with one tap if they don't find a shortcut they want.
+ return mOriginalIcon == null || !dl.isEventOverView(mOriginalIcon, ev);
+ }
+ }
+ return false;
}
}
diff --git a/src/com/android/launcher3/util/TraceHelper.java b/src/com/android/launcher3/util/TraceHelper.java
new file mode 100644
index 0000000..5b66fcd
--- /dev/null
+++ b/src/com/android/launcher3/util/TraceHelper.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.util;
+
+import android.os.SystemClock;
+import android.os.Trace;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.MutableLong;
+
+import com.android.launcher3.config.FeatureFlags;
+
+/**
+ * A wrapper around {@link Trace} to allow easier proguarding for production builds.
+ *
+ * To enable any tracing log, execute the following command:
+ * $ adb shell setprop log.tag.TAGNAME VERBOSE
+ */
+public class TraceHelper {
+
+ private static final boolean ENABLED = FeatureFlags.IS_DOGFOOD_BUILD;
+
+ private static final boolean SYSTEM_TRACE = true;
+ private static final ArrayMap<String, MutableLong> sUpTimes =
+ ENABLED ? new ArrayMap<String, MutableLong>() : null;
+
+ public static void beginSection(String sectionName) {
+ if (ENABLED) {
+ MutableLong time = sUpTimes.get(sectionName);
+ if (time == null) {
+ time = new MutableLong(Log.isLoggable(sectionName, Log.VERBOSE) ? 0 : -1);
+ sUpTimes.put(sectionName, time);
+ }
+ if (time.value >= 0) {
+ if (SYSTEM_TRACE) {
+ Trace.beginSection(sectionName);
+ }
+ time.value = SystemClock.uptimeMillis();
+ }
+ }
+ }
+
+ public static void partitionSection(String sectionName, String partition) {
+ if (ENABLED) {
+ MutableLong time = sUpTimes.get(sectionName);
+ if (time.value >= 0) {
+
+ if (SYSTEM_TRACE) {
+ Trace.endSection();
+ Trace.beginSection(sectionName);
+ }
+
+ long now = SystemClock.uptimeMillis();
+ Log.d(sectionName, partition + " : " + (now - time.value));
+ time.value = now;
+ }
+ }
+ }
+
+ public static void endSection(String sectionName) {
+ if (ENABLED) {
+ endSection(sectionName, "End");
+ }
+ }
+
+ public static void endSection(String sectionName, String msg) {
+ if (ENABLED) {
+ MutableLong time = sUpTimes.get(sectionName);
+ if (time.value >= 0) {
+ if (SYSTEM_TRACE) {
+ Trace.endSection();
+ }
+ Log.d(sectionName, msg + " : " + (SystemClock.uptimeMillis() - time.value));
+ }
+ }
+ }
+}
diff --git a/src/com/android/launcher3/util/UiThreadHelper.java b/src/com/android/launcher3/util/UiThreadHelper.java
new file mode 100644
index 0000000..27140a1
--- /dev/null
+++ b/src/com/android/launcher3/util/UiThreadHelper.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.util;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Process;
+import android.view.inputmethod.InputMethodManager;
+
+/**
+ * Utility class for offloading some class from UI thread
+ */
+public class UiThreadHelper {
+
+ private static HandlerThread sHandlerThread;
+ private static Handler sHandler;
+
+ private static final int MSG_HIDE_KEYBOARD = 1;
+
+ public static Looper getBackgroundLooper() {
+ if (sHandlerThread == null) {
+ sHandlerThread =
+ new HandlerThread("UiThreadHelper", Process.THREAD_PRIORITY_FOREGROUND);
+ sHandlerThread.start();
+ }
+ return sHandlerThread.getLooper();
+ }
+
+ private static Handler getHandler(Context context) {
+ if (sHandler == null) {
+ sHandler = new Handler(getBackgroundLooper(),
+ new UiCallbacks(context.getApplicationContext()));
+ }
+ return sHandler;
+ }
+
+ public static void hideKeyboardAsync(Context context, IBinder token) {
+ Message.obtain(getHandler(context), MSG_HIDE_KEYBOARD, token).sendToTarget();
+ }
+
+ private static class UiCallbacks implements Handler.Callback {
+
+ private final InputMethodManager mIMM;
+
+ UiCallbacks(Context context) {
+ mIMM = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
+ }
+
+ @Override
+ public boolean handleMessage(Message message) {
+ switch (message.what) {
+ case MSG_HIDE_KEYBOARD:
+ mIMM.hideSoftInputFromWindow((IBinder) message.obj, 0);
+ return true;
+ }
+ return false;
+ }
+ }
+}
diff --git a/src/com/android/launcher3/widget/WidgetsBottomSheet.java b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
index 01101ac..432efa7 100644
--- a/src/com/android/launcher3/widget/WidgetsBottomSheet.java
+++ b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
@@ -40,24 +40,23 @@
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.touch.SwipeDetector;
import com.android.launcher3.anim.PropertyListBuilder;
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.graphics.GradientView;
import com.android.launcher3.model.WidgetItem;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
+import com.android.launcher3.touch.SwipeDetector;
+import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.util.Themes;
-import com.android.launcher3.util.TouchController;
import java.util.List;
/**
* Bottom sheet for the "Widgets" system shortcut in the long-press popup.
*/
-public class WidgetsBottomSheet extends AbstractFloatingView implements Insettable, TouchController,
+public class WidgetsBottomSheet extends AbstractFloatingView implements Insettable,
SwipeDetector.Listener, View.OnClickListener, View.OnLongClickListener,
DragController.DragListener {
@@ -242,18 +241,6 @@
}
@Override
- public int getLogContainerType() {
- return LauncherLogProto.ContainerType.WIDGETS; // TODO: be more specific
- }
-
- /**
- * Returns a {@link WidgetsBottomSheet} which is already open or null
- */
- public static WidgetsBottomSheet getOpen(Launcher launcher) {
- return getOpenView(launcher, TYPE_WIDGETS_BOTTOM_SHEET);
- }
-
- @Override
public void setInsets(Rect insets) {
// Extend behind left, right, and bottom insets.
int leftInset = insets.left - mInsets.left;
@@ -302,12 +289,27 @@
}
@Override
+ public void logActionCommand(int command) {
+ // TODO: be more specific
+ mLauncher.getUserEventDispatcher().logActionCommand(command, ContainerType.WIDGETS);
+ }
+
+ @Override
public boolean onControllerTouchEvent(MotionEvent ev) {
return mSwipeDetector.onTouchEvent(ev);
}
@Override
public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
+ if (ev.getAction() == MotionEvent.ACTION_UP) {
+ // If we got ACTION_UP without ever returning true on intercept,
+ // the user never started dragging the bottom sheet.
+ if (!mLauncher.getDragLayer().isEventOverView(this, ev)) {
+ close(true);
+ return false;
+ }
+ }
+
int directionsToDetectScroll = mSwipeDetector.isIdleState() ?
SwipeDetector.DIRECTION_NEGATIVE : 0;
mSwipeDetector.setDetectableScrollConditions(