Merge change 6639 into donut
* changes: Restore audio settings and wifi.
This commit is contained in:
@@ -67,6 +67,12 @@ public class Process {
|
|||||||
*/
|
*/
|
||||||
public static final int PHONE_UID = 1001;
|
public static final int PHONE_UID = 1001;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the UID/GID for the WIFI supplicant process.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static final int WIFI_UID = 1010;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the start of a range of UIDs (and GIDs), going from this
|
* Defines the start of a range of UIDs (and GIDs), going from this
|
||||||
* number to {@link #LAST_APPLICATION_UID} that are reserved for assigning
|
* number to {@link #LAST_APPLICATION_UID} that are reserved for assigning
|
||||||
|
|||||||
@@ -16,12 +16,16 @@
|
|||||||
|
|
||||||
package com.android.providers.settings;
|
package com.android.providers.settings;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.EOFException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.zip.CRC32;
|
||||||
|
|
||||||
import android.backup.BackupDataInput;
|
import android.backup.BackupDataInput;
|
||||||
import android.backup.BackupDataOutput;
|
import android.backup.BackupDataOutput;
|
||||||
@@ -34,7 +38,9 @@ import android.database.Cursor;
|
|||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
|
import android.os.FileUtils;
|
||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
|
import android.os.Process;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
@@ -52,6 +58,13 @@ public class SettingsBackupAgent extends BackupHelperAgent {
|
|||||||
private static final String KEY_SYNC = "sync_providers";
|
private static final String KEY_SYNC = "sync_providers";
|
||||||
private static final String KEY_LOCALE = "locale";
|
private static final String KEY_LOCALE = "locale";
|
||||||
|
|
||||||
|
private static final int STATE_SYSTEM = 0;
|
||||||
|
private static final int STATE_SECURE = 1;
|
||||||
|
private static final int STATE_SYNC = 2;
|
||||||
|
private static final int STATE_LOCALE = 3;
|
||||||
|
private static final int STATE_WIFI = 4;
|
||||||
|
private static final int STATE_SIZE = 5; // The number of state items
|
||||||
|
|
||||||
private static String[] sortedSystemKeys = null;
|
private static String[] sortedSystemKeys = null;
|
||||||
private static String[] sortedSecureKeys = null;
|
private static String[] sortedSecureKeys = null;
|
||||||
|
|
||||||
@@ -87,20 +100,22 @@ public class SettingsBackupAgent extends BackupHelperAgent {
|
|||||||
byte[] secureSettingsData = getSecureSettings();
|
byte[] secureSettingsData = getSecureSettings();
|
||||||
byte[] syncProviders = mSettingsHelper.getSyncProviders();
|
byte[] syncProviders = mSettingsHelper.getSyncProviders();
|
||||||
byte[] locale = mSettingsHelper.getLocaleData();
|
byte[] locale = mSettingsHelper.getLocaleData();
|
||||||
|
byte[] wifiData = getFileData(FILE_WIFI_SUPPLICANT);
|
||||||
|
|
||||||
data.writeEntityHeader(KEY_SYSTEM, systemSettingsData.length);
|
long[] stateChecksums = readOldChecksums(oldState);
|
||||||
data.writeEntityData(systemSettingsData, systemSettingsData.length);
|
|
||||||
|
|
||||||
data.writeEntityHeader(KEY_SECURE, secureSettingsData.length);
|
stateChecksums[STATE_SYSTEM] =
|
||||||
data.writeEntityData(secureSettingsData, secureSettingsData.length);
|
writeIfChanged(stateChecksums[STATE_SYSTEM], KEY_SYSTEM, systemSettingsData, data);
|
||||||
|
stateChecksums[STATE_SECURE] =
|
||||||
|
writeIfChanged(stateChecksums[STATE_SECURE], KEY_SECURE, secureSettingsData, data);
|
||||||
|
stateChecksums[STATE_SYNC] =
|
||||||
|
writeIfChanged(stateChecksums[STATE_SYNC], KEY_SYNC, syncProviders, data);
|
||||||
|
stateChecksums[STATE_LOCALE] =
|
||||||
|
writeIfChanged(stateChecksums[STATE_LOCALE], KEY_LOCALE, locale, data);
|
||||||
|
stateChecksums[STATE_WIFI] =
|
||||||
|
writeIfChanged(stateChecksums[STATE_WIFI], FILE_WIFI_SUPPLICANT, wifiData, data);
|
||||||
|
|
||||||
data.writeEntityHeader(KEY_SYNC, syncProviders.length);
|
writeNewChecksums(stateChecksums, newState);
|
||||||
data.writeEntityData(syncProviders, syncProviders.length);
|
|
||||||
|
|
||||||
data.writeEntityHeader(KEY_LOCALE, locale.length);
|
|
||||||
data.writeEntityData(locale, locale.length);
|
|
||||||
|
|
||||||
backupFile(FILE_WIFI_SUPPLICANT, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -115,11 +130,15 @@ public class SettingsBackupAgent extends BackupHelperAgent {
|
|||||||
final int size = data.getDataSize();
|
final int size = data.getDataSize();
|
||||||
if (KEY_SYSTEM.equals(key)) {
|
if (KEY_SYSTEM.equals(key)) {
|
||||||
restoreSettings(data, Settings.System.CONTENT_URI);
|
restoreSettings(data, Settings.System.CONTENT_URI);
|
||||||
|
mSettingsHelper.applyAudioSettings();
|
||||||
} else if (KEY_SECURE.equals(key)) {
|
} else if (KEY_SECURE.equals(key)) {
|
||||||
restoreSettings(data, Settings.Secure.CONTENT_URI);
|
restoreSettings(data, Settings.Secure.CONTENT_URI);
|
||||||
// TODO: Re-enable WIFI restore when we figure out a solution for the permissions
|
} else if (FILE_WIFI_SUPPLICANT.equals(key)) {
|
||||||
// } else if (FILE_WIFI_SUPPLICANT.equals(key)) {
|
restoreFile(FILE_WIFI_SUPPLICANT, data);
|
||||||
// restoreFile(FILE_WIFI_SUPPLICANT, data);
|
FileUtils.setPermissions(FILE_WIFI_SUPPLICANT,
|
||||||
|
FileUtils.S_IRUSR | FileUtils.S_IWUSR |
|
||||||
|
FileUtils.S_IRGRP | FileUtils.S_IWGRP,
|
||||||
|
Process.myUid(), Process.WIFI_UID);
|
||||||
} else if (KEY_SYNC.equals(key)) {
|
} else if (KEY_SYNC.equals(key)) {
|
||||||
mSettingsHelper.setSyncProviders(data);
|
mSettingsHelper.setSyncProviders(data);
|
||||||
} else if (KEY_LOCALE.equals(key)) {
|
} else if (KEY_LOCALE.equals(key)) {
|
||||||
@@ -132,6 +151,49 @@ public class SettingsBackupAgent extends BackupHelperAgent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private long[] readOldChecksums(ParcelFileDescriptor oldState) throws IOException {
|
||||||
|
long[] stateChecksums = new long[STATE_SIZE];
|
||||||
|
|
||||||
|
DataInputStream dataInput = new DataInputStream(
|
||||||
|
new FileInputStream(oldState.getFileDescriptor()));
|
||||||
|
for (int i = 0; i < STATE_SIZE; i++) {
|
||||||
|
try {
|
||||||
|
stateChecksums[i] = dataInput.readLong();
|
||||||
|
} catch (EOFException eof) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dataInput.close();
|
||||||
|
return stateChecksums;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeNewChecksums(long[] checksums, ParcelFileDescriptor newState)
|
||||||
|
throws IOException {
|
||||||
|
DataOutputStream dataOutput = new DataOutputStream(
|
||||||
|
new FileOutputStream(newState.getFileDescriptor()));
|
||||||
|
for (int i = 0; i < STATE_SIZE; i++) {
|
||||||
|
dataOutput.writeLong(checksums[i]);
|
||||||
|
}
|
||||||
|
dataOutput.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private long writeIfChanged(long oldChecksum, String key, byte[] data,
|
||||||
|
BackupDataOutput output) {
|
||||||
|
CRC32 checkSummer = new CRC32();
|
||||||
|
checkSummer.update(data);
|
||||||
|
long newChecksum = checkSummer.getValue();
|
||||||
|
if (oldChecksum == newChecksum) {
|
||||||
|
return oldChecksum;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
output.writeEntityHeader(key, data.length);
|
||||||
|
output.writeEntityData(data, data.length);
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
// Bail
|
||||||
|
}
|
||||||
|
return newChecksum;
|
||||||
|
}
|
||||||
|
|
||||||
private byte[] getSystemSettings() {
|
private byte[] getSystemSettings() {
|
||||||
Cursor sortedCursor = getContentResolver().query(Settings.System.CONTENT_URI, PROJECTION,
|
Cursor sortedCursor = getContentResolver().query(Settings.System.CONTENT_URI, PROJECTION,
|
||||||
null, null, Settings.NameValueTable.NAME);
|
null, null, Settings.NameValueTable.NAME);
|
||||||
@@ -248,7 +310,7 @@ public class SettingsBackupAgent extends BackupHelperAgent {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void backupFile(String filename, BackupDataOutput data) {
|
private byte[] getFileData(String filename) {
|
||||||
try {
|
try {
|
||||||
File file = new File(filename);
|
File file = new File(filename);
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
@@ -260,14 +322,13 @@ public class SettingsBackupAgent extends BackupHelperAgent {
|
|||||||
got = fis.read(bytes, offset, bytes.length - offset);
|
got = fis.read(bytes, offset, bytes.length - offset);
|
||||||
if (got > 0) offset += got;
|
if (got > 0) offset += got;
|
||||||
} while (offset < bytes.length && got > 0);
|
} while (offset < bytes.length && got > 0);
|
||||||
data.writeEntityHeader(filename, bytes.length);
|
return bytes;
|
||||||
data.writeEntityData(bytes, bytes.length);
|
|
||||||
} else {
|
} else {
|
||||||
data.writeEntityHeader(filename, 0);
|
return EMPTY_DATA;
|
||||||
data.writeEntityData(EMPTY_DATA, 0);
|
|
||||||
}
|
}
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
Log.w(TAG, "Couldn't backup " + filename);
|
Log.w(TAG, "Couldn't backup " + filename);
|
||||||
|
return EMPTY_DATA;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -167,6 +167,9 @@ public class SettingsHelper {
|
|||||||
// Check if locale was set by the user:
|
// Check if locale was set by the user:
|
||||||
Configuration conf = mContext.getResources().getConfiguration();
|
Configuration conf = mContext.getResources().getConfiguration();
|
||||||
Locale loc = conf.locale;
|
Locale loc = conf.locale;
|
||||||
|
// TODO: The following is not working as intended because the network is forcing a locale
|
||||||
|
// change after registering. Need to find some other way to detect if the user manually
|
||||||
|
// changed the locale
|
||||||
if (conf.userSetLocale) return; // Don't change if user set it in the SetupWizard
|
if (conf.userSetLocale) return; // Don't change if user set it in the SetupWizard
|
||||||
|
|
||||||
final String[] availableLocales = mContext.getAssets().getLocales();
|
final String[] availableLocales = mContext.getAssets().getLocales();
|
||||||
@@ -193,6 +196,14 @@ public class SettingsHelper {
|
|||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
// Intentionally left blank
|
// Intentionally left blank
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Informs the audio service of changes to the settings so that
|
||||||
|
* they can be re-read and applied.
|
||||||
|
*/
|
||||||
|
void applyAudioSettings() {
|
||||||
|
AudioManager am = new AudioManager(mContext);
|
||||||
|
am.reloadAudioSettings();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,11 +126,14 @@ public class SettingsProvider extends ContentProvider {
|
|||||||
// a notification and then using the contract class to get their data,
|
// a notification and then using the contract class to get their data,
|
||||||
// the system property will be updated and they'll get the new data.
|
// the system property will be updated and they'll get the new data.
|
||||||
|
|
||||||
|
boolean backedUpDataChanged = false;
|
||||||
String property = null, table = uri.getPathSegments().get(0);
|
String property = null, table = uri.getPathSegments().get(0);
|
||||||
if (table.equals("system")) {
|
if (table.equals("system")) {
|
||||||
property = Settings.System.SYS_PROP_SETTING_VERSION;
|
property = Settings.System.SYS_PROP_SETTING_VERSION;
|
||||||
|
backedUpDataChanged = true;
|
||||||
} else if (table.equals("secure")) {
|
} else if (table.equals("secure")) {
|
||||||
property = Settings.Secure.SYS_PROP_SETTING_VERSION;
|
property = Settings.Secure.SYS_PROP_SETTING_VERSION;
|
||||||
|
backedUpDataChanged = true;
|
||||||
} else if (table.equals("gservices")) {
|
} else if (table.equals("gservices")) {
|
||||||
property = Settings.Gservices.SYS_PROP_SETTING_VERSION;
|
property = Settings.Gservices.SYS_PROP_SETTING_VERSION;
|
||||||
}
|
}
|
||||||
@@ -142,7 +145,9 @@ public class SettingsProvider extends ContentProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Inform the backup manager about a data change
|
// Inform the backup manager about a data change
|
||||||
|
if (backedUpDataChanged) {
|
||||||
mBackupManager.dataChanged();
|
mBackupManager.dataChanged();
|
||||||
|
}
|
||||||
// Now send the notification through the content framework.
|
// Now send the notification through the content framework.
|
||||||
|
|
||||||
String notify = uri.getQueryParameter("notify");
|
String notify = uri.getQueryParameter("notify");
|
||||||
|
|||||||
Reference in New Issue
Block a user