From 072543f58037697772663ed34ee26317e9d662c5 Mon Sep 17 00:00:00 2001 From: Amith Yamasani Date: Fri, 13 Feb 2015 11:09:45 -0800 Subject: [PATCH] Backup/restore owner info from locksettings Backup the owner info string and whether or not owner info is to be shown on the lockscreen. Watch for changes to the two settings in LockSettingsService and inform backup manager. Bump up version numbers for the new entity. Bug: 19300363 Change-Id: I35485c961d18b26be68873f4d5eeedc5ae513cc8 --- .../settings/SettingsBackupAgent.java | 112 +++++++++++++++++- .../android/server/LockSettingsService.java | 10 ++ 2 files changed, 118 insertions(+), 4 deletions(-) diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java index 78f6ace3c53bf..eac83d8e2563e 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java @@ -32,14 +32,18 @@ import android.os.FileUtils; import android.os.Handler; import android.os.ParcelFileDescriptor; import android.os.Process; +import android.os.UserHandle; import android.provider.Settings; import android.util.Log; +import com.android.internal.widget.LockPatternUtils; + import libcore.io.IoUtils; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.BufferedWriter; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.CharArrayReader; import java.io.DataInputStream; @@ -76,10 +80,11 @@ public class SettingsBackupAgent extends BackupAgentHelper { private static final String KEY_SECURE = "secure"; private static final String KEY_GLOBAL = "global"; private static final String KEY_LOCALE = "locale"; + private static final String KEY_LOCK_SETTINGS = "lock_settings"; // Versioning of the state file. Increment this version // number any time the set of state items is altered. - private static final int STATE_VERSION = 3; + private static final int STATE_VERSION = 4; // Slots in the checksum array. Never insert new items in the middle // of this array; new slots must be appended. @@ -89,20 +94,23 @@ public class SettingsBackupAgent extends BackupAgentHelper { private static final int STATE_WIFI_SUPPLICANT = 3; private static final int STATE_WIFI_CONFIG = 4; private static final int STATE_GLOBAL = 5; + private static final int STATE_LOCK_SETTINGS = 6; - private static final int STATE_SIZE = 6; // The current number of state items + private static final int STATE_SIZE = 7; // The current number of state items // Number of entries in the checksum array at various version numbers private static final int STATE_SIZES[] = { 0, 4, // version 1 5, // version 2 added STATE_WIFI_CONFIG - STATE_SIZE // version 3 added STATE_GLOBAL + 6, // version 3 added STATE_GLOBAL + STATE_SIZE // version 4 added STATE_LOCK_SETTINGS }; // Versioning of the 'full backup' format - private static final int FULL_BACKUP_VERSION = 2; + private static final int FULL_BACKUP_VERSION = 3; private static final int FULL_BACKUP_ADDED_GLOBAL = 2; // added the "global" entry + private static final int FULL_BACKUP_ADDED_LOCK_SETTINGS = 3; // added the "lock_settings" entry private static final int INTEGER_BYTE_COUNT = Integer.SIZE / Byte.SIZE; @@ -124,6 +132,10 @@ public class SettingsBackupAgent extends BackupAgentHelper { private static final String KEY_WIFI_SUPPLICANT = "\uffedWIFI"; private static final String KEY_WIFI_CONFIG = "\uffedCONFIG_WIFI"; + // Keys within the lock settings section + private static final String KEY_LOCK_SETTINGS_OWNER_INFO_ENABLED = "owner_info_enabled"; + private static final String KEY_LOCK_SETTINGS_OWNER_INFO = "owner_info"; + // Name of the temporary file we use during full backup/restore. This is // stored in the full-backup tarfile as well, so should not be changed. private static final String STAGE_FILE = "flattened-data"; @@ -367,6 +379,7 @@ public class SettingsBackupAgent extends BackupAgentHelper { byte[] systemSettingsData = getSystemSettings(); byte[] secureSettingsData = getSecureSettings(); byte[] globalSettingsData = getGlobalSettings(); + byte[] lockSettingsData = getLockSettings(); byte[] locale = mSettingsHelper.getLocaleData(); byte[] wifiSupplicantData = getWifiSupplicant(FILE_WIFI_SUPPLICANT); byte[] wifiConfigData = getFileData(mWifiConfigFile); @@ -387,6 +400,9 @@ public class SettingsBackupAgent extends BackupAgentHelper { stateChecksums[STATE_WIFI_CONFIG] = writeIfChanged(stateChecksums[STATE_WIFI_CONFIG], KEY_WIFI_CONFIG, wifiConfigData, data); + stateChecksums[STATE_LOCK_SETTINGS] = + writeIfChanged(stateChecksums[STATE_LOCK_SETTINGS], KEY_LOCK_SETTINGS, + lockSettingsData, data); writeNewChecksums(stateChecksums, newState); } @@ -492,6 +508,8 @@ public class SettingsBackupAgent extends BackupAgentHelper { } else if (KEY_WIFI_CONFIG.equals(key)) { initWifiRestoreIfNecessary(); mWifiRestore.incorporateWifiConfigFile(data); + } else if (KEY_LOCK_SETTINGS.equals(key)) { + restoreLockSettings(data); } else { data.skipEntityData(); } @@ -513,6 +531,7 @@ public class SettingsBackupAgent extends BackupAgentHelper { byte[] systemSettingsData = getSystemSettings(); byte[] secureSettingsData = getSecureSettings(); byte[] globalSettingsData = getGlobalSettings(); + byte[] lockSettingsData = getLockSettings(); byte[] locale = mSettingsHelper.getLocaleData(); byte[] wifiSupplicantData = getWifiSupplicant(FILE_WIFI_SUPPLICANT); byte[] wifiConfigData = getFileData(mWifiConfigFile); @@ -547,6 +566,9 @@ public class SettingsBackupAgent extends BackupAgentHelper { if (DEBUG_BACKUP) Log.d(TAG, wifiConfigData.length + " bytes of wifi config data"); out.writeInt(wifiConfigData.length); out.write(wifiConfigData); + if (DEBUG_BACKUP) Log.d(TAG, lockSettingsData.length + " bytes of lock settings data"); + out.writeInt(lockSettingsData.length); + out.write(lockSettingsData); out.flush(); // also flushes downstream @@ -629,6 +651,16 @@ public class SettingsBackupAgent extends BackupAgentHelper { in.readFully(buffer, 0, nBytes); restoreFileData(mWifiConfigFile, buffer, nBytes); + if (version >= FULL_BACKUP_ADDED_LOCK_SETTINGS) { + nBytes = in.readInt(); + if (DEBUG_BACKUP) Log.d(TAG, nBytes + " bytes of lock settings data"); + if (nBytes > buffer.length) buffer = new byte[nBytes]; + if (nBytes > 0) { + in.readFully(buffer, 0, nBytes); + restoreLockSettings(buffer, nBytes); + } + } + if (DEBUG_BACKUP) Log.d(TAG, "Full restore complete."); } else { data.close(); @@ -676,6 +708,9 @@ public class SettingsBackupAgent extends BackupAgentHelper { return oldChecksum; } try { + if (DEBUG_BACKUP) { + Log.v(TAG, "Writing entity " + key + " of size " + data.length); + } output.writeEntityHeader(key, data.length); output.writeEntityData(data, data.length); } catch (IOException ioe) { @@ -714,6 +749,31 @@ public class SettingsBackupAgent extends BackupAgentHelper { } } + /** + * Serialize the owner info settings + */ + private byte[] getLockSettings() { + final LockPatternUtils lockPatternUtils = new LockPatternUtils(this); + final boolean ownerInfoEnabled = lockPatternUtils.isOwnerInfoEnabled(); + final String ownerInfo = lockPatternUtils.getOwnerInfo(UserHandle.myUserId()); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream out = new DataOutputStream(baos); + try { + out.writeUTF(KEY_LOCK_SETTINGS_OWNER_INFO_ENABLED); + out.writeUTF(ownerInfoEnabled ? "1" : "0"); + if (ownerInfo != null) { + out.writeUTF(KEY_LOCK_SETTINGS_OWNER_INFO); + out.writeUTF(ownerInfo != null ? ownerInfo : ""); + } + // End marker + out.writeUTF(""); + out.flush(); + } catch (IOException ioe) { + } + return baos.toByteArray(); + } + private void restoreSettings(BackupDataInput data, Uri contentUri, HashSet movedToGlobal) { byte[] settings = new byte[data.getDataSize()]; @@ -796,6 +856,50 @@ public class SettingsBackupAgent extends BackupAgentHelper { } } + /** + * Restores the owner info enabled and owner info settings in LockSettings. + * + * @param buffer + * @param nBytes + */ + private void restoreLockSettings(byte[] buffer, int nBytes) { + final LockPatternUtils lockPatternUtils = new LockPatternUtils(this); + + ByteArrayInputStream bais = new ByteArrayInputStream(buffer, 0, nBytes); + DataInputStream in = new DataInputStream(bais); + try { + String key; + // Read until empty string marker + while ((key = in.readUTF()).length() > 0) { + final String value = in.readUTF(); + if (DEBUG_BACKUP) { + Log.v(TAG, "Restoring lock_settings " + key + " = " + value); + } + switch (key) { + case KEY_LOCK_SETTINGS_OWNER_INFO_ENABLED: + lockPatternUtils.setOwnerInfoEnabled("1".equals(value)); + break; + case KEY_LOCK_SETTINGS_OWNER_INFO: + lockPatternUtils.setOwnerInfo(value, UserHandle.myUserId()); + break; + } + } + in.close(); + } catch (IOException ioe) { + } + } + + private void restoreLockSettings(BackupDataInput data) { + final byte[] settings = new byte[data.getDataSize()]; + try { + data.readEntityData(settings, 0, settings.length); + } catch (IOException ioe) { + Log.e(TAG, "Couldn't read entity data"); + return; + } + restoreLockSettings(settings, settings.length); + } + /** * Given a cursor and a set of keys, extract the required keys and * values and write them to a byte array. diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java index 77b8b31d43eb7..895a5c3a6799f 100644 --- a/services/core/java/com/android/server/LockSettingsService.java +++ b/services/core/java/com/android/server/LockSettingsService.java @@ -17,6 +17,7 @@ package com.android.server; import android.app.admin.DevicePolicyManager; +import android.app.backup.BackupManager; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; @@ -46,6 +47,7 @@ import android.security.KeyStore; import android.text.TextUtils; import android.util.Slog; +import com.android.internal.util.ArrayUtils; import com.android.internal.widget.ILockSettings; import com.android.internal.widget.LockPatternUtils; @@ -257,6 +259,9 @@ public class LockSettingsService extends ILockSettings.Stub { private void setStringUnchecked(String key, int userId, String value) { mStorage.writeKeyValue(key, value, userId); + if (ArrayUtils.contains(SETTINGS_TO_BACKUP, key)) { + BackupManager.dataChanged("com.android.providers.settings"); + } } @Override @@ -463,6 +468,11 @@ public class LockSettingsService extends ILockSettings.Stub { Secure.LOCK_SCREEN_OWNER_INFO }; + private static final String[] SETTINGS_TO_BACKUP = new String[] { + Secure.LOCK_SCREEN_OWNER_INFO_ENABLED, + Secure.LOCK_SCREEN_OWNER_INFO + }; + private IMountService getMountService() { final IBinder service = ServiceManager.getService("mount"); if (service != null) {