1220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani/* 2220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani * Copyright (C) 2008 The Android Open Source Project 3220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani * 4220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani * Licensed under the Apache License, Version 2.0 (the "License"); 5220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani * you may not use this file except in compliance with the License. 6220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani * You may obtain a copy of the License at 7220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani * 8220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani * http://www.apache.org/licenses/LICENSE-2.0 9220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani * 10220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani * Unless required by applicable law or agreed to in writing, software 11220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani * distributed under the License is distributed on an "AS IS" BASIS, 12220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani * See the License for the specific language governing permissions and 14220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani * limitations under the License. 15220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani */ 16220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 17220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasanipackage com.android.providers.settings; 18220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 192cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasaniimport java.io.BufferedReader; 202cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasaniimport java.io.BufferedWriter; 21d158214511a3c04753de04fa6389e46d33135c38Amith Yamasaniimport java.io.DataInputStream; 22d158214511a3c04753de04fa6389e46d33135c38Amith Yamasaniimport java.io.DataOutputStream; 232cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasaniimport java.io.EOFException; 24220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasaniimport java.io.File; 25220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasaniimport java.io.FileInputStream; 26220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasaniimport java.io.FileOutputStream; 272cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasaniimport java.io.FileReader; 282cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasaniimport java.io.FileWriter; 29220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasaniimport java.io.IOException; 30220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasaniimport java.util.Arrays; 31d158214511a3c04753de04fa6389e46d33135c38Amith Yamasaniimport java.util.zip.CRC32; 32220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 334528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tateimport android.app.backup.BackupDataInput; 344528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tateimport android.app.backup.BackupDataOutput; 35cc84c69726507a85116f5664e20e2ebfac76edbeChristopher Tateimport android.app.backup.BackupAgentHelper; 36220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasaniimport android.content.ContentValues; 37220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasaniimport android.content.Context; 38220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasaniimport android.database.Cursor; 39220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasaniimport android.net.Uri; 40220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasaniimport android.net.wifi.WifiManager; 41d158214511a3c04753de04fa6389e46d33135c38Amith Yamasaniimport android.os.FileUtils; 42220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasaniimport android.os.ParcelFileDescriptor; 43d158214511a3c04753de04fa6389e46d33135c38Amith Yamasaniimport android.os.Process; 44220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasaniimport android.provider.Settings; 45220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasaniimport android.text.TextUtils; 46220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasaniimport android.util.Log; 47220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 48220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani/** 49220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani * Performs backup and restore of the System and Secure settings. 50220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani * List of settings that are backed up are stored in the Settings.java file 51220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani */ 52cc84c69726507a85116f5664e20e2ebfac76edbeChristopher Tatepublic class SettingsBackupAgent extends BackupAgentHelper { 53436344ae12c819f58306ceb94241a266141e1218Christopher Tate private static final boolean DEBUG = false; 54220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 55220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani private static final String KEY_SYSTEM = "system"; 56220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani private static final String KEY_SECURE = "secure"; 578823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani private static final String KEY_LOCALE = "locale"; 58220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 59a286f419084d56217f05a64f1d24c9e07917212eChristopher Tate // Versioning of the state file. Increment this version 60a286f419084d56217f05a64f1d24c9e07917212eChristopher Tate // number any time the set of state items is altered. 61a286f419084d56217f05a64f1d24c9e07917212eChristopher Tate private static final int STATE_VERSION = 1; 62a286f419084d56217f05a64f1d24c9e07917212eChristopher Tate 63d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani private static final int STATE_SYSTEM = 0; 64d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani private static final int STATE_SECURE = 1; 65a286f419084d56217f05a64f1d24c9e07917212eChristopher Tate private static final int STATE_LOCALE = 2; 66a286f419084d56217f05a64f1d24c9e07917212eChristopher Tate private static final int STATE_WIFI = 3; 67a286f419084d56217f05a64f1d24c9e07917212eChristopher Tate private static final int STATE_SIZE = 4; // The number of state items 68d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani 69220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani private static String[] sortedSystemKeys = null; 70220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani private static String[] sortedSecureKeys = null; 71220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 72220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani private static final byte[] EMPTY_DATA = new byte[0]; 73220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 74220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani private static final String TAG = "SettingsBackupAgent"; 75220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 76220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani private static final int COLUMN_NAME = 1; 77220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani private static final int COLUMN_VALUE = 2; 78220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 79220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani private static final String[] PROJECTION = { 80220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani Settings.NameValueTable._ID, 81220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani Settings.NameValueTable.NAME, 82220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani Settings.NameValueTable.VALUE 83220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani }; 84220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 85220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani private static final String FILE_WIFI_SUPPLICANT = "/data/misc/wifi/wpa_supplicant.conf"; 862cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani private static final String FILE_WIFI_SUPPLICANT_TEMPLATE = 872cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani "/system/etc/wifi/wpa_supplicant.conf"; 8892c1752175f0880a0e0a05fdca37b54a8fb2b52dChristian Sonntag 8992c1752175f0880a0e0a05fdca37b54a8fb2b52dChristian Sonntag // the key to store the WIFI data under, should be sorted as last, so restore happens last. 9092c1752175f0880a0e0a05fdca37b54a8fb2b52dChristian Sonntag // use very late unicode character to quasi-guarantee last sort position. 912cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani private static final String KEY_WIFI_SUPPLICANT = "\uffedWIFI"; 92220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 93220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani private SettingsHelper mSettingsHelper; 94220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 95220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani public void onCreate() { 96220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani mSettingsHelper = new SettingsHelper(this); 97220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani super.onCreate(); 98220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 99220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 100220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani @Override 101220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, 102220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani ParcelFileDescriptor newState) throws IOException { 103220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 104220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani byte[] systemSettingsData = getSystemSettings(); 105220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani byte[] secureSettingsData = getSecureSettings(); 1068823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani byte[] locale = mSettingsHelper.getLocaleData(); 1072cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani byte[] wifiData = getWifiSupplicant(FILE_WIFI_SUPPLICANT); 108220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 109d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani long[] stateChecksums = readOldChecksums(oldState); 1108823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani 111d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani stateChecksums[STATE_SYSTEM] = 112d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani writeIfChanged(stateChecksums[STATE_SYSTEM], KEY_SYSTEM, systemSettingsData, data); 113d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani stateChecksums[STATE_SECURE] = 114d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani writeIfChanged(stateChecksums[STATE_SECURE], KEY_SECURE, secureSettingsData, data); 115d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani stateChecksums[STATE_LOCALE] = 116d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani writeIfChanged(stateChecksums[STATE_LOCALE], KEY_LOCALE, locale, data); 117d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani stateChecksums[STATE_WIFI] = 11892c1752175f0880a0e0a05fdca37b54a8fb2b52dChristian Sonntag writeIfChanged(stateChecksums[STATE_WIFI], KEY_WIFI_SUPPLICANT, wifiData, data); 1198823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani 120d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani writeNewChecksums(stateChecksums, newState); 121220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 122220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 123220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani @Override 124220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani public void onRestore(BackupDataInput data, int appVersionCode, 125220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani ParcelFileDescriptor newState) throws IOException { 126220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 127220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani while (data.readNextHeader()) { 128220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani final String key = data.getKey(); 1298823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani final int size = data.getDataSize(); 130220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani if (KEY_SYSTEM.equals(key)) { 131220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani restoreSettings(data, Settings.System.CONTENT_URI); 132d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani mSettingsHelper.applyAudioSettings(); 133220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } else if (KEY_SECURE.equals(key)) { 134220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani restoreSettings(data, Settings.Secure.CONTENT_URI); 13592c1752175f0880a0e0a05fdca37b54a8fb2b52dChristian Sonntag } else if (KEY_WIFI_SUPPLICANT.equals(key)) { 136c5b5b0fb94d078148b5fe5f6b8bb4ee361949f3eChristian Sonntag int retainedWifiState = enableWifi(false); 1372cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani restoreWifiSupplicant(FILE_WIFI_SUPPLICANT, data); 138d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani FileUtils.setPermissions(FILE_WIFI_SUPPLICANT, 139d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani FileUtils.S_IRUSR | FileUtils.S_IWUSR | 140d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani FileUtils.S_IRGRP | FileUtils.S_IWGRP, 141d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani Process.myUid(), Process.WIFI_UID); 142c5b5b0fb94d078148b5fe5f6b8bb4ee361949f3eChristian Sonntag // retain the previous WIFI state. 143c5b5b0fb94d078148b5fe5f6b8bb4ee361949f3eChristian Sonntag enableWifi(retainedWifiState == WifiManager.WIFI_STATE_ENABLED || 144c5b5b0fb94d078148b5fe5f6b8bb4ee361949f3eChristian Sonntag retainedWifiState == WifiManager.WIFI_STATE_ENABLING); 1458823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani } else if (KEY_LOCALE.equals(key)) { 1468823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani byte[] localeData = new byte[size]; 1478823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani data.readEntityData(localeData, 0, size); 1488823c0a8c68fe669c21c539eef9fc6541f0c7494Amith Yamasani mSettingsHelper.setLocaleData(localeData); 149220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } else { 150220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani data.skipEntityData(); 151220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 152220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 153220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 154220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 155d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani private long[] readOldChecksums(ParcelFileDescriptor oldState) throws IOException { 156d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani long[] stateChecksums = new long[STATE_SIZE]; 157d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani 158d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani DataInputStream dataInput = new DataInputStream( 159d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani new FileInputStream(oldState.getFileDescriptor())); 160a286f419084d56217f05a64f1d24c9e07917212eChristopher Tate 161a286f419084d56217f05a64f1d24c9e07917212eChristopher Tate try { 162a286f419084d56217f05a64f1d24c9e07917212eChristopher Tate int stateVersion = dataInput.readInt(); 163a286f419084d56217f05a64f1d24c9e07917212eChristopher Tate if (stateVersion == STATE_VERSION) { 164a286f419084d56217f05a64f1d24c9e07917212eChristopher Tate for (int i = 0; i < STATE_SIZE; i++) { 165a286f419084d56217f05a64f1d24c9e07917212eChristopher Tate stateChecksums[i] = dataInput.readLong(); 166a286f419084d56217f05a64f1d24c9e07917212eChristopher Tate } 167d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani } 168a286f419084d56217f05a64f1d24c9e07917212eChristopher Tate } catch (EOFException eof) { 169a286f419084d56217f05a64f1d24c9e07917212eChristopher Tate // With the default 0 checksum we'll wind up forcing a backup of 170a286f419084d56217f05a64f1d24c9e07917212eChristopher Tate // any unhandled data sets, which is appropriate. 171d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani } 172d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani dataInput.close(); 173d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani return stateChecksums; 174d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani } 175d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani 176d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani private void writeNewChecksums(long[] checksums, ParcelFileDescriptor newState) 177d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani throws IOException { 178d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani DataOutputStream dataOutput = new DataOutputStream( 179d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani new FileOutputStream(newState.getFileDescriptor())); 180a286f419084d56217f05a64f1d24c9e07917212eChristopher Tate 181a286f419084d56217f05a64f1d24c9e07917212eChristopher Tate dataOutput.writeInt(STATE_VERSION); 182d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani for (int i = 0; i < STATE_SIZE; i++) { 183d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani dataOutput.writeLong(checksums[i]); 184d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani } 185d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani dataOutput.close(); 186d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani } 187d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani 188d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani private long writeIfChanged(long oldChecksum, String key, byte[] data, 189d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani BackupDataOutput output) { 190d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani CRC32 checkSummer = new CRC32(); 191d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani checkSummer.update(data); 192d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani long newChecksum = checkSummer.getValue(); 193d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani if (oldChecksum == newChecksum) { 194d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani return oldChecksum; 195d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani } 196d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani try { 197d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani output.writeEntityHeader(key, data.length); 198d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani output.writeEntityData(data, data.length); 199d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani } catch (IOException ioe) { 200d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani // Bail 201d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani } 202d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani return newChecksum; 203d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani } 204d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani 205220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani private byte[] getSystemSettings() { 206220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani Cursor sortedCursor = getContentResolver().query(Settings.System.CONTENT_URI, PROJECTION, 207220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani null, null, Settings.NameValueTable.NAME); 208220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani // Copy and sort the array 209220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani if (sortedSystemKeys == null) { 210220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani sortedSystemKeys = copyAndSort(Settings.System.SETTINGS_TO_BACKUP); 211220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 212220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani byte[] result = extractRelevantValues(sortedCursor, sortedSystemKeys); 213220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani sortedCursor.close(); 214220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani return result; 215220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 216220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 217220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani private byte[] getSecureSettings() { 218220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani Cursor sortedCursor = getContentResolver().query(Settings.Secure.CONTENT_URI, PROJECTION, 219220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani null, null, Settings.NameValueTable.NAME); 220220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani // Copy and sort the array 221220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani if (sortedSecureKeys == null) { 222220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani sortedSecureKeys = copyAndSort(Settings.Secure.SETTINGS_TO_BACKUP); 223220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 224220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani byte[] result = extractRelevantValues(sortedCursor, sortedSecureKeys); 225220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani sortedCursor.close(); 226220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani return result; 227220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 228220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 229220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani private void restoreSettings(BackupDataInput data, Uri contentUri) { 230796e0f0ed531b7ff9922cd632d70d8f1da8f5829Christopher Tate if (DEBUG) Log.i(TAG, "restoreSettings: " + contentUri); 231796e0f0ed531b7ff9922cd632d70d8f1da8f5829Christopher Tate String[] whitelist = null; 232796e0f0ed531b7ff9922cd632d70d8f1da8f5829Christopher Tate if (contentUri.equals(Settings.Secure.CONTENT_URI)) { 233796e0f0ed531b7ff9922cd632d70d8f1da8f5829Christopher Tate whitelist = Settings.Secure.SETTINGS_TO_BACKUP; 234796e0f0ed531b7ff9922cd632d70d8f1da8f5829Christopher Tate } else if (contentUri.equals(Settings.System.CONTENT_URI)) { 235796e0f0ed531b7ff9922cd632d70d8f1da8f5829Christopher Tate whitelist = Settings.System.SETTINGS_TO_BACKUP; 236796e0f0ed531b7ff9922cd632d70d8f1da8f5829Christopher Tate } 237796e0f0ed531b7ff9922cd632d70d8f1da8f5829Christopher Tate 238220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani ContentValues cv = new ContentValues(2); 239220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani byte[] settings = new byte[data.getDataSize()]; 240220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani try { 241220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani data.readEntityData(settings, 0, settings.length); 242220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } catch (IOException ioe) { 243220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani Log.e(TAG, "Couldn't read entity data"); 244220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani return; 245220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 246220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani int pos = 0; 247220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani while (pos < settings.length) { 248220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani int length = readInt(settings, pos); 249220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani pos += 4; 250220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani String settingName = length > 0? new String(settings, pos, length) : null; 251220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani pos += length; 252220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani length = readInt(settings, pos); 253220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani pos += 4; 254220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani String settingValue = length > 0? new String(settings, pos, length) : null; 255220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani pos += length; 256220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani if (!TextUtils.isEmpty(settingName) && !TextUtils.isEmpty(settingValue)) { 257220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani //Log.i(TAG, "Restore " + settingName + " = " + settingValue); 2580738e8893540e8f7fac7c193be5fe24b67f04672Christopher Tate 259796e0f0ed531b7ff9922cd632d70d8f1da8f5829Christopher Tate // Only restore settings in our list of known-acceptable data 260796e0f0ed531b7ff9922cd632d70d8f1da8f5829Christopher Tate if (invalidSavedSetting(whitelist, settingName)) { 2610738e8893540e8f7fac7c193be5fe24b67f04672Christopher Tate continue; 2620738e8893540e8f7fac7c193be5fe24b67f04672Christopher Tate } 2630738e8893540e8f7fac7c193be5fe24b67f04672Christopher Tate 26470c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani if (mSettingsHelper.restoreValue(settingName, settingValue)) { 26570c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani cv.clear(); 26670c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani cv.put(Settings.NameValueTable.NAME, settingName); 26770c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani cv.put(Settings.NameValueTable.VALUE, settingValue); 26870c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani getContentResolver().insert(contentUri, cv); 26970c874ba20b586712a7550b6c5efeb6dc0fdf9faAmith Yamasani } 270220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 271220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 272220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 273220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 274796e0f0ed531b7ff9922cd632d70d8f1da8f5829Christopher Tate // Returns 'true' if the given setting is one that we refuse to restore 275796e0f0ed531b7ff9922cd632d70d8f1da8f5829Christopher Tate private boolean invalidSavedSetting(String[] knownNames, String candidate) { 276796e0f0ed531b7ff9922cd632d70d8f1da8f5829Christopher Tate // no filter? allow everything 277796e0f0ed531b7ff9922cd632d70d8f1da8f5829Christopher Tate if (knownNames == null) { 278796e0f0ed531b7ff9922cd632d70d8f1da8f5829Christopher Tate return false; 279796e0f0ed531b7ff9922cd632d70d8f1da8f5829Christopher Tate } 280796e0f0ed531b7ff9922cd632d70d8f1da8f5829Christopher Tate 281796e0f0ed531b7ff9922cd632d70d8f1da8f5829Christopher Tate // whitelisted setting? allow it 282796e0f0ed531b7ff9922cd632d70d8f1da8f5829Christopher Tate for (String name : knownNames) { 283796e0f0ed531b7ff9922cd632d70d8f1da8f5829Christopher Tate if (name.equals(candidate)) { 284796e0f0ed531b7ff9922cd632d70d8f1da8f5829Christopher Tate return false; 2850738e8893540e8f7fac7c193be5fe24b67f04672Christopher Tate } 2860738e8893540e8f7fac7c193be5fe24b67f04672Christopher Tate } 2870738e8893540e8f7fac7c193be5fe24b67f04672Christopher Tate 288796e0f0ed531b7ff9922cd632d70d8f1da8f5829Christopher Tate // refuse everything else 289796e0f0ed531b7ff9922cd632d70d8f1da8f5829Christopher Tate if (DEBUG) Log.v(TAG, "Ignoring restore datum: " + candidate); 290796e0f0ed531b7ff9922cd632d70d8f1da8f5829Christopher Tate return true; 2910738e8893540e8f7fac7c193be5fe24b67f04672Christopher Tate } 2920738e8893540e8f7fac7c193be5fe24b67f04672Christopher Tate 293220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani private String[] copyAndSort(String[] keys) { 294220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani String[] sortedKeys = new String[keys.length]; 295220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani System.arraycopy(keys, 0, sortedKeys, 0, keys.length); 296220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani Arrays.sort(sortedKeys); 297220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani return sortedKeys; 298220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 299220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 300220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani /** 301c5b5b0fb94d078148b5fe5f6b8bb4ee361949f3eChristian Sonntag * Given a cursor sorted by key name and a set of keys sorted by name, 302220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani * extract the required keys and values and write them to a byte array. 303220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani * @param sortedCursor 304220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani * @param sortedKeys 305220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani * @return 306220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani */ 307220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani byte[] extractRelevantValues(Cursor sortedCursor, String[] sortedKeys) { 308220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani byte[][] values = new byte[sortedKeys.length * 2][]; // keys and values 309220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani if (!sortedCursor.moveToFirst()) { 310220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani Log.e(TAG, "Couldn't read from the cursor"); 311220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani return new byte[0]; 312220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 313220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani int keyIndex = 0; 314220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani int totalSize = 0; 315220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani while (!sortedCursor.isAfterLast()) { 316220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani String name = sortedCursor.getString(COLUMN_NAME); 317220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani while (sortedKeys[keyIndex].compareTo(name.toString()) < 0) { 318220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani keyIndex++; 319220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani if (keyIndex == sortedKeys.length) break; 320220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 321220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani if (keyIndex < sortedKeys.length && name.equals(sortedKeys[keyIndex])) { 322220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani String value = sortedCursor.getString(COLUMN_VALUE); 323220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani byte[] nameBytes = name.toString().getBytes(); 324220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani totalSize += 4 + nameBytes.length; 325220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani values[keyIndex * 2] = nameBytes; 326220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani byte[] valueBytes; 327220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani if (TextUtils.isEmpty(value)) { 328220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani valueBytes = null; 329220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani totalSize += 4; 330220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } else { 331220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani valueBytes = value.toString().getBytes(); 332220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani totalSize += 4 + valueBytes.length; 333220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani //Log.i(TAG, "Backing up " + name + " = " + value); 334220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 335220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani values[keyIndex * 2 + 1] = valueBytes; 336220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani keyIndex++; 337220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 338220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani if (keyIndex == sortedKeys.length || !sortedCursor.moveToNext()) { 339220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani break; 340220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 341220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 342220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 343220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani byte[] result = new byte[totalSize]; 344220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani int pos = 0; 345220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani for (int i = 0; i < sortedKeys.length * 2; i++) { 346220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani if (values[i] != null) { 347220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani pos = writeInt(result, pos, values[i].length); 348220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani pos = writeBytes(result, pos, values[i]); 349220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 350220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 351220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani return result; 352220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 353220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 3542cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani private byte[] getWifiSupplicant(String filename) { 355220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani try { 356220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani File file = new File(filename); 357220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani if (file.exists()) { 3582cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani BufferedReader br = new BufferedReader(new FileReader(file)); 3592cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani StringBuffer relevantLines = new StringBuffer(); 3602cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani boolean started = false; 3612cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani String line; 3622cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani while ((line = br.readLine()) != null) { 3632cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani if (!started && line.startsWith("network")) { 3642cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani started = true; 3652cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani } 3662cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani if (started) { 3672cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani relevantLines.append(line).append("\n"); 3682cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani } 3692cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani } 3702cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani if (relevantLines.length() > 0) { 3712cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani return relevantLines.toString().getBytes(); 3722cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani } else { 3732cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani return EMPTY_DATA; 3742cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani } 375220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } else { 376d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani return EMPTY_DATA; 377220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 378220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } catch (IOException ioe) { 379220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani Log.w(TAG, "Couldn't backup " + filename); 380d158214511a3c04753de04fa6389e46d33135c38Amith Yamasani return EMPTY_DATA; 381220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 382220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 383220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 3842cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani private void restoreWifiSupplicant(String filename, BackupDataInput data) { 385220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani byte[] bytes = new byte[data.getDataSize()]; 386220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani if (bytes.length <= 0) return; 387220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani try { 388220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani data.readEntityData(bytes, 0, bytes.length); 3892cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani File supplicantFile = new File(FILE_WIFI_SUPPLICANT); 3902cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani if (supplicantFile.exists()) supplicantFile.delete(); 3912cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani copyWifiSupplicantTemplate(); 3922cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani 3932cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani FileOutputStream fos = new FileOutputStream(filename, true); 3942cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani fos.write("\n".getBytes()); 395220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani fos.write(bytes); 396220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } catch (IOException ioe) { 397220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani Log.w(TAG, "Couldn't restore " + filename); 398220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 399220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 400220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 4012cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani private void copyWifiSupplicantTemplate() { 4022cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani try { 4032cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani BufferedReader br = new BufferedReader(new FileReader(FILE_WIFI_SUPPLICANT_TEMPLATE)); 4042cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani BufferedWriter bw = new BufferedWriter(new FileWriter(FILE_WIFI_SUPPLICANT)); 4052cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani char[] temp = new char[1024]; 4062cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani int size; 4072cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani while ((size = br.read(temp)) > 0) { 4082cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani bw.write(temp, 0, size); 4092cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani } 4102cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani bw.close(); 4112cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani br.close(); 4122cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani } catch (IOException ioe) { 4132cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani Log.w(TAG, "Couldn't copy wpa_supplicant file"); 4142cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani } 4152cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani } 4162cfab8445851c59f7da07d81645ece8d70e8ce28Amith Yamasani 417220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani /** 418220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani * Write an int in BigEndian into the byte array. 419220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani * @param out byte array 420220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani * @param pos current pos in array 421220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani * @param value integer to write 422220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani * @return the index after adding the size of an int (4) 423220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani */ 424220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani private int writeInt(byte[] out, int pos, int value) { 425220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani out[pos + 0] = (byte) ((value >> 24) & 0xFF); 426220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani out[pos + 1] = (byte) ((value >> 16) & 0xFF); 427220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani out[pos + 2] = (byte) ((value >> 8) & 0xFF); 428220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani out[pos + 3] = (byte) ((value >> 0) & 0xFF); 429220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani return pos + 4; 430220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 431220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 432220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani private int writeBytes(byte[] out, int pos, byte[] value) { 433220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani System.arraycopy(value, 0, out, pos, value.length); 434220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani return pos + value.length; 435220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 436220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 437220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani private int readInt(byte[] in, int pos) { 438220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani int result = 439220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani ((in[pos ] & 0xFF) << 24) | 440220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani ((in[pos + 1] & 0xFF) << 16) | 441220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani ((in[pos + 2] & 0xFF) << 8) | 442220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani ((in[pos + 3] & 0xFF) << 0); 443220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani return result; 444220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 445220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani 446c5b5b0fb94d078148b5fe5f6b8bb4ee361949f3eChristian Sonntag private int enableWifi(boolean enable) { 447220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani WifiManager wfm = (WifiManager) getSystemService(Context.WIFI_SERVICE); 448220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani if (wfm != null) { 449c5b5b0fb94d078148b5fe5f6b8bb4ee361949f3eChristian Sonntag int state = wfm.getWifiState(); 450220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani wfm.setWifiEnabled(enable); 451c5b5b0fb94d078148b5fe5f6b8bb4ee361949f3eChristian Sonntag return state; 452220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 453c5b5b0fb94d078148b5fe5f6b8bb4ee361949f3eChristian Sonntag return WifiManager.WIFI_STATE_UNKNOWN; 454220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani } 455220f4d633be1098e7887dbd06f179138bf19f1adAmith Yamasani} 456