Merge "Add special column for All Apps button in FocusLogic's sparse matrix." into ub-launcher3-burnaby-polish
diff --git a/WallpaperPicker/res/values-sw720dp-v19/styles.xml b/WallpaperPicker/res/values-sw720dp-v19/styles.xml
deleted file mode 100644
index d8dab22..0000000
--- a/WallpaperPicker/res/values-sw720dp-v19/styles.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-* Copyright (C) 2013 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.
-*/
--->
-
-<resources>
- <style name="Theme" parent="@android:style/Theme.DeviceDefault.Wallpaper.NoTitleBar">
- <item name="android:windowActionModeOverlay">true</item>
- <item name="android:windowTranslucentStatus">true</item>
- <item name="android:windowTranslucentNavigation">true</item>
- </style>
-</resources>
diff --git a/WallpaperPicker/res/values-sw720dp/styles.xml b/WallpaperPicker/res/values-sw720dp/styles.xml
index 12f8884..0058f7e 100644
--- a/WallpaperPicker/res/values-sw720dp/styles.xml
+++ b/WallpaperPicker/res/values-sw720dp/styles.xml
@@ -18,7 +18,11 @@
-->
<resources>
- <style name="Theme" parent="@android:style/Theme.DeviceDefault.Wallpaper.NoTitleBar">
+ <style name="BaseWallpaperTheme" parent="@android:style/Theme.DeviceDefault.Light.NoActionBar">
+ <item name="android:windowBackground">@android:color/transparent</item>
+ <item name="android:colorBackgroundCacheHint">@null</item>
+ <item name="android:windowShowWallpaper">true</item>
+ <item name="android:windowNoTitle">true</item>
<item name="android:windowActionModeOverlay">true</item>
</style>
</resources>
diff --git a/WallpaperPicker/res/values-v21/styles.xml b/WallpaperPicker/res/values-v21/styles.xml
index 70220ed..de4b2f2 100644
--- a/WallpaperPicker/res/values-v21/styles.xml
+++ b/WallpaperPicker/res/values-v21/styles.xml
@@ -34,8 +34,8 @@
</style>
<style name="Theme" parent="@style/BaseWallpaperTheme">
- <item name="android:windowTranslucentStatus">true</item>
- <item name="android:windowTranslucentNavigation">true</item>
+ <item name="android:statusBarColor">#00000000</item>
+ <item name="android:navigationBarColor">#00000000</item>
<item name="android:colorControlActivated">@color/launcher_accent_color</item>
<item name="android:colorAccent">@color/launcher_accent_color</item>
<item name="android:colorPrimary">@color/launcher_accent_color</item>
diff --git a/WallpaperPicker/src/com/android/photos/BitmapRegionTileSource.java b/WallpaperPicker/src/com/android/photos/BitmapRegionTileSource.java
index 2d496a5..6baac6a 100644
--- a/WallpaperPicker/src/com/android/photos/BitmapRegionTileSource.java
+++ b/WallpaperPicker/src/com/android/photos/BitmapRegionTileSource.java
@@ -159,6 +159,7 @@
public enum State { NOT_LOADED, LOADED, ERROR_LOADING };
private State mState = State.NOT_LOADED;
+ /** Returns whether loading was successful. */
public boolean loadInBackground(InBitmapProvider bitmapProvider) {
ExifInterface ei = new ExifInterface();
if (readExif(ei)) {
@@ -193,7 +194,7 @@
try {
mPreview = loadPreviewBitmap(opts);
} catch (IllegalArgumentException e) {
- Log.d(TAG, "Unable to reusage bitmap", e);
+ Log.d(TAG, "Unable to reuse bitmap", e);
opts.inBitmap = null;
mPreview = null;
}
@@ -202,6 +203,10 @@
if (mPreview == null) {
mPreview = loadPreviewBitmap(opts);
}
+ if (mPreview == null) {
+ mState = State.ERROR_LOADING;
+ return false;
+ }
// Verify that the bitmap can be used on GL surface
try {
@@ -212,7 +217,7 @@
Log.d(TAG, "Image cannot be rendered on a GL surface", e);
mState = State.ERROR_LOADING;
}
- return true;
+ return mState == State.LOADED;
}
}
@@ -310,7 +315,7 @@
Bitmap b = BitmapFactory.decodeStream(is, null, options);
Utils.closeSilently(is);
return b;
- } catch (FileNotFoundException e) {
+ } catch (FileNotFoundException | OutOfMemoryError e) {
Log.e("BitmapRegionTileSource", "Failed to load URI " + mUri, e);
return null;
}
@@ -412,7 +417,8 @@
"Failed to create preview of apropriate size! "
+ " in: %dx%d, out: %dx%d",
mWidth, mHeight,
- preview.getWidth(), preview.getHeight()));
+ preview == null ? -1 : preview.getWidth(),
+ preview == null ? -1 : preview.getHeight()));
}
}
}
diff --git a/src/com/android/launcher3/AppInfo.java b/src/com/android/launcher3/AppInfo.java
index c95d558..ede6c71 100644
--- a/src/com/android/launcher3/AppInfo.java
+++ b/src/com/android/launcher3/AppInfo.java
@@ -51,11 +51,6 @@
*/
boolean usingLowResIcon;
- /**
- * The time at which the app was first installed.
- */
- long firstInstallTime;
-
public ComponentName componentName;
static final int DOWNLOADED_FLAG = 1;
@@ -84,7 +79,6 @@
this.container = ItemInfo.NO_ID;
flags = initFlags(info);
- firstInstallTime = info.getFirstInstallTime();
iconCache.getTitleAndIcon(this, info, true /* useLowResIcon */);
intent = makeLaunchIntent(context, info, user);
this.user = user;
@@ -109,7 +103,6 @@
title = Utilities.trim(info.title);
intent = new Intent(info.intent);
flags = info.flags;
- firstInstallTime = info.firstInstallTime;
iconBitmap = info.iconBitmap;
}
@@ -129,7 +122,6 @@
Log.d(tag, label + " size=" + list.size());
for (AppInfo info: list) {
Log.d(tag, " title=\"" + info.title + "\" iconBitmap=" + info.iconBitmap
- + " firstInstallTime=" + info.firstInstallTime
+ " componentName=" + info.componentName.getPackageName());
}
}
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 71a1df3..0a2a017 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -36,7 +36,6 @@
import android.graphics.drawable.TransitionDrawable;
import android.os.Build;
import android.os.Parcelable;
-import android.os.PowerManager;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.util.Log;
@@ -899,9 +898,14 @@
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
- int offset = getMeasuredWidth() - getPaddingLeft() - getPaddingRight() -
- (mCountX * mCellWidth);
- int left = getPaddingLeft() + (int) Math.ceil(offset / 2f);
+ boolean isFullscreen = mShortcutsAndWidgets.getChildCount() > 0 &&
+ ((LayoutParams) mShortcutsAndWidgets.getChildAt(0).getLayoutParams()).isFullscreen;
+ int left = getPaddingLeft();
+ if (!isFullscreen) {
+ int offset = getMeasuredWidth() - getPaddingLeft() - getPaddingRight() -
+ (mCountX * mCellWidth);
+ left += (int) Math.ceil(offset / 2f);
+ }
int top = getPaddingTop();
mTouchFeedbackView.layout(left, top,
@@ -2178,10 +2182,7 @@
// Animations are disabled in power save mode, causing the repeated animation to jump
// spastically between beginning and end states. Since this looks bad, we don't repeat
// the animation in power save mode.
- PowerManager powerManager = (PowerManager) getContext()
- .getSystemService(Context.POWER_SERVICE);
- boolean powerSaverOn = Utilities.ATLEAST_LOLLIPOP && powerManager.isPowerSaveMode();
- if (!powerSaverOn) {
+ if (!Utilities.isPowerSaverOn(getContext())) {
va.setRepeatMode(ValueAnimator.REVERSE);
va.setRepeatCount(ValueAnimator.INFINITE);
}
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index c0ad516..ccbfba1 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -245,7 +245,9 @@
hotseatCellHeightPx = iconSizePx;
// Folder
- folderCellWidthPx = Math.min(cellWidthPx + 6 * edgeMarginPx,
+ int folderCellPadding = isTablet || isLandscape ? 6 * edgeMarginPx : 3 * edgeMarginPx;
+ // Don't let the folder get too close to the edges of the screen.
+ folderCellWidthPx = Math.min(cellWidthPx + folderCellPadding,
(availableWidthPx - 4 * edgeMarginPx) / inv.numFolderColumns);
folderCellHeightPx = cellHeightPx + edgeMarginPx;
folderBackgroundOffset = -edgeMarginPx;
diff --git a/src/com/android/launcher3/FocusHelper.java b/src/com/android/launcher3/FocusHelper.java
index 3d12aa3..4709488 100644
--- a/src/com/android/launcher3/FocusHelper.java
+++ b/src/com/android/launcher3/FocusHelper.java
@@ -174,7 +174,7 @@
}
/**
- * Handles key events in the workspace hot seat (bottom of the screen).
+ * Handles key events in the workspace hotseat (bottom of the screen).
* <p>Currently we don't special case for the phone UI in different orientations, even though
* the hotseat is on the side in landscape mode. This is to ensure that accessibility
* consistency is maintained across rotations.
@@ -261,12 +261,38 @@
countY, matrix, iconIndex, pageIndex, pageCount, Utilities.isRtl(v.getResources()));
View newIcon = null;
- if (newIconIndex == FocusLogic.NEXT_PAGE_FIRST_ITEM) {
- parent = getCellLayoutChildrenForIndex(workspace, pageIndex + 1);
- newIcon = parent.getChildAt(0);
- // TODO(hyunyoungs): handle cases where the child is not an icon but
- // a folder or a widget.
- workspace.snapToPage(pageIndex + 1);
+ switch (newIconIndex) {
+ case FocusLogic.NEXT_PAGE_FIRST_ITEM:
+ parent = getCellLayoutChildrenForIndex(workspace, pageIndex + 1);
+ newIcon = parent.getChildAt(0);
+ // TODO(hyunyoungs): handle cases where the child is not an icon but
+ // a folder or a widget.
+ workspace.snapToPage(pageIndex + 1);
+ break;
+ case FocusLogic.PREVIOUS_PAGE_FIRST_ITEM:
+ parent = getCellLayoutChildrenForIndex(workspace, pageIndex - 1);
+ newIcon = parent.getChildAt(0);
+ // TODO(hyunyoungs): handle cases where the child is not an icon but
+ // a folder or a widget.
+ workspace.snapToPage(pageIndex - 1);
+ break;
+ case FocusLogic.PREVIOUS_PAGE_LAST_ITEM:
+ parent = getCellLayoutChildrenForIndex(workspace, pageIndex - 1);
+ newIcon = parent.getChildAt(parent.getChildCount() - 1);
+ // TODO(hyunyoungs): handle cases where the child is not an icon but
+ // a folder or a widget.
+ workspace.snapToPage(pageIndex - 1);
+ break;
+ case FocusLogic.PREVIOUS_PAGE_LEFT_COLUMN:
+ case FocusLogic.PREVIOUS_PAGE_RIGHT_COLUMN:
+ // Go to the previous page but keep the focus on the same hotseat icon.
+ workspace.snapToPage(pageIndex - 1);
+ break;
+ case FocusLogic.NEXT_PAGE_LEFT_COLUMN:
+ case FocusLogic.NEXT_PAGE_RIGHT_COLUMN:
+ // Go to the next page but keep the focus on the same hotseat icon.
+ workspace.snapToPage(pageIndex + 1);
+ break;
}
if (parent == iconParent && newIconIndex >= iconParent.getChildCount()) {
newIconIndex -= iconParent.getChildCount();
@@ -366,7 +392,7 @@
if (parent != null) {
iconLayout = (CellLayout) parent.getParent();
matrix = FocusLogic.createSparseMatrix(iconLayout,
- iconLayout.getCountX(), row);
+ iconLayout.getCountX(), row);
newIconIndex = FocusLogic.handleKeyEvent(keyCode, countX + 1, countY,
matrix, FocusLogic.PIVOT, newPageIndex, pageCount,
Utilities.isRtl(v.getResources()));
diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java
index 9377bad..da895c6 100644
--- a/src/com/android/launcher3/Folder.java
+++ b/src/com/android/launcher3/Folder.java
@@ -318,9 +318,10 @@
sendCustomAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
String.format(getContext().getString(R.string.folder_renamed), newTitle));
}
- // In order to clear the focus from the text field, we set the focus on ourself. This
- // ensures that every time the field is clicked, focus is gained, giving reliable behavior.
- requestFocus();
+
+ // This ensures that focus is gained every time the field is clicked, which selects all
+ // the text and brings up the soft keyboard if necessary.
+ mFolderName.clearFocus();
Selection.setSelection((Spannable) mFolderName.getText(), 0, 0);
mIsEditingName = false;
@@ -451,6 +452,11 @@
mContent.snapToPageImmediately(0);
}
+ // This is set to true in close(), but isn't reset to false until onDropCompleted(). This
+ // leads to an consistent state if you drag out of the folder and drag back in without
+ // dropping. One resulting issue is that replaceFolderWithFinalItem() can be called twice.
+ mDeleteFolderOnDropCompleted = false;
+
Animator openFolderAnim = null;
final Runnable onCompleteRunnable;
if (!Utilities.ATLEAST_LOLLIPOP) {
@@ -640,7 +646,7 @@
@Override
public void onAnimationEnd(Animator animation) {
setLayerType(LAYER_TYPE_NONE, null);
- close();
+ close(true);
}
@Override
public void onAnimationStart(Animator animation) {
@@ -654,7 +660,7 @@
oa.start();
}
- public void close() {
+ public void close(boolean wasAnimated) {
// TODO: Clear all active animations.
DragLayer parent = (DragLayer) getParent();
if (parent != null) {
@@ -662,7 +668,9 @@
}
mDragController.removeDropTarget(this);
clearFocus();
- mFolderIcon.requestFocus();
+ if (wasAnimated) {
+ mFolderIcon.requestFocus();
+ }
if (mRearrangeOnClose) {
rearrangeChildren();
@@ -1144,10 +1152,10 @@
// addInScreenFromBind() to ensure that hotseat items are placed correctly.
mLauncher.getWorkspace().addInScreenFromBind(newIcon, mInfo.container,
mInfo.screenId, mInfo.cellX, mInfo.cellY, mInfo.spanX, mInfo.spanY);
- }
- // Focus the newly created child
- newIcon.requestFocus();
+ // Focus the newly created child
+ newIcon.requestFocus();
+ }
}
}
};
@@ -1164,15 +1172,37 @@
return mDestroyed;
}
- // This method keeps track of the last item in the folder for the purposes
+ // This method keeps track of the first and last item in the folder for the purposes
// of keyboard focus
public void updateTextViewFocus() {
- View lastChild = mContent.getLastItem();
- if (lastChild != null) {
+ final View firstChild = mContent.getFirstItem();
+ final View lastChild = mContent.getLastItem();
+ if (firstChild != null && lastChild != null) {
mFolderName.setNextFocusDownId(lastChild.getId());
mFolderName.setNextFocusRightId(lastChild.getId());
mFolderName.setNextFocusLeftId(lastChild.getId());
mFolderName.setNextFocusUpId(lastChild.getId());
+ // Hitting TAB from the folder name wraps around to the first item on the current
+ // folder page, and hitting SHIFT+TAB from that item wraps back to the folder name.
+ mFolderName.setNextFocusForwardId(firstChild.getId());
+ // When clicking off the folder when editing the name, this Folder gains focus. When
+ // pressing an arrow key from that state, give the focus to the first item.
+ this.setNextFocusDownId(firstChild.getId());
+ this.setNextFocusRightId(firstChild.getId());
+ this.setNextFocusLeftId(firstChild.getId());
+ this.setNextFocusUpId(firstChild.getId());
+ // When pressing shift+tab in the above state, give the focus to the last item.
+ setOnKeyListener(new OnKeyListener() {
+ @Override
+ public boolean onKey(View v, int keyCode, KeyEvent event) {
+ boolean isShiftPlusTab = keyCode == KeyEvent.KEYCODE_TAB &&
+ event.hasModifiers(KeyEvent.META_SHIFT_ON);
+ if (isShiftPlusTab && Folder.this.isFocused()) {
+ return lastChild.requestFocus();
+ }
+ return false;
+ }
+ });
}
}
@@ -1293,7 +1323,11 @@
rearrangeChildren();
}
if (getItemCount() <= 1) {
- replaceFolderWithFinalItem();
+ if (mInfo.opened) {
+ mLauncher.closeFolder(this, true);
+ } else {
+ replaceFolderWithFinalItem();
+ }
}
}
@@ -1337,6 +1371,8 @@
public void onFocusChange(View v, boolean hasFocus) {
if (v == mFolderName && hasFocus) {
startEditingFolderName();
+ } else if (v == mFolderName && !hasFocus) {
+ dismissEditingName();
}
}
diff --git a/src/com/android/launcher3/FolderPagedView.java b/src/com/android/launcher3/FolderPagedView.java
index cc9c573..d503d2c 100644
--- a/src/com/android/launcher3/FolderPagedView.java
+++ b/src/com/android/launcher3/FolderPagedView.java
@@ -402,16 +402,28 @@
return !ALLOW_FOLDER_SCROLL && getItemCount() >= mMaxItemsPerPage;
}
+ public View getFirstItem() {
+ if (getChildCount() < 1) {
+ return null;
+ }
+ ShortcutAndWidgetContainer currContainer = getCurrentCellLayout().getShortcutsAndWidgets();
+ if (mGridCountX > 0) {
+ return currContainer.getChildAt(0, 0);
+ } else {
+ return currContainer.getChildAt(0);
+ }
+ }
+
public View getLastItem() {
if (getChildCount() < 1) {
return null;
}
- ShortcutAndWidgetContainer lastContainer = getCurrentCellLayout().getShortcutsAndWidgets();
- int lastRank = lastContainer.getChildCount() - 1;
+ ShortcutAndWidgetContainer currContainer = getCurrentCellLayout().getShortcutsAndWidgets();
+ int lastRank = currContainer.getChildCount() - 1;
if (mGridCountX > 0) {
- return lastContainer.getChildAt(lastRank % mGridCountX, lastRank / mGridCountX);
+ return currContainer.getChildAt(lastRank % mGridCountX, lastRank / mGridCountX);
} else {
- return lastContainer.getChildAt(lastRank);
+ return currContainer.getChildAt(lastRank);
}
}
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index 59ab839..a77332f 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -179,15 +179,7 @@
private Bitmap makeDefaultIcon(UserHandleCompat user) {
Drawable unbadged = getFullResDefaultActivityIcon();
- Drawable d = mUserManager.getBadgedDrawableForUser(unbadged, user);
- Bitmap b = Bitmap.createBitmap(Math.max(d.getIntrinsicWidth(), 1),
- Math.max(d.getIntrinsicHeight(), 1),
- Bitmap.Config.ARGB_8888);
- Canvas c = new Canvas(b);
- d.setBounds(0, 0, b.getWidth(), b.getHeight());
- d.draw(c);
- c.setBitmap(null);
- return b;
+ return Utilities.createBadgedIconBitmap(unbadged, user, mContext);
}
/**
@@ -380,7 +372,8 @@
}
if (entry == null) {
entry = new CacheEntry();
- entry.icon = Utilities.createIconBitmap(app.getBadgedIcon(mIconDpi), mContext);
+ entry.icon = Utilities.createBadgedIconBitmap(
+ app.getIcon(mIconDpi), app.getUser(), mContext);
}
entry.title = app.getLabel();
entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, app.getUser());
@@ -542,7 +535,8 @@
// Check the DB first.
if (!getEntryFromDB(cacheKey, entry, useLowResIcon)) {
if (info != null) {
- entry.icon = Utilities.createIconBitmap(info.getBadgedIcon(mIconDpi), mContext);
+ entry.icon = Utilities.createBadgedIconBitmap(
+ info.getIcon(mIconDpi), info.getUser(), mContext);
} else {
if (usePackageIcon) {
CacheEntry packageEntry = getEntryForPackageLocked(
@@ -623,9 +617,8 @@
if (appInfo == null) {
throw new NameNotFoundException("ApplicationInfo is null");
}
- Drawable drawable = mUserManager.getBadgedDrawableForUser(
- appInfo.loadIcon(mPackageManager), user);
- entry.icon = Utilities.createIconBitmap(drawable, mContext);
+ entry.icon = Utilities.createBadgedIconBitmap(
+ appInfo.loadIcon(mPackageManager), user, mContext);
entry.title = appInfo.loadLabel(mPackageManager);
entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, user);
entry.isLowResIcon = false;
diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java
index 9a75193..571d99a 100644
--- a/src/com/android/launcher3/InstallShortcutReceiver.java
+++ b/src/com/android/launcher3/InstallShortcutReceiver.java
@@ -171,7 +171,6 @@
private static void queuePendingShortcutInfo(PendingInstallShortcutInfo info, Context context) {
// Queue the item up for adding if launcher has not loaded properly yet
- LauncherAppState.setApplicationContext(context.getApplicationContext());
LauncherAppState app = LauncherAppState.getInstance();
boolean launcherNotLoaded = app.getModel().getCallback() == null;
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index e983eb1..0d183db 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -17,7 +17,6 @@
package com.android.launcher3;
import android.annotation.TargetApi;
-import android.app.ActivityManager;
import android.content.Context;
import android.graphics.Point;
import android.util.DisplayMetrics;
@@ -84,9 +83,6 @@
DeviceProfile landscapeProfile;
DeviceProfile portraitProfile;
- // On Marshmallow the status bar is no longer opaque, when drawn on the right.
- public boolean isRightInsetOpaque;
-
InvariantDeviceProfile() {
}
@@ -170,9 +166,6 @@
largeSide, smallSide, true /* isLandscape */);
portraitProfile = new DeviceProfile(context, this, smallestSize, largestSize,
smallSide, largeSide, false /* isLandscape */);
-
- isRightInsetOpaque = !Utilities.ATLEAST_MARSHMALLOW ||
- context.getSystemService(ActivityManager.class).isLowRamDevice();
}
ArrayList<InvariantDeviceProfile> getPredefinedDeviceProfiles() {
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 9824e3e..a379acc 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -85,7 +85,6 @@
import android.view.ViewGroup;
import android.view.ViewStub;
import android.view.ViewTreeObserver;
-import android.view.Window;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.OvershootInterpolator;
@@ -418,7 +417,6 @@
super.onCreate(savedInstanceState);
- LauncherAppState.setApplicationContext(getApplicationContext());
LauncherAppState app = LauncherAppState.getInstance();
// Load configuration-specific DeviceProfile
@@ -1623,18 +1621,28 @@
// The AppWidgetHostView has already been inflated and instantiated
launcherInfo.hostView = hostView;
}
- launcherInfo.hostView.setTag(launcherInfo);
launcherInfo.hostView.setVisibility(View.VISIBLE);
- launcherInfo.notifyWidgetSizeChanged(this);
-
- mWorkspace.addInScreen(launcherInfo.hostView, container, screenId, info.cellX,
- info.cellY, launcherInfo.spanX, launcherInfo.spanY, isWorkspaceLocked());
-
- addWidgetToAutoAdvanceIfNeeded(launcherInfo.hostView, appWidgetInfo);
+ addAppWidgetToWorkspace(launcherInfo, appWidgetInfo, isWorkspaceLocked());
}
resetAddInfo();
}
+ private void addAppWidgetToWorkspace(LauncherAppWidgetInfo item,
+ LauncherAppWidgetProviderInfo appWidgetInfo, boolean insert) {
+ item.hostView.setTag(item);
+ item.onBindAppWidget(this);
+
+ item.hostView.setFocusable(true);
+ item.hostView.setOnFocusChangeListener(mFocusHandler);
+
+ mWorkspace.addInScreen(item.hostView, item.container, item.screenId,
+ item.cellX, item.cellY, item.spanX, item.spanY, insert);
+
+ if (!item.isCustomWidget()) {
+ addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);
+ }
+ }
+
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -1684,31 +1692,10 @@
}
registerReceiver(mReceiver, filter);
FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView());
- setupTransparentSystemBarsForLollipop();
mAttached = true;
mVisible = true;
}
- /**
- * Sets up transparent navigation and status bars in Lollipop.
- * This method is a no-op for other platform versions.
- */
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
- private void setupTransparentSystemBarsForLollipop() {
- if (Utilities.ATLEAST_LOLLIPOP) {
- Window window = getWindow();
- window.getAttributes().systemUiVisibility |=
- (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
- | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
- window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
- | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
- window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
- window.setStatusBarColor(Color.TRANSPARENT);
- window.setNavigationBarColor(Color.TRANSPARENT);
- }
- }
-
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
@@ -3125,6 +3112,10 @@
}
oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));
oa.start();
+ if (Utilities.isPowerSaverOn(this)) {
+ // Animations are disabled in battery saver mode, so just skip to the end state.
+ oa.end();
+ }
}
private void shrinkAndFadeInFolderIcon(final FolderIcon fi, boolean animate) {
@@ -3226,7 +3217,7 @@
if (animate) {
folder.animateClosed();
} else {
- folder.close();
+ folder.close(false);
}
// Notify the accessibility manager that this folder "window" has disappeared and no
@@ -4124,15 +4115,7 @@
item.hostView.setOnClickListener(this);
}
- item.hostView.setTag(item);
- item.onBindAppWidget(this);
-
- workspace.addInScreen(item.hostView, item.container, item.screenId, item.cellX,
- item.cellY, item.spanX, item.spanY, false);
- if (!item.isCustomWidget()) {
- addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);
- }
-
+ addAppWidgetToWorkspace(item, appWidgetInfo, false);
workspace.requestLayout();
if (DEBUG_WIDGETS) {
diff --git a/src/com/android/launcher3/LauncherAppWidgetHostView.java b/src/com/android/launcher3/LauncherAppWidgetHostView.java
index cf461a5..c49d43f 100644
--- a/src/com/android/launcher3/LauncherAppWidgetHostView.java
+++ b/src/com/android/launcher3/LauncherAppWidgetHostView.java
@@ -19,6 +19,8 @@
import android.appwidget.AppWidgetHostView;
import android.appwidget.AppWidgetProviderInfo;
import android.content.Context;
+import android.graphics.Rect;
+import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
@@ -28,6 +30,8 @@
import com.android.launcher3.DragLayer.TouchCompleteListener;
+import java.util.ArrayList;
+
/**
* {@inheritDoc}
*/
@@ -43,6 +47,8 @@
private float mSlop;
+ private boolean mChildrenFocused;
+
public LauncherAppWidgetHostView(Context context) {
super(context);
mContext = context;
@@ -175,6 +181,90 @@
@Override
public int getDescendantFocusability() {
- return ViewGroup.FOCUS_BLOCK_DESCENDANTS;
+ return mChildrenFocused ? ViewGroup.FOCUS_BEFORE_DESCENDANTS
+ : ViewGroup.FOCUS_BLOCK_DESCENDANTS;
+ }
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ if (mChildrenFocused && event.getKeyCode() == KeyEvent.KEYCODE_ESCAPE
+ && event.getAction() == KeyEvent.ACTION_UP) {
+ mChildrenFocused = false;
+ requestFocus();
+ return true;
+ }
+ return super.dispatchKeyEvent(event);
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ if (!mChildrenFocused && keyCode == KeyEvent.KEYCODE_ENTER) {
+ event.startTracking();
+ return true;
+ }
+ return super.onKeyDown(keyCode, event);
+ }
+
+ @Override
+ public boolean onKeyUp(int keyCode, KeyEvent event) {
+ if (event.isTracking()) {
+ if (!mChildrenFocused && keyCode == KeyEvent.KEYCODE_ENTER) {
+ mChildrenFocused = true;
+ ArrayList<View> focusableChildren = getFocusables(FOCUS_FORWARD);
+ focusableChildren.remove(this);
+ int childrenCount = focusableChildren.size();
+ switch (childrenCount) {
+ case 0:
+ mChildrenFocused = false;
+ break;
+ case 1: {
+ if (getTag() instanceof ItemInfo) {
+ ItemInfo item = (ItemInfo) getTag();
+ if (item.spanX == 1 && item.spanY == 1) {
+ focusableChildren.get(0).performClick();
+ mChildrenFocused = false;
+ return true;
+ }
+ }
+ // continue;
+ }
+ default:
+ focusableChildren.get(0).requestFocus();
+ return true;
+ }
+ }
+ }
+ return super.onKeyUp(keyCode, event);
+ }
+
+ @Override
+ protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
+ if (gainFocus) {
+ mChildrenFocused = false;
+ }
+ super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
+ }
+
+ @Override
+ public void requestChildFocus(View child, View focused) {
+ super.requestChildFocus(child, focused);
+ dispatchChildFocus(focused != null);
+ }
+
+ @Override
+ public void clearChildFocus(View child) {
+ super.clearChildFocus(child);
+ dispatchChildFocus(false);
+ }
+
+ @Override
+ public boolean dispatchUnhandledMove(View focused, int direction) {
+ return mChildrenFocused;
+ }
+
+ private void dispatchChildFocus(boolean focused) {
+ if (getOnFocusChangeListener() != null) {
+ getOnFocusChangeListener().onFocusChange(this, focused || isFocused());
+ }
}
}
diff --git a/src/com/android/launcher3/LauncherAppWidgetInfo.java b/src/com/android/launcher3/LauncherAppWidgetInfo.java
index 882f7e2..55edf45 100644
--- a/src/com/android/launcher3/LauncherAppWidgetInfo.java
+++ b/src/com/android/launcher3/LauncherAppWidgetInfo.java
@@ -123,17 +123,11 @@
*/
void onBindAppWidget(Launcher launcher) {
if (!mHasNotifiedInitialWidgetSizeChanged) {
- notifyWidgetSizeChanged(launcher);
+ AppWidgetResizeFrame.updateWidgetSizeRanges(hostView, launcher, spanX, spanY);
+ mHasNotifiedInitialWidgetSizeChanged = true;
}
}
- /**
- * Trigger an update callback to the widget to notify it that its size has changed.
- */
- void notifyWidgetSizeChanged(Launcher launcher) {
- AppWidgetResizeFrame.updateWidgetSizeRanges(hostView, launcher, spanX, spanY);
- mHasNotifiedInitialWidgetSizeChanged = true;
- }
@Override
public String toString() {
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index ef79cf8..f095a05 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -84,6 +84,10 @@
@Override
public boolean onCreate() {
final Context context = getContext();
+ // The content provider exists for the entire duration of the launcher main process and
+ // is the first component to get created. Initializing application context here ensures
+ // that LauncherAppState always exists in the main process.
+ LauncherAppState.setApplicationContext(context.getApplicationContext());
StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
mOpenHelper = new DatabaseHelper(context);
StrictMode.setThreadPolicy(oldPolicy);
diff --git a/src/com/android/launcher3/LauncherRootView.java b/src/com/android/launcher3/LauncherRootView.java
index 1c6ca87..71ccd85 100644
--- a/src/com/android/launcher3/LauncherRootView.java
+++ b/src/com/android/launcher3/LauncherRootView.java
@@ -1,17 +1,22 @@
package com.android.launcher3;
+import android.annotation.TargetApi;
+import android.app.ActivityManager;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
+import android.view.View;
public class LauncherRootView extends InsettableFrameLayout {
private final Paint mOpaquePaint;
private boolean mDrawRightInsetBar;
+ private View mAlignedView;
+
public LauncherRootView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -21,10 +26,32 @@
}
@Override
+ protected void onFinishInflate() {
+ if (getChildCount() > 0) {
+ // LauncherRootView contains only one child, which should be aligned
+ // based on the horizontal insets.
+ mAlignedView = getChildAt(0);
+ }
+ super.onFinishInflate();
+ }
+
+ @TargetApi(23)
+ @Override
protected boolean fitSystemWindows(Rect insets) {
- setInsets(insets);
- mDrawRightInsetBar = mInsets.right > 0 && LauncherAppState
- .getInstance().getInvariantDeviceProfile().isRightInsetOpaque;
+ mDrawRightInsetBar = insets.right > 0 &&
+ (!Utilities.ATLEAST_MARSHMALLOW ||
+ getContext().getSystemService(ActivityManager.class).isLowRamDevice());
+ setInsets(mDrawRightInsetBar ? new Rect(0, insets.top, 0, insets.bottom) : insets);
+
+ if (mAlignedView != null) {
+ // Apply margins on aligned view to handle left/right insets.
+ MarginLayoutParams lp = (MarginLayoutParams) mAlignedView.getLayoutParams();
+ if (lp.leftMargin != insets.left || lp.rightMargin != insets.right) {
+ lp.leftMargin = insets.left;
+ lp.rightMargin = insets.right;
+ mAlignedView.setLayoutParams(lp);
+ }
+ }
return true; // I'll take it from here
}
diff --git a/src/com/android/launcher3/LauncherStateTransitionAnimation.java b/src/com/android/launcher3/LauncherStateTransitionAnimation.java
index 3391d06..83b12a9 100644
--- a/src/com/android/launcher3/LauncherStateTransitionAnimation.java
+++ b/src/com/android/launcher3/LauncherStateTransitionAnimation.java
@@ -641,11 +641,11 @@
}
animation.play(reveal);
}
-
- dispatchOnLauncherTransitionPrepare(fromView, animated, true);
- dispatchOnLauncherTransitionPrepare(toView, animated, true);
}
+ dispatchOnLauncherTransitionPrepare(fromView, animated, true);
+ dispatchOnLauncherTransitionPrepare(toView, animated, true);
+
animation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 9258360..b6d3cc4 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -202,9 +202,6 @@
protected final Rect mInsets = new Rect();
protected final boolean mIsRtl;
- // When set to true, full screen content and overscroll effect is shited inside by right inset.
- protected boolean mIgnoreRightInset;
-
// Edge effect
private final LauncherEdgeEffect mEdgeGlowLeft = new LauncherEdgeEffect();
private final LauncherEdgeEffect mEdgeGlowRight = new LauncherEdgeEffect();
@@ -822,8 +819,7 @@
childWidthMode = MeasureSpec.EXACTLY;
childHeightMode = MeasureSpec.EXACTLY;
- childWidth = getViewportWidth() - mInsets.left
- - (mIgnoreRightInset ? mInsets.right : 0);
+ childWidth = getViewportWidth() - mInsets.left - mInsets.right;
childHeight = getViewportHeight();
}
if (referenceChildWidth == 0) {
@@ -1182,9 +1178,8 @@
getEdgeVerticalPostion(sTmpIntPoint);
- int width = mIgnoreRightInset ? (display.width() - mInsets.right) : display.width();
- canvas.translate(sTmpIntPoint[0] - display.top, -width);
- mEdgeGlowRight.setSize(sTmpIntPoint[1] - sTmpIntPoint[0], width);
+ canvas.translate(sTmpIntPoint[0] - display.top, -display.width());
+ mEdgeGlowRight.setSize(sTmpIntPoint[1] - sTmpIntPoint[0], display.width());
if (mEdgeGlowRight.draw(canvas)) {
postInvalidateOnAnimation();
}
@@ -1225,7 +1220,17 @@
@Override
public boolean dispatchUnhandledMove(View focused, int direction) {
- // XXX-RTL: This will be fixed in a future CL
+ if (super.dispatchUnhandledMove(focused, direction)) {
+ return true;
+ }
+
+ if (mIsRtl) {
+ if (direction == View.FOCUS_LEFT) {
+ direction = View.FOCUS_RIGHT;
+ } else if (direction == View.FOCUS_RIGHT) {
+ direction = View.FOCUS_LEFT;
+ }
+ }
if (direction == View.FOCUS_LEFT) {
if (getCurrentPage() > 0) {
snapToPage(getCurrentPage() - 1);
@@ -1237,7 +1242,7 @@
return true;
}
}
- return super.dispatchUnhandledMove(focused, direction);
+ return false;
}
@Override
diff --git a/src/com/android/launcher3/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
index 157b48a..56282fe 100644
--- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java
+++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
@@ -23,7 +23,6 @@
import android.graphics.Rect;
import android.view.View;
import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
public class ShortcutAndWidgetContainer extends ViewGroup {
static final String TAG = "CellLayoutChildren";
diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java
index 5766cf2..6bdcb4b 100644
--- a/src/com/android/launcher3/ShortcutInfo.java
+++ b/src/com/android/launcher3/ShortcutInfo.java
@@ -52,7 +52,7 @@
public static final int FLAG_AUTOINTALL_ICON = 2; //0B10;
/**
- * The icon is being installed. If {@link FLAG_RESTORED_ICON} or {@link FLAG_AUTOINTALL_ICON}
+ * The icon is being installed. If {@link #FLAG_RESTORED_ICON} or {@link #FLAG_AUTOINTALL_ICON}
* is set, then the icon is either being installed or is in a broken state.
*/
public static final int FLAG_INSTALL_SESSION_ACTIVE = 4; // 0B100;
@@ -126,19 +126,14 @@
private int mInstallProgress;
/**
- * Refer {@link AppInfo#firstInstallTime}.
- */
- public long firstInstallTime;
-
- /**
- * TODO move this to {@link status}
+ * TODO move this to {@link #status}
*/
int flags = 0;
/**
* If this shortcut is a placeholder, then intent will be a market intent for the package, and
* this will hold the original intent from the database. Otherwise, null.
- * Refer {@link #FLAG_RESTORE_PENDING}, {@link #FLAG_INSTALL_PENDING}
+ * Refer {@link #FLAG_RESTORED_ICON}, {@link #FLAG_AUTOINTALL_ICON}
*/
Intent promisedIntent;
@@ -172,7 +167,6 @@
mIcon = info.mIcon; // TODO: should make a copy here. maybe we don't need this ctor at all
customIcon = info.customIcon;
flags = info.flags;
- firstInstallTime = info.firstInstallTime;
user = info.user;
status = info.status;
}
@@ -184,7 +178,6 @@
intent = new Intent(info.intent);
customIcon = false;
flags = info.flags;
- firstInstallTime = info.firstInstallTime;
}
public void setIcon(Bitmap b) {
@@ -293,7 +286,6 @@
shortcut.intent = AppInfo.makeLaunchIntent(context, info, info.getUser());
shortcut.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
shortcut.flags = AppInfo.initFlags(info);
- shortcut.firstInstallTime = info.getFirstInstallTime();
return shortcut;
}
}
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index d14d056..54d050f 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -46,6 +46,7 @@
import android.graphics.drawable.PaintDrawable;
import android.os.Build;
import android.os.Bundle;
+import android.os.PowerManager;
import android.os.Process;
import android.text.Spannable;
import android.text.SpannableString;
@@ -59,6 +60,8 @@
import android.view.View;
import android.widget.Toast;
+import com.android.launcher3.compat.UserHandleCompat;
+
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
@@ -194,6 +197,28 @@
}
/**
+ * Returns a bitmap suitable for the all apps view. The icon is badged for {@param user}
+ */
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ public static Bitmap createBadgedIconBitmap(
+ Drawable icon, UserHandleCompat user, Context context) {
+ Bitmap bitmap = createIconBitmap(icon, context);
+ if (Utilities.ATLEAST_LOLLIPOP && user != null
+ && !UserHandleCompat.myUserHandle().equals(user)) {
+ BitmapDrawable drawable = new BitmapDrawable(context.getResources(), bitmap);
+ Drawable badged = context.getPackageManager().getUserBadgedIcon(
+ drawable, user.getUser());
+ if (badged instanceof BitmapDrawable) {
+ return ((BitmapDrawable) badged).getBitmap();
+ } else {
+ return createIconBitmap(badged, context);
+ }
+ } else {
+ return bitmap;
+ }
+ }
+
+ /**
* Returns a bitmap suitable for the all apps view.
*/
public static Bitmap createIconBitmap(Drawable icon, Context context) {
@@ -759,4 +784,10 @@
return context.getSharedPreferences(
LauncherFiles.SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE);
}
+
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ public static boolean isPowerSaverOn(Context context) {
+ PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+ return ATLEAST_LOLLIPOP && powerManager.isPowerSaveMode();
+ }
}
diff --git a/src/com/android/launcher3/WallpaperChangedReceiver.java b/src/com/android/launcher3/WallpaperChangedReceiver.java
index 2d5612f..c24fbff 100644
--- a/src/com/android/launcher3/WallpaperChangedReceiver.java
+++ b/src/com/android/launcher3/WallpaperChangedReceiver.java
@@ -22,8 +22,6 @@
public class WallpaperChangedReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent data) {
- LauncherAppState.setApplicationContext(context.getApplicationContext());
- LauncherAppState appState = LauncherAppState.getInstance();
- appState.onWallpaperChanged();
+ LauncherAppState.getInstance().onWallpaperChanged();
}
}
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index f046fbd..5073902 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -455,7 +455,6 @@
setWallpaperDimension();
setEdgeGlowColor(getResources().getColor(R.color.workspace_edge_effect_color));
- mIgnoreRightInset = app.getInvariantDeviceProfile().isRightInsetOpaque;
}
private void setupLayoutTransition() {
@@ -1544,6 +1543,13 @@
}
@Override
+ protected void determineScrollingStart(MotionEvent ev, float touchSlopScale) {
+ if (!isSwitchingState()) {
+ super.determineScrollingStart(ev, touchSlopScale);
+ }
+ }
+
+ @Override
public void announceForAccessibility(CharSequence text) {
// Don't announce if apps is on top of us.
if (!mLauncher.isAppsViewVisible()) {
diff --git a/src/com/android/launcher3/compat/LauncherActivityInfoCompat.java b/src/com/android/launcher3/compat/LauncherActivityInfoCompat.java
index 07ef0ef..0bc9588 100644
--- a/src/com/android/launcher3/compat/LauncherActivityInfoCompat.java
+++ b/src/com/android/launcher3/compat/LauncherActivityInfoCompat.java
@@ -33,7 +33,6 @@
public abstract Drawable getIcon(int density);
public abstract ApplicationInfo getApplicationInfo();
public abstract long getFirstInstallTime();
- public abstract Drawable getBadgedIcon(int density);
/**
* Creates a LauncherActivityInfoCompat for the primary user.
diff --git a/src/com/android/launcher3/compat/LauncherActivityInfoCompatV16.java b/src/com/android/launcher3/compat/LauncherActivityInfoCompatV16.java
index ea51aac..fee0376 100644
--- a/src/com/android/launcher3/compat/LauncherActivityInfoCompatV16.java
+++ b/src/com/android/launcher3/compat/LauncherActivityInfoCompatV16.java
@@ -93,8 +93,4 @@
public String getName() {
return mActivityInfo.name;
}
-
- public Drawable getBadgedIcon(int density) {
- return getIcon(density);
- }
}
diff --git a/src/com/android/launcher3/compat/LauncherActivityInfoCompatVL.java b/src/com/android/launcher3/compat/LauncherActivityInfoCompatVL.java
index 4448758..67c5c27 100644
--- a/src/com/android/launcher3/compat/LauncherActivityInfoCompatVL.java
+++ b/src/com/android/launcher3/compat/LauncherActivityInfoCompatVL.java
@@ -55,8 +55,4 @@
public long getFirstInstallTime() {
return mLauncherActivityInfo.getFirstInstallTime();
}
-
- public Drawable getBadgedIcon(int density) {
- return mLauncherActivityInfo.getBadgedIcon(density);
- }
}
diff --git a/src/com/android/launcher3/compat/PackageInstallerCompatVL.java b/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
index 6424e03..4aa667e 100644
--- a/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
+++ b/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
@@ -43,7 +43,6 @@
PackageInstallerCompatVL(Context context) {
mInstaller = context.getPackageManager().getPackageInstaller();
- LauncherAppState.setApplicationContext(context.getApplicationContext());
mCache = LauncherAppState.getInstance().getIconCache();
mWorker = new Handler(LauncherModel.getWorkerLooper());
diff --git a/src/com/android/launcher3/compat/UserHandleCompat.java b/src/com/android/launcher3/compat/UserHandleCompat.java
index 567022b..9479908 100644
--- a/src/com/android/launcher3/compat/UserHandleCompat.java
+++ b/src/com/android/launcher3/compat/UserHandleCompat.java
@@ -49,7 +49,7 @@
}
}
- UserHandle getUser() {
+ public UserHandle getUser() {
return mUser;
}
diff --git a/src/com/android/launcher3/compat/UserManagerCompat.java b/src/com/android/launcher3/compat/UserManagerCompat.java
index f708004..6b7cba8 100644
--- a/src/com/android/launcher3/compat/UserManagerCompat.java
+++ b/src/com/android/launcher3/compat/UserManagerCompat.java
@@ -17,8 +17,6 @@
package com.android.launcher3.compat;
import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.os.Build;
import com.android.launcher3.Utilities;
@@ -54,7 +52,6 @@
public abstract List<UserHandleCompat> getUserProfiles();
public abstract long getSerialNumberForUser(UserHandleCompat user);
public abstract UserHandleCompat getUserForSerialNumber(long serialNumber);
- public abstract Drawable getBadgedDrawableForUser(Drawable unbadged, UserHandleCompat user);
public abstract CharSequence getBadgedLabelForUser(CharSequence label, UserHandleCompat user);
public abstract long getUserCreationTime(UserHandleCompat user);
}
diff --git a/src/com/android/launcher3/compat/UserManagerCompatV16.java b/src/com/android/launcher3/compat/UserManagerCompatV16.java
index 85aee57..fcd7555 100644
--- a/src/com/android/launcher3/compat/UserManagerCompatV16.java
+++ b/src/com/android/launcher3/compat/UserManagerCompatV16.java
@@ -16,8 +16,6 @@
package com.android.launcher3.compat;
-import android.graphics.drawable.Drawable;
-
import java.util.ArrayList;
import java.util.List;
@@ -36,11 +34,6 @@
return UserHandleCompat.myUserHandle();
}
- public Drawable getBadgedDrawableForUser(Drawable unbadged,
- UserHandleCompat user) {
- return unbadged;
- }
-
public long getSerialNumberForUser(UserHandleCompat user) {
return 0;
}
diff --git a/src/com/android/launcher3/compat/UserManagerCompatVL.java b/src/com/android/launcher3/compat/UserManagerCompatVL.java
index 98d5eca..c53d702 100644
--- a/src/com/android/launcher3/compat/UserManagerCompatVL.java
+++ b/src/com/android/launcher3/compat/UserManagerCompatVL.java
@@ -21,7 +21,6 @@
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
-import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.UserHandle;
@@ -86,11 +85,6 @@
}
@Override
- public Drawable getBadgedDrawableForUser(Drawable unbadged, UserHandleCompat user) {
- return mPm.getUserBadgedIcon(unbadged, user.getUser());
- }
-
- @Override
public CharSequence getBadgedLabelForUser(CharSequence label, UserHandleCompat user) {
if (user == null) {
return label;
diff --git a/src/com/android/launcher3/util/ManagedProfileHeuristic.java b/src/com/android/launcher3/util/ManagedProfileHeuristic.java
index 849b05c..fb9bbb2 100644
--- a/src/com/android/launcher3/util/ManagedProfileHeuristic.java
+++ b/src/com/android/launcher3/util/ManagedProfileHeuristic.java
@@ -42,6 +42,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -85,6 +86,7 @@
private ArrayList<ShortcutInfo> mHomescreenApps;
private ArrayList<ShortcutInfo> mWorkFolderApps;
+ private HashMap<ShortcutInfo, Long> mShortcutToInstallTimeMap;
private ManagedProfileHeuristic(Context context, UserHandleCompat user) {
mContext = context;
@@ -100,32 +102,29 @@
Context.MODE_PRIVATE);
}
+ private void initVars() {
+ mHomescreenApps = new ArrayList<>();
+ mWorkFolderApps = new ArrayList<>();
+ mShortcutToInstallTimeMap = new HashMap<>();
+ }
+
/**
* Checks the list of user apps and adds icons for newly installed apps on the homescreen or
* workfolder.
*/
public void processUserApps(List<LauncherActivityInfoCompat> apps) {
- mHomescreenApps = new ArrayList<>();
- mWorkFolderApps = new ArrayList<>();
+ initVars();
HashSet<String> packageSet = new HashSet<>();
final boolean userAppsExisted = getUserApps(packageSet);
boolean newPackageAdded = false;
-
for (LauncherActivityInfoCompat info : apps) {
String packageName = info.getComponentName().getPackageName();
if (!packageSet.contains(packageName)) {
packageSet.add(packageName);
newPackageAdded = true;
-
- try {
- PackageInfo pkgInfo = mContext.getPackageManager()
- .getPackageInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES);
- markForAddition(info, pkgInfo.firstInstallTime);
- } catch (NameNotFoundException e) {
- Log.e(TAG, "Unknown package " + packageName, e);
- }
+ markForAddition(info, info.getFirstInstallTime());
}
}
@@ -142,7 +141,22 @@
ArrayList<ShortcutInfo> targetList =
(installTime <= mUserCreationTime + AUTO_ADD_TO_FOLDER_DURATION) ?
mWorkFolderApps : mHomescreenApps;
- targetList.add(ShortcutInfo.fromActivityInfo(info, mContext));
+ ShortcutInfo si = ShortcutInfo.fromActivityInfo(info, mContext);
+ mShortcutToInstallTimeMap.put(si, installTime);
+ targetList.add(si);
+ }
+
+ private void sortList(ArrayList<ShortcutInfo> infos) {
+ Collections.sort(infos, new Comparator<ShortcutInfo>() {
+
+ @Override
+ public int compare(ShortcutInfo lhs, ShortcutInfo rhs) {
+ Long lhsTime = mShortcutToInstallTimeMap.get(lhs);
+ Long rhsTime = mShortcutToInstallTimeMap.get(rhs);
+ return Utilities.longCompare(lhsTime == null ? 0 : lhsTime,
+ rhsTime == null ? 0 : rhsTime);
+ }
+ });
}
/**
@@ -152,13 +166,7 @@
if (mWorkFolderApps.isEmpty()) {
return;
}
- Collections.sort(mWorkFolderApps, new Comparator<ShortcutInfo>() {
-
- @Override
- public int compare(ShortcutInfo lhs, ShortcutInfo rhs) {
- return Utilities.longCompare(lhs.firstInstallTime, rhs.firstInstallTime);
- }
- });
+ sortList(mWorkFolderApps);
// Try to get a work folder.
String folderIdKey = USER_FOLDER_ID_PREFIX + mUserSerial;
@@ -222,6 +230,7 @@
finalizeWorkFolder();
if (addHomeScreenShortcuts && !mHomescreenApps.isEmpty()) {
+ sortList(mHomescreenApps);
mModel.addAndBindAddedWorkspaceItems(mContext, mHomescreenApps);
}
}
@@ -230,9 +239,7 @@
* Updates the list of installed apps and adds any new icons on homescreen or work folder.
*/
public void processPackageAdd(String[] packages) {
- mHomescreenApps = new ArrayList<>();
- mWorkFolderApps = new ArrayList<>();
-
+ initVars();
HashSet<String> packageSet = new HashSet<>();
final boolean userAppsExisted = getUserApps(packageSet);