Failing restore, if we have an item outside screen bounds

Bug: 17552590
Change-Id: I2d25847fd05d9579bc29ccbfa62e34809d4855d1
This commit is contained in:
Sunny Goyal 2014-10-29 10:51:54 -07:00
parent 001058054a
commit 5fd733dbae
1 changed files with 62 additions and 15 deletions

View File

@ -146,6 +146,7 @@ public class LauncherBackupHelper implements BackupHelper {
private byte[] mBuffer = new byte[512]; private byte[] mBuffer = new byte[512];
private long mLastBackupRestoreTime; private long mLastBackupRestoreTime;
private DeviceProfieData mCurrentProfile;
boolean restoreSuccessful; boolean restoreSuccessful;
public LauncherBackupHelper(Context context) { public LauncherBackupHelper(Context context) {
@ -241,9 +242,28 @@ public class LauncherBackupHelper implements BackupHelper {
* to this device. * to this device.
*/ */
private boolean isBackupCompatible(Journal oldState) { private boolean isBackupCompatible(Journal oldState) {
DeviceProfieData currentProfile = getDeviceProfieData();
DeviceProfieData oldProfile = oldState.profile;
if (oldProfile == null || oldProfile.desktopCols == 0) {
// Profile info is not valid, ignore the check.
return true; 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);
}
/** /**
* Restore launcher configuration from the restored data stream. * Restore launcher configuration from the restored data stream.
* It assumes that the keys will arrive in lexical order. So if the journal was present in the * It assumes that the keys will arrive in lexical order. So if the journal was present in the
@ -348,6 +368,9 @@ public class LauncherBackupHelper implements BackupHelper {
* @return the current device profile information. * @return the current device profile information.
*/ */
private DeviceProfieData getDeviceProfieData() { private DeviceProfieData getDeviceProfieData() {
if (mCurrentProfile != null) {
return mCurrentProfile;
}
LauncherAppState.setApplicationContext(mContext.getApplicationContext()); LauncherAppState.setApplicationContext(mContext.getApplicationContext());
LauncherAppState app = LauncherAppState.getInstance(); LauncherAppState app = LauncherAppState.getInstance();
@ -359,12 +382,12 @@ public class LauncherBackupHelper implements BackupHelper {
profile = app.getDynamicGrid().getDeviceProfile(); profile = app.getDynamicGrid().getDeviceProfile();
} }
DeviceProfieData data = new DeviceProfieData(); mCurrentProfile = new DeviceProfieData();
data.desktopRows = profile.numRows; mCurrentProfile.desktopRows = profile.numRows;
data.desktopCols = profile.numColumns; mCurrentProfile.desktopCols = profile.numColumns;
data.hotseatCount = profile.numHotseatIcons; mCurrentProfile.hotseatCount = profile.numHotseatIcons;
data.allappsRank = profile.hotseatAllAppsRank; mCurrentProfile.allappsRank = profile.hotseatAllAppsRank;
return data; return mCurrentProfile;
} }
/** /**
@ -695,18 +718,18 @@ public class LauncherBackupHelper implements BackupHelper {
} }
/** keys need to be strings, decode and parse. */ /** keys need to be strings, decode and parse. */
private Key backupKeyToKey(String backupKey) throws KeyParsingException { private Key backupKeyToKey(String backupKey) throws InvalidBackupException {
try { try {
Key key = Key.parseFrom(Base64.decode(backupKey, Base64.DEFAULT)); Key key = Key.parseFrom(Base64.decode(backupKey, Base64.DEFAULT));
if (key.checksum != checkKey(key)) { if (key.checksum != checkKey(key)) {
key = null; key = null;
throw new KeyParsingException("invalid key read from stream" + backupKey); throw new InvalidBackupException("invalid key read from stream" + backupKey);
} }
return key; return key;
} catch (InvalidProtocolBufferNanoException e) { } catch (InvalidProtocolBufferNanoException e) {
throw new KeyParsingException(e); throw new InvalidBackupException(e);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
throw new KeyParsingException(e); throw new InvalidBackupException(e);
} }
} }
@ -777,7 +800,7 @@ public class LauncherBackupHelper implements BackupHelper {
/** Deserialize a Favorite from persistence, after verifying checksum wrapper. */ /** Deserialize a Favorite from persistence, after verifying checksum wrapper. */
private ContentValues unpackFavorite(byte[] buffer, int dataSize) private ContentValues unpackFavorite(byte[] buffer, int dataSize)
throws InvalidProtocolBufferNanoException { throws IOException {
Favorite favorite = unpackProto(new Favorite(), buffer, dataSize); Favorite favorite = unpackProto(new Favorite(), buffer, dataSize);
ContentValues values = new ContentValues(); ContentValues values = new ContentValues();
values.put(Favorites._ID, favorite.id); values.put(Favorites._ID, favorite.id);
@ -810,6 +833,8 @@ public class LauncherBackupHelper implements BackupHelper {
UserManagerCompat.getInstance(mContext).getSerialNumberForUser(myUserHandle); UserManagerCompat.getInstance(mContext).getSerialNumberForUser(myUserHandle);
values.put(LauncherSettings.Favorites.PROFILE_ID, userSerialNumber); values.put(LauncherSettings.Favorites.PROFILE_ID, userSerialNumber);
DeviceProfieData currentProfile = getDeviceProfieData();
if (favorite.itemType == Favorites.ITEM_TYPE_APPWIDGET) { if (favorite.itemType == Favorites.ITEM_TYPE_APPWIDGET) {
if (!TextUtils.isEmpty(favorite.appWidgetProvider)) { if (!TextUtils.isEmpty(favorite.appWidgetProvider)) {
values.put(Favorites.APPWIDGET_PROVIDER, favorite.appWidgetProvider); values.put(Favorites.APPWIDGET_PROVIDER, favorite.appWidgetProvider);
@ -819,9 +844,31 @@ public class LauncherBackupHelper implements BackupHelper {
LauncherAppWidgetInfo.FLAG_ID_NOT_VALID | LauncherAppWidgetInfo.FLAG_ID_NOT_VALID |
LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY | LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY |
LauncherAppWidgetInfo.FLAG_UI_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 { } else {
// Let LauncherModel know we've been here. // Let LauncherModel know we've been here.
values.put(LauncherSettings.Favorites.RESTORED, 1); 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; return values;
@ -1083,12 +1130,12 @@ public class LauncherBackupHelper implements BackupHelper {
.getSerialNumberForUser(UserHandleCompat.myUserHandle()); .getSerialNumberForUser(UserHandleCompat.myUserHandle());
} }
private class KeyParsingException extends IOException { private class InvalidBackupException extends IOException {
private KeyParsingException(Throwable cause) { private InvalidBackupException(Throwable cause) {
super(cause); super(cause);
} }
public KeyParsingException(String reason) { public InvalidBackupException(String reason) {
super(reason); super(reason);
} }
} }