merge in ics-release history after reset to master
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 3934237..a516424 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -83,10 +83,10 @@
<dimen name="dragViewOffsetY">-8dp</dimen>
<!-- Padding applied to AppWidgets -->
- <dimen name="app_widget_padding_left">0dp</dimen>
- <dimen name="app_widget_padding_right">0dp</dimen>
- <dimen name="app_widget_padding_top">0dp</dimen>
- <dimen name="app_widget_padding_bottom">0dp</dimen>
+ <dimen name="app_widget_padding_left">3dp</dimen>
+ <dimen name="app_widget_padding_right">3dp</dimen>
+ <dimen name="app_widget_padding_top">1dp</dimen>
+ <dimen name="app_widget_padding_bottom">1dp</dimen>
<!-- Folders -->
<!-- The size of the image which sits behind the preview of the folder contents -->
diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java
index 8158624..949d872 100644
--- a/src/com/android/launcher2/AppsCustomizePagedView.java
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -164,6 +164,10 @@
private final LayoutInflater mLayoutInflater;
private final PackageManager mPackageManager;
+ // Save and Restore
+ private int mSaveInstanceStateItemIndex = -1;
+ private int mRestorePage = -1;
+
// Content
private ContentType mContentType;
private ArrayList<ApplicationInfo> mApps;
@@ -253,6 +257,58 @@
}
}
+ /** Returns the item index of the center item on this page so that we can restore to this
+ * item index when we rotate. */
+ private int getMiddleComponentIndexOnCurrentPage() {
+ int i = -1;
+ if (getPageCount() > 0) {
+ int currentPage = getCurrentPage();
+ switch (mContentType) {
+ case Applications: {
+ PagedViewCellLayout layout = (PagedViewCellLayout) getChildAt(currentPage);
+ PagedViewCellLayoutChildren childrenLayout = layout.getChildrenLayout();
+ int numItemsPerPage = mCellCountX * mCellCountY;
+ int childCount = childrenLayout.getChildCount();
+ if (childCount > 0) {
+ i = (currentPage * numItemsPerPage) + (childCount / 2);
+ }}
+ break;
+ case Widgets: {
+ PagedViewGridLayout layout = (PagedViewGridLayout) getChildAt(currentPage);
+ int numItemsPerPage = mWidgetCountX * mWidgetCountY;
+ int childCount = layout.getChildCount();
+ if (childCount > 0) {
+ i = (currentPage * numItemsPerPage) + (childCount / 2);
+ }}
+ break;
+ }
+ }
+ return i;
+ }
+
+ /** Get the index of the item to restore to if we need to restore the current page. */
+ int getSaveInstanceStateIndex() {
+ if (mSaveInstanceStateItemIndex == -1) {
+ mSaveInstanceStateItemIndex = getMiddleComponentIndexOnCurrentPage();
+ }
+ return mSaveInstanceStateItemIndex;
+ }
+
+ /** Returns the page in the current orientation which is expected to contain the specified
+ * item index. */
+ int getPageForComponent(int index) {
+ switch (mContentType) {
+ case Applications: {
+ int numItemsPerPage = mCellCountX * mCellCountY;
+ return (index / numItemsPerPage);
+ }
+ case Widgets: {
+ int numItemsPerPage = mWidgetCountX * mWidgetCountY;
+ return (index / numItemsPerPage);
+ }}
+ return -1;
+ }
+
/**
* This differs from isDataReady as this is the test done if isDataReady is not set.
*/
@@ -262,6 +318,20 @@
return !mApps.isEmpty();
}
+ /** Restores the page for an item at the specified index */
+ void restorePageForIndex(int index) {
+ if (index < 0) return;
+
+ int page = getPageForComponent(index);
+ if (page > -1) {
+ if (getChildCount() > 0) {
+ invalidatePageData(page);
+ } else {
+ mRestorePage = page;
+ }
+ }
+ }
+
protected void onDataReady(int width, int height) {
// Note that we transpose the counts in portrait so that we get a similar layout
boolean isLandscape = getResources().getConfiguration().orientation ==
@@ -289,7 +359,8 @@
int heightSpec = MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.AT_MOST);
mWidgetSpacingLayout.measure(widthSpec, heightSpec);
mContentWidth = mWidgetSpacingLayout.getContentWidth();
- invalidatePageData();
+ invalidatePageData(Math.max(0, mRestorePage));
+ mRestorePage = -1;
}
@Override
@@ -1076,6 +1147,10 @@
setChildrenDrawnWithCacheEnabled(false);
*/
super.onPageEndMoving();
+
+ // We reset the save index when we change pages so that it will be recalculated on next
+ // rotation
+ mSaveInstanceStateItemIndex = -1;
}
/*
diff --git a/src/com/android/launcher2/IconCache.java b/src/com/android/launcher2/IconCache.java
index b2ebe2a..7f3ae86 100644
--- a/src/com/android/launcher2/IconCache.java
+++ b/src/com/android/launcher2/IconCache.java
@@ -160,13 +160,14 @@
}
}
- public Bitmap getIcon(ComponentName component, ResolveInfo resolveInfo) {
+ public Bitmap getIcon(ComponentName component, ResolveInfo resolveInfo,
+ HashMap<Object, CharSequence> labelCache) {
synchronized (mCache) {
if (resolveInfo == null || component == null) {
return null;
}
- CacheEntry entry = cacheLocked(component, resolveInfo, null);
+ CacheEntry entry = cacheLocked(component, resolveInfo, labelCache);
return entry.icon;
}
}
@@ -183,12 +184,13 @@
mCache.put(componentName, entry);
- if (labelCache != null && labelCache.containsKey(info)) {
- entry.title = labelCache.get(info).toString();
+ ComponentName key = LauncherModel.getComponentNameFromResolveInfo(info);
+ if (labelCache != null && labelCache.containsKey(key)) {
+ entry.title = labelCache.get(key).toString();
} else {
entry.title = info.loadLabel(mPackageManager).toString();
if (labelCache != null) {
- labelCache.put(info, entry.title);
+ labelCache.put(key, entry.title);
}
}
if (entry.title == null) {
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index dc0120b..a0601e0 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -673,8 +673,8 @@
mAppsCustomizeContent.getCurrentPage());
}
- // Note: currently we do not restore the page for the AppsCustomize pane because the
- // change in layout can drastically affect the saved page index
+ int currentIndex = savedState.getInt("apps_customize_currentIndex");
+ mAppsCustomizeContent.restorePageForIndex(currentIndex);
}
}
@@ -1145,6 +1145,8 @@
if (currentTabTag != null) {
outState.putString("apps_customize_currentTab", currentTabTag);
}
+ int currentIndex = mAppsCustomizeContent.getSaveInstanceStateIndex();
+ outState.putInt("apps_customize_currentIndex", currentIndex);
}
}
diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java
index c46e175..f14140c 100644
--- a/src/com/android/launcher2/LauncherModel.java
+++ b/src/com/android/launcher2/LauncherModel.java
@@ -661,11 +661,13 @@
private boolean mStopped;
private boolean mLoadAndBindStepFinished;
private HashMap<Object, CharSequence> mLabelCache;
+ private HashMap<Object, byte[]> mDbIconCache;
LoaderTask(Context context, boolean isLaunching) {
mContext = context;
mIsLaunching = isLaunching;
mLabelCache = new HashMap<Object, CharSequence>();
+ mDbIconCache = new HashMap<Object, byte[]>();
}
boolean isLaunching() {
@@ -731,10 +733,15 @@
final Callbacks cbk = mCallbacks.get();
final boolean loadWorkspaceFirst = cbk != null ? (!cbk.isAllAppsVisible()) : true;
+ // We update the icons in the database afterwards in case they have changed
+ mDbIconCache.clear();
+
keep_running: {
// Elevate priority when Home launches for the first time to avoid
// starving at boot time. Staring at a blank home is not cool.
synchronized (mLock) {
+ if (DEBUG_LOADERS) Log.d(TAG, "Setting thread priority to " +
+ (mIsLaunching ? "DEFAULT" : "BACKGROUND"));
android.os.Process.setThreadPriority(mIsLaunching
? Process.THREAD_PRIORITY_DEFAULT : Process.THREAD_PRIORITY_BACKGROUND);
}
@@ -754,6 +761,7 @@
// settled down.
synchronized (mLock) {
if (mIsLaunching) {
+ if (DEBUG_LOADERS) Log.d(TAG, "Setting thread priority to BACKGROUND");
android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
}
}
@@ -769,6 +777,14 @@
}
}
+
+ // Update the saved icons if necessary
+ if (DEBUG_LOADERS) Log.d(TAG, "Comparing loaded icons to database icons");
+ for (Object key : mDbIconCache.keySet()) {
+ updateSavedIcon(mContext, (ShortcutInfo) key, mDbIconCache.get(key));
+ }
+ mDbIconCache.clear();
+
// Clear out this reference, otherwise we end up holding it until all of the
// callback runnables are done.
mContext = null;
@@ -970,7 +986,7 @@
// now that we've loaded everthing re-save it with the
// icon in case it disappears somehow.
- updateSavedIcon(context, info, c, iconIndex);
+ queueIconToBeChecked(mDbIconCache, info, c, iconIndex);
} else {
// Failed to load the shortcut, probably because the
// activity manager couldn't resolve it (maybe the app
@@ -1522,7 +1538,7 @@
// have icons anyway.
final ResolveInfo resolveInfo = manager.resolveActivity(intent, 0);
if (resolveInfo != null) {
- icon = mIconCache.getIcon(componentName, resolveInfo);
+ icon = mIconCache.getIcon(componentName, resolveInfo, labelCache);
}
// the db
if (icon == null) {
@@ -1539,12 +1555,13 @@
// from the resource
if (resolveInfo != null) {
- if (labelCache != null && labelCache.containsKey(resolveInfo)) {
- info.title = labelCache.get(resolveInfo);
+ ComponentName key = LauncherModel.getComponentNameFromResolveInfo(resolveInfo);
+ if (labelCache != null && labelCache.containsKey(key)) {
+ info.title = labelCache.get(key);
} else {
info.title = resolveInfo.activityInfo.loadLabel(manager);
if (labelCache != null) {
- labelCache.put(resolveInfo, info.title);
+ labelCache.put(key, info.title);
}
}
}
@@ -1749,10 +1766,11 @@
return info;
}
- void updateSavedIcon(Context context, ShortcutInfo info, Cursor c, int iconIndex) {
+ boolean queueIconToBeChecked(HashMap<Object, byte[]> cache, ShortcutInfo info, Cursor c,
+ int iconIndex) {
// If apps can't be on SD, don't even bother.
if (!mAppsCanBeOnExternalStorage) {
- return;
+ return false;
}
// If this icon doesn't have a custom icon, check to see
// what's stored in the DB, and if it doesn't match what
@@ -1761,25 +1779,29 @@
// package manager can't find an icon (for example because
// the app is on SD) then we can use that instead.
if (!info.customIcon && !info.usingFallbackIcon) {
- boolean needSave;
- byte[] data = c.getBlob(iconIndex);
- try {
- if (data != null) {
- Bitmap saved = BitmapFactory.decodeByteArray(data, 0, data.length);
- Bitmap loaded = info.getIcon(mIconCache);
- needSave = !saved.sameAs(loaded);
- } else {
- needSave = true;
- }
- } catch (Exception e) {
+ cache.put(info, c.getBlob(iconIndex));
+ return true;
+ }
+ return false;
+ }
+ void updateSavedIcon(Context context, ShortcutInfo info, byte[] data) {
+ boolean needSave = false;
+ try {
+ if (data != null) {
+ Bitmap saved = BitmapFactory.decodeByteArray(data, 0, data.length);
+ Bitmap loaded = info.getIcon(mIconCache);
+ needSave = !saved.sameAs(loaded);
+ } else {
needSave = true;
}
- if (needSave) {
- Log.d(TAG, "going to save icon bitmap for info=" + info);
- // This is slower than is ideal, but this only happens once
- // or when the app is updated with a new icon.
- updateItemInDatabase(context, info);
- }
+ } catch (Exception e) {
+ needSave = true;
+ }
+ if (needSave) {
+ Log.d(TAG, "going to save icon bitmap for info=" + info);
+ // This is slower than is ideal, but this only happens once
+ // or when the app is updated with a new icon.
+ updateItemInDatabase(context, info);
}
}
@@ -1823,6 +1845,13 @@
return sCollator.compare(a.label.toString(), b.label.toString());
}
};
+ static ComponentName getComponentNameFromResolveInfo(ResolveInfo info) {
+ if (info.activityInfo != null) {
+ return new ComponentName(info.activityInfo.packageName, info.activityInfo.name);
+ } else {
+ return new ComponentName(info.serviceInfo.packageName, info.serviceInfo.name);
+ }
+ }
public static class ShortcutNameComparator implements Comparator<ResolveInfo> {
private PackageManager mPackageManager;
private HashMap<Object, CharSequence> mLabelCache;
@@ -1836,19 +1865,21 @@
}
public final int compare(ResolveInfo a, ResolveInfo b) {
CharSequence labelA, labelB;
- if (mLabelCache.containsKey(a)) {
- labelA = mLabelCache.get(a);
+ ComponentName keyA = LauncherModel.getComponentNameFromResolveInfo(a);
+ ComponentName keyB = LauncherModel.getComponentNameFromResolveInfo(b);
+ if (mLabelCache.containsKey(keyA)) {
+ labelA = mLabelCache.get(keyA);
} else {
labelA = a.loadLabel(mPackageManager).toString();
- mLabelCache.put(a, labelA);
+ mLabelCache.put(keyA, labelA);
}
- if (mLabelCache.containsKey(b)) {
- labelB = mLabelCache.get(b);
+ if (mLabelCache.containsKey(keyB)) {
+ labelB = mLabelCache.get(keyB);
} else {
labelB = b.loadLabel(mPackageManager).toString();
- mLabelCache.put(b, labelB);
+ mLabelCache.put(keyB, labelB);
}
return sCollator.compare(labelA, labelB);
}
diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java
index 6e26363..40e2328 100644
--- a/src/com/android/launcher2/PagedView.java
+++ b/src/com/android/launcher2/PagedView.java
@@ -1649,7 +1649,7 @@
// Set a new page as the current page if necessary
if (currentPage > -1) {
- setCurrentPage(currentPage);
+ setCurrentPage(Math.min(getPageCount() - 1, currentPage));
}
// Mark each of the pages as dirty
diff --git a/src/com/android/launcher2/PagedViewCellLayout.java b/src/com/android/launcher2/PagedViewCellLayout.java
index 63cf9e8..803e700 100644
--- a/src/com/android/launcher2/PagedViewCellLayout.java
+++ b/src/com/android/launcher2/PagedViewCellLayout.java
@@ -192,6 +192,10 @@
return mChildren.getChildCount();
}
+ public PagedViewCellLayoutChildren getChildrenLayout() {
+ return mChildren;
+ }
+
@Override
public View getChildOnPageAt(int i) {
return mChildren.getChildAt(i);