use of com.android.launcher3.backup.BackupProtos.Journal in project Launcher3 by chislon.
the class LauncherBackupHelper method readJournal.
/**
* Read the old journal from the input file.
*
* In the event of any error, just pretend we didn't have a journal,
* in that case, do a full backup.
*
* @param oldState the read-0only file descriptor pointing to the old journal
* @return a Journal protocol bugffer
*/
private Journal readJournal(ParcelFileDescriptor oldState) {
Journal journal = new Journal();
if (oldState == null) {
return journal;
}
FileInputStream inStream = new FileInputStream(oldState.getFileDescriptor());
try {
int remaining = inStream.available();
if (DEBUG)
Log.d(TAG, "available " + remaining);
if (remaining < MAX_JOURNAL_SIZE) {
byte[] buffer = new byte[remaining];
int bytesRead = 0;
while (remaining > 0) {
try {
int result = inStream.read(buffer, bytesRead, remaining);
if (result > 0) {
if (DEBUG)
Log.d(TAG, "read some bytes: " + result);
remaining -= result;
bytesRead += result;
} else {
// stop reading ands see what there is to parse
Log.w(TAG, "read error: " + result);
remaining = 0;
}
} catch (IOException e) {
Log.w(TAG, "failed to read the journal", e);
buffer = null;
remaining = 0;
}
}
if (DEBUG)
Log.d(TAG, "journal bytes read: " + bytesRead);
if (buffer != null) {
try {
MessageNano.mergeFrom(journal, readCheckedBytes(buffer, 0, bytesRead));
} catch (InvalidProtocolBufferNanoException e) {
Log.d(TAG, "failed to read the journal", e);
journal.clear();
}
}
}
} catch (IOException e) {
Log.d(TAG, "failed to close the journal", e);
} finally {
try {
inStream.close();
} catch (IOException e) {
Log.d(TAG, "failed to close the journal", e);
}
}
return journal;
}
use of com.android.launcher3.backup.BackupProtos.Journal in project Launcher3 by chislon.
the class LauncherBackupHelper method backupWidgets.
/**
* Write all the static widget resources we need to render placeholders
* for a package that is not installed.
*
* @param in notes from last backup
* @param data output stream for key/value pairs
* @param out notes about this backup
* @param keys keys to mark as clean in the notes for next backup
* @throws IOException
*/
private void backupWidgets(Journal in, BackupDataOutput data, Journal out, ArrayList<Key> keys) throws IOException {
// persist static widget info that hasn't been persisted yet
final LauncherAppState appState = LauncherAppState.getInstanceNoCreate();
if (appState == null) {
// try again later
dataChanged();
if (DEBUG)
Log.d(TAG, "Launcher is not initialized, delaying widget backup");
return;
}
final ContentResolver cr = mContext.getContentResolver();
final WidgetPreviewLoader previewLoader = new WidgetPreviewLoader(mContext);
final PagedViewCellLayout widgetSpacingLayout = new PagedViewCellLayout(mContext);
final IconCache iconCache = appState.getIconCache();
final int dpi = mContext.getResources().getDisplayMetrics().densityDpi;
final DeviceProfile profile = appState.getDynamicGrid().getDeviceProfile();
if (DEBUG)
Log.d(TAG, "cellWidthPx: " + profile.cellWidthPx);
// read the old ID set
Set<String> savedIds = getSavedIdsByType(Key.WIDGET, in);
if (DEBUG)
Log.d(TAG, "widgets savedIds.size()=" + savedIds.size());
int startRows = out.rows;
if (DEBUG)
Log.d(TAG, "starting here: " + startRows);
String where = Favorites.ITEM_TYPE + "=" + Favorites.ITEM_TYPE_APPWIDGET;
Cursor cursor = cr.query(Favorites.CONTENT_URI, FAVORITE_PROJECTION, where, null, null);
Set<String> currentIds = new HashSet<String>(cursor.getCount());
try {
cursor.moveToPosition(-1);
while (cursor.moveToNext()) {
final long id = cursor.getLong(ID_INDEX);
final String providerName = cursor.getString(APPWIDGET_PROVIDER_INDEX);
final int spanX = cursor.getInt(SPANX_INDEX);
final int spanY = cursor.getInt(SPANY_INDEX);
final ComponentName provider = ComponentName.unflattenFromString(providerName);
Key key = null;
String backupKey = null;
if (provider != null) {
key = getKey(Key.WIDGET, providerName);
backupKey = keyToBackupKey(key);
currentIds.add(backupKey);
} else {
Log.w(TAG, "empty intent on appwidget: " + id);
}
if (savedIds.contains(backupKey)) {
if (DEBUG)
Log.d(TAG, "already saved widget " + backupKey);
// remember that we already backed this up previously
keys.add(key);
} else if (backupKey != null) {
if (DEBUG)
Log.d(TAG, "I can count this high: " + out.rows);
if ((out.rows - startRows) < MAX_WIDGETS_PER_PASS) {
if (DEBUG)
Log.d(TAG, "saving widget " + backupKey);
previewLoader.setPreviewSize(spanX * profile.cellWidthPx, spanY * profile.cellHeightPx, widgetSpacingLayout);
byte[] blob = packWidget(dpi, previewLoader, iconCache, provider);
keys.add(key);
writeRowToBackup(key, blob, out, data);
} else {
if (DEBUG)
Log.d(TAG, "scheduling another run for widget " + backupKey);
// too many widgets for this pass, request another.
dataChanged();
}
}
}
} finally {
cursor.close();
}
if (DEBUG)
Log.d(TAG, "widget currentIds.size()=" + currentIds.size());
// these IDs must have been deleted
savedIds.removeAll(currentIds);
out.rows += removeDeletedKeysFromBackup(savedIds, data);
}
use of com.android.launcher3.backup.BackupProtos.Journal in project Launcher3 by chislon.
the class LauncherBackupHelper method backupScreens.
/**
* Write all modified screens to the data stream.
*
* @param in notes from last backup
* @param data output stream for key/value pairs
* @param out notes about this backup
* @param keys keys to mark as clean in the notes for next backup
* @throws IOException
*/
private void backupScreens(Journal in, BackupDataOutput data, Journal out, ArrayList<Key> keys) throws IOException {
// read the old ID set
Set<String> savedIds = getSavedIdsByType(Key.SCREEN, in);
if (DEBUG)
Log.d(TAG, "screen savedIds.size()=" + savedIds.size());
// persist things that have changed since the last backup
ContentResolver cr = mContext.getContentResolver();
Cursor cursor = cr.query(WorkspaceScreens.CONTENT_URI, SCREEN_PROJECTION, null, null, null);
Set<String> currentIds = new HashSet<String>(cursor.getCount());
try {
cursor.moveToPosition(-1);
while (cursor.moveToNext()) {
final long id = cursor.getLong(ID_INDEX);
final long updateTime = cursor.getLong(ID_MODIFIED);
Key key = getKey(Key.SCREEN, id);
keys.add(key);
currentIds.add(keyToBackupKey(key));
if (updateTime > in.t) {
byte[] blob = packScreen(cursor);
writeRowToBackup(key, blob, out, data);
}
}
} finally {
cursor.close();
}
if (DEBUG)
Log.d(TAG, "screen currentIds.size()=" + currentIds.size());
// these IDs must have been deleted
savedIds.removeAll(currentIds);
out.rows += removeDeletedKeysFromBackup(savedIds, data);
}
use of com.android.launcher3.backup.BackupProtos.Journal in project Launcher3 by chislon.
the class LauncherBackupHelper method backupIcons.
/**
* Write all the static icon resources we need to render placeholders
* for a package that is not installed.
*
* @param in notes from last backup
* @param data output stream for key/value pairs
* @param out notes about this backup
* @param keys keys to mark as clean in the notes for next backup
* @throws IOException
*/
private void backupIcons(Journal in, BackupDataOutput data, Journal out, ArrayList<Key> keys) throws IOException {
// persist icons that haven't been persisted yet
final LauncherAppState appState = LauncherAppState.getInstanceNoCreate();
if (appState == null) {
// try again later
dataChanged();
if (DEBUG)
Log.d(TAG, "Launcher is not initialized, delaying icon backup");
return;
}
final ContentResolver cr = mContext.getContentResolver();
final IconCache iconCache = appState.getIconCache();
final int dpi = mContext.getResources().getDisplayMetrics().densityDpi;
// read the old ID set
Set<String> savedIds = getSavedIdsByType(Key.ICON, in);
if (DEBUG)
Log.d(TAG, "icon savedIds.size()=" + savedIds.size());
int startRows = out.rows;
if (DEBUG)
Log.d(TAG, "starting here: " + startRows);
String where = Favorites.ITEM_TYPE + "=" + Favorites.ITEM_TYPE_APPLICATION;
Cursor cursor = cr.query(Favorites.CONTENT_URI, FAVORITE_PROJECTION, where, null, null);
Set<String> currentIds = new HashSet<String>(cursor.getCount());
try {
cursor.moveToPosition(-1);
while (cursor.moveToNext()) {
final long id = cursor.getLong(ID_INDEX);
final String intentDescription = cursor.getString(INTENT_INDEX);
try {
Intent intent = Intent.parseUri(intentDescription, 0);
ComponentName cn = intent.getComponent();
Key key = null;
String backupKey = null;
if (cn != null) {
key = getKey(Key.ICON, cn.flattenToShortString());
backupKey = keyToBackupKey(key);
currentIds.add(backupKey);
} else {
Log.w(TAG, "empty intent on application favorite: " + id);
}
if (savedIds.contains(backupKey)) {
if (DEBUG)
Log.d(TAG, "already saved icon " + backupKey);
// remember that we already backed this up previously
keys.add(key);
} else if (backupKey != null) {
if (DEBUG)
Log.d(TAG, "I can count this high: " + out.rows);
if ((out.rows - startRows) < MAX_ICONS_PER_PASS) {
if (DEBUG)
Log.d(TAG, "saving icon " + backupKey);
Bitmap icon = iconCache.getIcon(intent);
keys.add(key);
if (icon != null && !iconCache.isDefaultIcon(icon)) {
byte[] blob = packIcon(dpi, icon);
writeRowToBackup(key, blob, out, data);
}
} else {
if (DEBUG)
Log.d(TAG, "scheduling another run for icon " + backupKey);
// too many icons for this pass, request another.
dataChanged();
}
}
} catch (URISyntaxException e) {
Log.w(TAG, "invalid URI on application favorite: " + id);
} catch (IOException e) {
Log.w(TAG, "unable to save application icon for favorite: " + id);
}
}
} finally {
cursor.close();
}
if (DEBUG)
Log.d(TAG, "icon currentIds.size()=" + currentIds.size());
// these IDs must have been deleted
savedIds.removeAll(currentIds);
out.rows += removeDeletedKeysFromBackup(savedIds, data);
}
use of com.android.launcher3.backup.BackupProtos.Journal in project Launcher3 by chislon.
the class LauncherBackupHelper method writeNewStateDescription.
/**
* Record the restore state for the next backup.
*
* @param newState notes about the backup state after restore.
*/
@Override
public void writeNewStateDescription(ParcelFileDescriptor newState) {
// clear the output journal time, to force a full backup to
// will catch any changes the restore process might have made
Journal out = new Journal();
out.t = 0;
out.key = mKeys.toArray(BackupProtos.Key.emptyArray());
writeJournal(newState, out);
Log.v(TAG, "onRestore: read " + mKeys.size() + " rows");
mKeys.clear();
}
Aggregations