Merge "Moving methods which update internal sets on a separate thread" into ub-now-queens
diff --git a/res/layout/user_folder.xml b/res/layout/user_folder.xml
index 4e5303a..31e9da0 100644
--- a/res/layout/user_folder.xml
+++ b/res/layout/user_folder.xml
@@ -45,6 +45,7 @@
android:hint="@string/folder_hint_text"
android:textSize="14sp"
android:textColor="#ff777777"
+ android:textColorHint="#ff808080"
android:textColorHighlight="#ffCCCCCC"
android:textCursorDrawable="@null"
android:gravity="center_horizontal"
diff --git a/src/com/android/launcher3/AppsCustomizePagedView.java b/src/com/android/launcher3/AppsCustomizePagedView.java
index 7f3b7fb..0648858 100644
--- a/src/com/android/launcher3/AppsCustomizePagedView.java
+++ b/src/com/android/launcher3/AppsCustomizePagedView.java
@@ -1476,7 +1476,9 @@
}
}
+ @Override
public void reset() {
+ super.reset();
// If we have reset, then we should not continue to restore the previous state
mSaveInstanceStateItemIndex = -1;
diff --git a/src/com/android/launcher3/AppsCustomizeTabHost.java b/src/com/android/launcher3/AppsCustomizeTabHost.java
index 9a516fd..df65cba 100644
--- a/src/com/android/launcher3/AppsCustomizeTabHost.java
+++ b/src/com/android/launcher3/AppsCustomizeTabHost.java
@@ -141,14 +141,6 @@
mPagedView.loadAssociatedPages(mPagedView.getCurrentPage());
}
}
-
- public void onTrimMemory() {
- mContent.setVisibility(GONE);
- // Clear the widget pages of all their subviews - this will trigger the widget previews
- // to delete their bitmaps
- mPagedView.clearAllWidgetPages();
- }
-
@Override
public ViewGroup getContent() {
return mPagedView;
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index bb7265e..a2de314 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -50,6 +50,7 @@
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.ContentObserver;
+import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
@@ -488,13 +489,6 @@
// On large interfaces, we want the screen to auto-rotate based on the current orientation
unlockScreenOrientation(true);
- if (shouldShowIntroScreen()) {
- showIntroScreen();
- } else {
- showFirstRunActivity();
- showFirstRunClings();
- }
-
if (mLauncherCallbacks != null) {
mLauncherCallbacks.onCreate(savedInstanceState);
if (mLauncherCallbacks.hasLauncherOverlay()) {
@@ -505,6 +499,13 @@
mWorkspace.setLauncherOverlay(mLauncherOverlay);
}
}
+
+ if (shouldShowIntroScreen()) {
+ showIntroScreen();
+ } else {
+ showFirstRunActivity();
+ showFirstRunClings();
+ }
}
private LauncherCallbacks mLauncherCallbacks;
@@ -3568,6 +3569,9 @@
if (mSearchDropTargetBar != null) {
mSearchDropTargetBar.hideSearchBar(false);
}
+
+ // This can hold unnecessary references to views.
+ mStateAnimation = null;
}
});
@@ -3853,6 +3857,9 @@
content.setCurrentPage(content.getNextPage());
mAppsCustomizeContent.updateCurrentPageScroll();
+
+ // This can hold unnecessary references to views.
+ mStateAnimation = null;
}
});
@@ -3896,8 +3903,16 @@
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
- if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE) {
- mAppsCustomizeTabHost.onTrimMemory();
+ if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
+ // The widget preview db can result in holding onto over
+ // 3MB of memory for caching which isn't necessary.
+ SQLiteDatabase.releaseMemory();
+
+ // We reset the apps customize tray in order to
+ // to free all the memory associated with widget previews
+ if (mAppsCustomizeTabHost != null) {
+ mAppsCustomizeTabHost.reset();
+ }
}
}
@@ -5245,6 +5260,9 @@
if (introScreen != null) {
mDragLayer.showOverlayView(introScreen);
}
+ if (mLauncherOverlayContainer != null) {
+ mLauncherOverlayContainer.setVisibility(View.INVISIBLE);
+ }
}
public void dismissIntroScreen() {
@@ -5256,11 +5274,17 @@
@Override
public void run() {
mDragLayer.dismissOverlayView();
+ if (mLauncherOverlayContainer != null) {
+ mLauncherOverlayContainer.setVisibility(View.VISIBLE);
+ }
showFirstRunClings();
}
}, ACTIVITY_START_DELAY);
} else {
mDragLayer.dismissOverlayView();
+ if (mLauncherOverlayContainer != null) {
+ mLauncherOverlayContainer.setVisibility(View.VISIBLE);
+ }
showFirstRunClings();
}
changeWallpaperVisiblity(true);
diff --git a/src/com/android/launcher3/LauncherBackupHelper.java b/src/com/android/launcher3/LauncherBackupHelper.java
index 8b9c5d9..c260fbc 100644
--- a/src/com/android/launcher3/LauncherBackupHelper.java
+++ b/src/com/android/launcher3/LauncherBackupHelper.java
@@ -146,6 +146,7 @@
private byte[] mBuffer = new byte[512];
private long mLastBackupRestoreTime;
+ private DeviceProfieData mCurrentProfile;
boolean restoreSuccessful;
public LauncherBackupHelper(Context context) {
@@ -241,7 +242,26 @@
* to this device.
*/
private boolean isBackupCompatible(Journal oldState) {
- return true;
+ DeviceProfieData currentProfile = getDeviceProfieData();
+
+ DeviceProfieData oldProfile = oldState.profile;
+
+ if (oldProfile == null || oldProfile.desktopCols == 0) {
+ // Profile info is not valid, ignore the check.
+ return true;
+ }
+
+ boolean isHotsetCompatible = false;
+ if (currentProfile.allappsRank >= oldProfile.hotseatCount) {
+ isHotsetCompatible = true;
+ }
+ if ((currentProfile.hotseatCount >= oldProfile.hotseatCount) &&
+ (currentProfile.allappsRank == oldProfile.allappsRank)) {
+ isHotsetCompatible = true;
+ }
+
+ return isHotsetCompatible && (currentProfile.desktopCols >= oldProfile.desktopCols)
+ && (currentProfile.desktopRows >= oldProfile.desktopRows);
}
/**
@@ -348,6 +368,9 @@
* @return the current device profile information.
*/
private DeviceProfieData getDeviceProfieData() {
+ if (mCurrentProfile != null) {
+ return mCurrentProfile;
+ }
LauncherAppState.setApplicationContext(mContext.getApplicationContext());
LauncherAppState app = LauncherAppState.getInstance();
@@ -359,12 +382,12 @@
profile = app.getDynamicGrid().getDeviceProfile();
}
- DeviceProfieData data = new DeviceProfieData();
- data.desktopRows = profile.numRows;
- data.desktopCols = profile.numColumns;
- data.hotseatCount = profile.numHotseatIcons;
- data.allappsRank = profile.hotseatAllAppsRank;
- return data;
+ mCurrentProfile = new DeviceProfieData();
+ mCurrentProfile.desktopRows = profile.numRows;
+ mCurrentProfile.desktopCols = profile.numColumns;
+ mCurrentProfile.hotseatCount = profile.numHotseatIcons;
+ mCurrentProfile.allappsRank = profile.hotseatAllAppsRank;
+ return mCurrentProfile;
}
/**
@@ -695,18 +718,18 @@
}
/** keys need to be strings, decode and parse. */
- private Key backupKeyToKey(String backupKey) throws KeyParsingException {
+ private Key backupKeyToKey(String backupKey) throws InvalidBackupException {
try {
Key key = Key.parseFrom(Base64.decode(backupKey, Base64.DEFAULT));
if (key.checksum != checkKey(key)) {
key = null;
- throw new KeyParsingException("invalid key read from stream" + backupKey);
+ throw new InvalidBackupException("invalid key read from stream" + backupKey);
}
return key;
} catch (InvalidProtocolBufferNanoException e) {
- throw new KeyParsingException(e);
+ throw new InvalidBackupException(e);
} catch (IllegalArgumentException e) {
- throw new KeyParsingException(e);
+ throw new InvalidBackupException(e);
}
}
@@ -777,7 +800,7 @@
/** Deserialize a Favorite from persistence, after verifying checksum wrapper. */
private ContentValues unpackFavorite(byte[] buffer, int dataSize)
- throws InvalidProtocolBufferNanoException {
+ throws IOException {
Favorite favorite = unpackProto(new Favorite(), buffer, dataSize);
ContentValues values = new ContentValues();
values.put(Favorites._ID, favorite.id);
@@ -810,6 +833,8 @@
UserManagerCompat.getInstance(mContext).getSerialNumberForUser(myUserHandle);
values.put(LauncherSettings.Favorites.PROFILE_ID, userSerialNumber);
+ DeviceProfieData currentProfile = getDeviceProfieData();
+
if (favorite.itemType == Favorites.ITEM_TYPE_APPWIDGET) {
if (!TextUtils.isEmpty(favorite.appWidgetProvider)) {
values.put(Favorites.APPWIDGET_PROVIDER, favorite.appWidgetProvider);
@@ -819,9 +844,31 @@
LauncherAppWidgetInfo.FLAG_ID_NOT_VALID |
LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY |
LauncherAppWidgetInfo.FLAG_UI_NOT_READY);
+
+ // Verify placement
+ if (((favorite.cellX + favorite.spanX) > currentProfile.desktopCols)
+ || ((favorite.cellY + favorite.spanY) > currentProfile.desktopRows)) {
+ restoreSuccessful = false;
+ throw new InvalidBackupException("Widget not in screen bounds, aborting restore");
+ }
} else {
// Let LauncherModel know we've been here.
values.put(LauncherSettings.Favorites.RESTORED, 1);
+
+ // Verify placement
+ if (favorite.container == Favorites.CONTAINER_HOTSEAT) {
+ if ((favorite.screen >= currentProfile.hotseatCount)
+ || (favorite.screen == currentProfile.allappsRank)) {
+ restoreSuccessful = false;
+ throw new InvalidBackupException("Item not in hotseat bounds, aborting restore");
+ }
+ } else {
+ if ((favorite.cellX >= currentProfile.desktopCols)
+ || (favorite.cellY >= currentProfile.desktopRows)) {
+ restoreSuccessful = false;
+ throw new InvalidBackupException("Item not in desktop bounds, aborting restore");
+ }
+ }
}
return values;
@@ -1083,12 +1130,12 @@
.getSerialNumberForUser(UserHandleCompat.myUserHandle());
}
- private class KeyParsingException extends IOException {
- private KeyParsingException(Throwable cause) {
+ private class InvalidBackupException extends IOException {
+ private InvalidBackupException(Throwable cause) {
super(cause);
}
- public KeyParsingException(String reason) {
+ public InvalidBackupException(String reason) {
super(reason);
}
}
diff --git a/src/com/android/launcher3/PagedViewWithDraggableItems.java b/src/com/android/launcher3/PagedViewWithDraggableItems.java
index 2a29c33..7f4a3a0 100644
--- a/src/com/android/launcher3/PagedViewWithDraggableItems.java
+++ b/src/com/android/launcher3/PagedViewWithDraggableItems.java
@@ -91,6 +91,10 @@
return super.onTouchEvent(ev);
}
+ public void reset() {
+ mLastTouchedItem = null;
+ }
+
@Override
public boolean onTouch(View v, MotionEvent event) {
mLastTouchedItem = v;