Skip to content

Commit 71abf6a

Browse files
Christopher TateAndroid (Google) Code Review
authored andcommitted
Merge "Merge restored wifi APs, don't overwrite" into jb-dev
2 parents ffc731d + 8dfe2b9 commit 71abf6a

File tree

1 file changed

+161
-10
lines changed

1 file changed

+161
-10
lines changed

packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java

Lines changed: 161 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import java.io.BufferedOutputStream;
3535
import java.io.BufferedReader;
3636
import java.io.BufferedWriter;
37+
import java.io.CharArrayReader;
3738
import java.io.DataInputStream;
3839
import java.io.DataOutputStream;
3940
import java.io.EOFException;
@@ -45,7 +46,11 @@
4546
import java.io.IOException;
4647
import java.io.InputStream;
4748
import java.io.OutputStream;
49+
import java.io.Reader;
50+
import java.io.Writer;
51+
import java.util.ArrayList;
4852
import java.util.HashMap;
53+
import java.util.HashSet;
4954
import java.util.Map;
5055
import java.util.zip.CRC32;
5156

@@ -55,7 +60,7 @@
5560
*/
5661
public class SettingsBackupAgent extends BackupAgentHelper {
5762
private static final boolean DEBUG = false;
58-
private static final boolean DEBUG_BACKUP = DEBUG || true;
63+
private static final boolean DEBUG_BACKUP = DEBUG || false;
5964

6065
private static final String KEY_SYSTEM = "system";
6166
private static final String KEY_SECURE = "secure";
@@ -111,6 +116,130 @@ public class SettingsBackupAgent extends BackupAgentHelper {
111116
private WifiManager mWfm;
112117
private static String mWifiConfigFile;
113118

119+
// Class for capturing a network definition from the wifi supplicant config file
120+
static class Network {
121+
String ssid = ""; // equals() and hashCode() need these to be non-null
122+
String key_mgmt = "";
123+
final ArrayList<String> rawLines = new ArrayList<String>();
124+
125+
public static Network readFromStream(BufferedReader in) {
126+
final Network n = new Network();
127+
String line;
128+
try {
129+
while (in.ready()) {
130+
line = in.readLine();
131+
if (line == null || line.startsWith("}")) {
132+
break;
133+
}
134+
n.rememberLine(line);
135+
}
136+
} catch (IOException e) {
137+
return null;
138+
}
139+
return n;
140+
}
141+
142+
void rememberLine(String line) {
143+
// can't rely on particular whitespace patterns so strip leading/trailing
144+
line = line.trim();
145+
if (line.isEmpty()) return; // only whitespace; drop the line
146+
rawLines.add(line);
147+
148+
// remember the ssid and key_mgmt lines for duplicate culling
149+
if (line.startsWith("ssid")) {
150+
ssid = line;
151+
} else if (line.startsWith("key_mgmt")) {
152+
key_mgmt = line;
153+
}
154+
}
155+
156+
public void write(Writer w) throws IOException {
157+
w.write("\nnetwork={\n");
158+
for (String line : rawLines) {
159+
w.write("\t" + line + "\n");
160+
}
161+
w.write("}\n");
162+
}
163+
164+
public void dump() {
165+
Log.v(TAG, "network={");
166+
for (String line : rawLines) {
167+
Log.v(TAG, " " + line);
168+
}
169+
Log.v(TAG, "}");
170+
}
171+
172+
// Same approach as Pair.equals() and Pair.hashCode()
173+
@Override
174+
public boolean equals(Object o) {
175+
if (o == this) return true;
176+
if (!(o instanceof Network)) return false;
177+
final Network other;
178+
try {
179+
other = (Network) o;
180+
} catch (ClassCastException e) {
181+
return false;
182+
}
183+
return ssid.equals(other.ssid) && key_mgmt.equals(other.key_mgmt);
184+
}
185+
186+
@Override
187+
public int hashCode() {
188+
int result = 17;
189+
result = 31 * result + ssid.hashCode();
190+
result = 31 * result + key_mgmt.hashCode();
191+
return result;
192+
}
193+
}
194+
195+
// Ingest multiple wifi config file fragments, looking for network={} blocks
196+
// and eliminating duplicates
197+
class WifiNetworkSettings {
198+
// One for fast lookup, one for maintaining ordering
199+
final HashSet<Network> mKnownNetworks = new HashSet<Network>();
200+
final ArrayList<Network> mNetworks = new ArrayList<Network>(8);
201+
202+
public void readNetworks(BufferedReader in) {
203+
try {
204+
String line;
205+
while (in.ready()) {
206+
line = in.readLine();
207+
if (line != null) {
208+
// Parse out 'network=' decls so we can ignore duplicates
209+
if (line.startsWith("network")) {
210+
Network net = Network.readFromStream(in);
211+
if (! mKnownNetworks.contains(net)) {
212+
if (DEBUG_BACKUP) {
213+
Log.v(TAG, "Adding " + net.ssid + " / " + net.key_mgmt);
214+
}
215+
mKnownNetworks.add(net);
216+
mNetworks.add(net);
217+
} else {
218+
if (DEBUG_BACKUP) {
219+
Log.v(TAG, "Dupe; skipped " + net.ssid + " / " + net.key_mgmt);
220+
}
221+
}
222+
}
223+
}
224+
}
225+
} catch (IOException e) {
226+
// whatever happened, we're done now
227+
}
228+
}
229+
230+
public void write(Writer w) throws IOException {
231+
for (Network net : mNetworks) {
232+
net.write(w);
233+
}
234+
}
235+
236+
public void dump() {
237+
for (Network net : mNetworks) {
238+
net.dump();
239+
}
240+
}
241+
}
242+
114243
@Override
115244
public void onCreate() {
116245
if (DEBUG_BACKUP) Log.d(TAG, "onCreate() invoked");
@@ -622,29 +751,51 @@ private void restoreWifiSupplicant(String filename, BackupDataInput data) {
622751

623752
private void restoreWifiSupplicant(String filename, byte[] bytes, int size) {
624753
try {
754+
WifiNetworkSettings supplicantImage = new WifiNetworkSettings();
755+
625756
File supplicantFile = new File(FILE_WIFI_SUPPLICANT);
626-
if (supplicantFile.exists()) supplicantFile.delete();
627-
copyWifiSupplicantTemplate();
757+
if (supplicantFile.exists()) {
758+
// Retain the existing APs; we'll append the restored ones to them
759+
BufferedReader in = new BufferedReader(new FileReader(FILE_WIFI_SUPPLICANT));
760+
supplicantImage.readNetworks(in);
761+
in.close();
628762

629-
OutputStream os = new BufferedOutputStream(new FileOutputStream(filename, true));
630-
os.write("\n".getBytes());
631-
os.write(bytes, 0, size);
632-
os.close();
763+
supplicantFile.delete();
764+
}
765+
766+
// Incorporate the restore AP information
767+
if (size > 0) {
768+
char[] restoredAsBytes = new char[size];
769+
for (int i = 0; i < size; i++) restoredAsBytes[i] = (char) bytes[i];
770+
BufferedReader in = new BufferedReader(new CharArrayReader(restoredAsBytes));
771+
supplicantImage.readNetworks(in);
772+
773+
if (DEBUG_BACKUP) {
774+
Log.v(TAG, "Final AP list:");
775+
supplicantImage.dump();
776+
}
777+
}
778+
779+
// Install the correct default template
780+
BufferedWriter bw = new BufferedWriter(new FileWriter(FILE_WIFI_SUPPLICANT));
781+
copyWifiSupplicantTemplate(bw);
782+
783+
// Write the restored supplicant config and we're done
784+
supplicantImage.write(bw);
785+
bw.close();
633786
} catch (IOException ioe) {
634787
Log.w(TAG, "Couldn't restore " + filename);
635788
}
636789
}
637790

638-
private void copyWifiSupplicantTemplate() {
791+
private void copyWifiSupplicantTemplate(BufferedWriter bw) {
639792
try {
640793
BufferedReader br = new BufferedReader(new FileReader(FILE_WIFI_SUPPLICANT_TEMPLATE));
641-
BufferedWriter bw = new BufferedWriter(new FileWriter(FILE_WIFI_SUPPLICANT));
642794
char[] temp = new char[1024];
643795
int size;
644796
while ((size = br.read(temp)) > 0) {
645797
bw.write(temp, 0, size);
646798
}
647-
bw.close();
648799
br.close();
649800
} catch (IOException ioe) {
650801
Log.w(TAG, "Couldn't copy wpa_supplicant file");

0 commit comments

Comments
 (0)