--- /dev/null
+package com.android.providers.settings;
+
+import android.net.NetworkPolicy;
+import android.net.NetworkTemplate;
+import android.util.Log;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+/**
+ * Backup/Restore Serializer Class for android.net.NetworkPolicy
+ */
+public class NetworkPolicySerializer {
+ private static final boolean DEBUG = false;
+ private static final String TAG = "NetworkPolicySerializer";
+
+ private static final int NULL = 0;
+ private static final int NOT_NULL = 1;
+ /**
+ * Current Version of the Serializer.
+ */
+ private static int STATE_VERSION = 1;
+
+ /**
+ * Marshals an array of NetworkPolicy objects into a byte-array.
+ *
+ * @param policies - NetworkPolicies to be Marshaled
+ * @return byte array
+ */
+
+ public static byte[] marshalNetworkPolicies(NetworkPolicy policies[]) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ if (policies != null && policies.length != 0) {
+ DataOutputStream out = new DataOutputStream(baos);
+ try {
+ out.writeInt(STATE_VERSION);
+ out.writeInt(policies.length);
+ for (NetworkPolicy policy : policies) {
+ byte[] marshaledPolicy = marshalNetworkPolicy(policy);
+ if (marshaledPolicy != null) {
+ out.writeByte(NOT_NULL);
+ out.writeInt(marshaledPolicy.length);
+ out.write(marshaledPolicy);
+ } else {
+ out.writeByte(NULL);
+ }
+ }
+ } catch (IOException ioe) {
+ Log.e(TAG, "Failed to Convert NetworkPolicies to byte array", ioe);
+ baos.reset();
+ }
+ }
+ return baos.toByteArray();
+ }
+
+ /**
+ * Unmarshals a byte array into an array of NetworkPolicy Objects
+ *
+ * @param data - marshaled NetworkPolicies Array
+ * @return NetworkPolicy[] array
+ */
+ public static NetworkPolicy[] unmarshalNetworkPolicies(byte[] data) {
+ if (data == null || data.length == 0) {
+ return new NetworkPolicy[0];
+ }
+ DataInputStream in = new DataInputStream(new ByteArrayInputStream(data));
+ try {
+ int version = in.readInt();
+ int length = in.readInt();
+ NetworkPolicy[] policies = new NetworkPolicy[length];
+ for (int i = 0; i < length; i++) {
+ byte isNull = in.readByte();
+ if (isNull == NULL) continue;
+ int byteLength = in.readInt();
+ byte[] policyData = new byte[byteLength];
+ in.read(policyData, 0, byteLength);
+ policies[i] = unmarshalNetworkPolicy(policyData);
+ }
+ return policies;
+ } catch (IOException ioe) {
+ Log.e(TAG, "Failed to Convert byte array to NetworkPolicies", ioe);
+ return new NetworkPolicy[0];
+ }
+ }
+
+ /**
+ * Marshals a NetworkPolicy object into a byte-array.
+ *
+ * @param networkPolicy - NetworkPolicy to be Marshaled
+ * @return byte array
+ */
+ public static byte[] marshalNetworkPolicy(NetworkPolicy networkPolicy) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ if (networkPolicy != null) {
+ DataOutputStream out = new DataOutputStream(baos);
+ try {
+ out.writeInt(STATE_VERSION);
+ writeNetworkTemplate(out, networkPolicy.template);
+ out.writeInt(networkPolicy.cycleDay);
+ writeString(out, networkPolicy.cycleTimezone);
+ out.writeLong(networkPolicy.warningBytes);
+ out.writeLong(networkPolicy.limitBytes);
+ out.writeLong(networkPolicy.lastWarningSnooze);
+ out.writeLong(networkPolicy.lastLimitSnooze);
+ out.writeInt(networkPolicy.metered ? 1 : 0);
+ out.writeInt(networkPolicy.inferred ? 1 : 0);
+ } catch (IOException ioe) {
+ Log.e(TAG, "Failed to Convert NetworkPolicy to byte array", ioe);
+ baos.reset();
+ }
+ }
+ return baos.toByteArray();
+ }
+
+ /**
+ * Unmarshals a byte array into a NetworkPolicy Object
+ *
+ * @param data - marshaled NetworkPolicy Object
+ * @return NetworkPolicy Object
+ */
+ public static NetworkPolicy unmarshalNetworkPolicy(byte[] data) {
+ if (data == null || data.length == 0) {
+ return null;
+ }
+ DataInputStream in = new DataInputStream(new ByteArrayInputStream(data));
+ try {
+ int version = in.readInt();
+ NetworkTemplate template = readNetworkTemplate(in, version);
+ int cycleDay = in.readInt();
+ String cycleTimeZone = readString(in, version);
+ long warningBytes = in.readLong();
+ long limitBytes = in.readLong();
+ long lastWarningSnooze = in.readLong();
+ long lastLimitSnooze = in.readLong();
+ boolean metered = in.readInt() == 1;
+ boolean inferred = in.readInt() == 1;
+ return new NetworkPolicy(template, cycleDay, cycleTimeZone, warningBytes, limitBytes,
+ lastWarningSnooze, lastLimitSnooze, metered, inferred);
+ } catch (IOException ioe) {
+ Log.e(TAG, "Failed to Convert byte array to NetworkPolicy", ioe);
+ return null;
+ }
+ }
+
+ private static NetworkTemplate readNetworkTemplate(DataInputStream in, int version)
+ throws IOException {
+ byte isNull = in.readByte();
+ if (isNull == NULL) return null;
+ int matchRule = in.readInt();
+ String subscriberId = readString(in, version);
+ String networkId = readString(in, version);
+ return new NetworkTemplate(matchRule, subscriberId, networkId);
+ }
+
+ private static void writeNetworkTemplate(DataOutputStream out, NetworkTemplate template)
+ throws IOException {
+ if (template != null) {
+ out.writeByte(NOT_NULL);
+ out.writeInt(template.getMatchRule());
+ writeString(out, template.getSubscriberId());
+ writeString(out, template.getNetworkId());
+ } else {
+ out.writeByte(NULL);
+ }
+ }
+
+ private static String readString(DataInputStream in, int version) throws IOException {
+ byte isNull = in.readByte();
+ if (isNull == NOT_NULL) {
+ return in.readUTF();
+ }
+ return null;
+ }
+
+ private static void writeString(DataOutputStream out, String val) throws IOException {
+ if (val != null) {
+ out.writeByte(NOT_NULL);
+ out.writeUTF(val);
+ } else {
+ out.writeByte(NULL);
+ }
+ }
+}
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
+import android.net.NetworkPolicyManager;
import android.net.Uri;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.KeyMgmt;
private static final String KEY_LOCALE = "locale";
private static final String KEY_LOCK_SETTINGS = "lock_settings";
private static final String KEY_SOFTAP_CONFIG = "softap_config";
+ private static final String KEY_NET_POLICIES = "network_policies";
+
// Versioning of the state file. Increment this version
// number any time the set of state items is altered.
- private static final int STATE_VERSION = 5;
+ private static final int STATE_VERSION = 6;
// Slots in the checksum array. Never insert new items in the middle
// of this array; new slots must be appended.
private static final int STATE_GLOBAL = 5;
private static final int STATE_LOCK_SETTINGS = 6;
private static final int STATE_SOFTAP_CONFIG = 7;
+ private static final int STATE_NET_POLICIES = 8;
- private static final int STATE_SIZE = 8; // The current number of state items
+ private static final int STATE_SIZE = 9; // The current number of state items
// Number of entries in the checksum array at various version numbers
private static final int STATE_SIZES[] = {
5, // version 2 added STATE_WIFI_CONFIG
6, // version 3 added STATE_GLOBAL
7, // version 4 added STATE_LOCK_SETTINGS
- STATE_SIZE // version 5 added STATE_SOFTAP_CONFIG
+ 8, // version 5 added STATE_SOFTAP_CONFIG
+ STATE_SIZE // version 6 added STATE_NET_POLICIES
};
// Versioning of the 'full backup' format
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 FULL_BACKUP_ADDED_SOFTAP_CONF = 4; //added the "softap_config" entry
+ private static final int FULL_BACKUP_ADDED_NET_POLICIES = 5; //added the "network_policies" entry
private static final int INTEGER_BYTE_COUNT = Integer.SIZE / Byte.SIZE;
byte[] wifiSupplicantData = getWifiSupplicant(FILE_WIFI_SUPPLICANT);
byte[] wifiConfigData = getFileData(mWifiConfigFile);
byte[] softApConfigData = getSoftAPConfiguration();
+ byte[] netPoliciesData = getNetworkPolicies();
long[] stateChecksums = readOldChecksums(oldState);
stateChecksums[STATE_SOFTAP_CONFIG] =
writeIfChanged(stateChecksums[STATE_SOFTAP_CONFIG], KEY_SOFTAP_CONFIG,
softApConfigData, data);
+ stateChecksums[STATE_NET_POLICIES] =
+ writeIfChanged(stateChecksums[STATE_NET_POLICIES], KEY_NET_POLICIES,
+ netPoliciesData, data);
writeNewChecksums(stateChecksums, newState);
}
byte[] softapData = new byte[size];
data.readEntityData(softapData, 0, size);
restoreSoftApConfiguration(softapData);
+ } else if (KEY_NET_POLICIES.equals(key)) {
+ byte[] netPoliciesData = new byte[size];
+ data.readEntityData(netPoliciesData, 0, size);
+ restoreNetworkPolicies(netPoliciesData);
} else {
data.skipEntityData();
}
byte[] wifiSupplicantData = getWifiSupplicant(FILE_WIFI_SUPPLICANT);
byte[] wifiConfigData = getFileData(mWifiConfigFile);
byte[] softApConfigData = getSoftAPConfiguration();
+ byte[] netPoliciesData = getNetworkPolicies();
// Write the data to the staging file, then emit that as our tarfile
// representation of the backed-up settings.
if (DEBUG_BACKUP) Log.d(TAG, softApConfigData.length + " bytes of softap config data");
out.writeInt(softApConfigData.length);
out.write(softApConfigData);
+ if (DEBUG_BACKUP) Log.d(TAG, netPoliciesData.length + " bytes of network policies data");
+ out.writeInt(netPoliciesData.length);
+ out.write(netPoliciesData);
out.flush(); // also flushes downstream
}
}
+ if (version >= FULL_BACKUP_ADDED_NET_POLICIES){
+ nBytes = in.readInt();
+ if (DEBUG_BACKUP) Log.d(TAG, nBytes + " bytes of network policies data");
+ if (nBytes > buffer.length) buffer = new byte[nBytes];
+ if (nBytes > 0) {
+ in.readFully(buffer, 0, nBytes);
+ restoreNetworkPolicies(buffer);
+ }
+ }
+
if (DEBUG_BACKUP) Log.d(TAG, "Full restore complete.");
} else {
data.close();
wifiManager.setWifiApConfiguration(WiFiConfigurationSerializer.unmarshalWifiConfig(data));
}
+ private byte[] getNetworkPolicies(){
+ NetworkPolicyManager networkPolicyManager =
+ (NetworkPolicyManager)getSystemService(NETWORK_POLICY_SERVICE);
+ return NetworkPolicySerializer
+ .marshalNetworkPolicies(networkPolicyManager.getNetworkPolicies());
+ }
+
+ private void restoreNetworkPolicies(byte[] data){
+ NetworkPolicyManager networkPolicyManager =
+ (NetworkPolicyManager)getSystemService(NETWORK_POLICY_SERVICE);
+ networkPolicyManager
+ .setNetworkPolicies(NetworkPolicySerializer.unmarshalNetworkPolicies(data));
+ }
+
/**
* Write an int in BigEndian into the byte array.
* @param out byte array
}
private int readInt(byte[] in, int pos) {
- int result =
- ((in[pos ] & 0xFF) << 24) |
- ((in[pos + 1] & 0xFF) << 16) |
- ((in[pos + 2] & 0xFF) << 8) |
- ((in[pos + 3] & 0xFF) << 0);
+ int result = ((in[pos ] & 0xFF) << 24) |
+ ((in[pos + 1] & 0xFF) << 16) |
+ ((in[pos + 2] & 0xFF) << 8) |
+ ((in[pos + 3] & 0xFF) << 0);
return result;
}
}
return WifiManager.WIFI_STATE_UNKNOWN;
}
-}
\ No newline at end of file
+}
# Note we statically link SettingsState to do some unit tests. It's not accessible otherwise
# because this test is not an instrumentation test. (because the target runs in the system process.)
LOCAL_SRC_FILES := $(call all-subdir-java-files) \
- ../src/com/android/providers/settings/SettingsState.java
+ ../src/com/android/providers/settings/SettingsState.java \
+ ../src/com/android/providers/settings/WiFiConfigurationSerializer.java \
+ ../src/com/android/providers/settings/NetworkPolicySerializer.java
+
LOCAL_PACKAGE_NAME := SettingsProviderTest
LOCAL_CERTIFICATE := platform
-include $(BUILD_PACKAGE)
\ No newline at end of file
+include $(BUILD_PACKAGE)
--- /dev/null
+package com.android.providers.settings;
+
+import android.net.NetworkPolicy;
+import android.net.NetworkTemplate;
+import android.test.AndroidTestCase;
+
+import java.util.Random;
+
+/**
+ * Tests for NetworkPolicySerializer
+ */
+public class NetworkPolicySerializerTest extends AndroidTestCase {
+ static Random sRandom = new Random();
+
+ public void testMarshallAndUnmarshalNetworkPolicy() {
+ NetworkPolicy policy = getDummyNetworkPolicy();
+ byte[] data = NetworkPolicySerializer.marshalNetworkPolicy(policy);
+ assertNotNull("Got Null data from marshal", data);
+ assertFalse("Got back an empty byte[] from marshal", data.length == 0);
+
+ NetworkPolicy unmarshaled = NetworkPolicySerializer.unmarshalNetworkPolicy(data);
+ assertNotNull("Got Null data from unmarshaled", unmarshaled);
+ assertTrue("NetworkPolicy Marshall and Unmarshal Failed!", policy.equals(unmarshaled));
+ }
+
+ public void testMarshallNetworkPolicyEdgeCases() {
+ byte[] data = NetworkPolicySerializer.marshalNetworkPolicy(null);
+ assertNotNull("NetworkPolicy marshal returned null. Expected: byte[0]", data);
+ assertEquals("NetworkPolicy marshal returned incomplete byte array. Expected: byte[0]",
+ data.length, 0);
+ }
+
+ public void testUnmarshallNetworkPolicyEdgeCases() {
+ NetworkPolicy policy = NetworkPolicySerializer.unmarshalNetworkPolicy(null);
+ assertNull("Non null NetworkPolicy returned for null byte[] input", policy);
+
+ policy = NetworkPolicySerializer.unmarshalNetworkPolicy(new byte[0]);
+ assertNull("Non null NetworkPolicy returned for empty byte[] input", policy);
+
+ policy = NetworkPolicySerializer.unmarshalNetworkPolicy(new byte[]{10, 20, 30, 40, 50, 60});
+ assertNull("Non null NetworkPolicy returned for incomplete byte[] input", policy);
+ }
+
+ public void testMarshallAndUnmarshalNetworkPolicies() {
+ NetworkPolicy[] policies = getDummyNetworkPolicies(5);
+ byte[] data = NetworkPolicySerializer.marshalNetworkPolicies(policies);
+ assertNotNull("Got Null data from marshal", data);
+ assertFalse("Got back an empty byte[] from marshal", data.length == 0);
+
+ NetworkPolicy[] unmarshaled = NetworkPolicySerializer.unmarshalNetworkPolicies(data);
+ assertNotNull("Got Null data from unmarshaled", unmarshaled);
+ try {
+ for (int i = 0; i < policies.length; i++) {
+ assertTrue("NetworkPolicies Marshall and Unmarshal Failed!",
+ policies[i].equals(unmarshaled[i]));
+ }
+ } catch (NullPointerException npe) {
+ assertTrue("Some policies were not marshaled/unmarshaled correctly", false);
+ }
+ }
+
+ public void testMarshallNetworkPoliciesEdgeCases() {
+ byte[] data = NetworkPolicySerializer.marshalNetworkPolicies(null);
+ assertNotNull("NetworkPolicies marshal returned null!", data);
+ assertEquals("NetworkPolicies marshal returned incomplete byte array", data.length, 0);
+
+ data = NetworkPolicySerializer.marshalNetworkPolicies(new NetworkPolicy[0]);
+ assertNotNull("NetworkPolicies marshal returned null for empty NetworkPolicy[]", data);
+ assertEquals("NetworkPolicies marshal returned incomplete byte array for empty NetworkPolicy[]"
+ , data.length, 0);
+ }
+
+ public void testUnmarshalNetworkPoliciesEdgeCases() {
+ NetworkPolicy[] policies = NetworkPolicySerializer.unmarshalNetworkPolicies(null);
+ assertNotNull("NetworkPolicies unmarshal returned null for null input. Expected: byte[0] ",
+ policies);
+ assertEquals("Non Empty NetworkPolicy[] returned for null input Expected: byte[0]",
+ policies.length, 0);
+
+ policies = NetworkPolicySerializer.unmarshalNetworkPolicies(new byte[0]);
+ assertNotNull("NetworkPolicies unmarshal returned null for empty byte[] input. Expected: byte[0]",
+ policies);
+ assertEquals("Non Empty NetworkPolicy[] returned for empty byte[] input. Expected: byte[0]",
+ policies.length, 0);
+
+ policies = NetworkPolicySerializer.unmarshalNetworkPolicies(new byte[]{10, 20, 30, 40, 50, 60});
+ assertNotNull("NetworkPolicies unmarshal returned null for incomplete byte[] input. " +
+ "Expected: byte[0] ", policies);
+ assertEquals("Non Empty NetworkPolicy[] returned for incomplete byte[] input Expected: byte[0]",
+ policies.length, 0);
+
+ }
+
+ private NetworkPolicy[] getDummyNetworkPolicies(int num) {
+ NetworkPolicy[] policies = new NetworkPolicy[num];
+ for (int i = 0; i < num; i++) {
+ policies[i] = getDummyNetworkPolicy();
+ }
+ return policies;
+ }
+
+ private NetworkPolicy getDummyNetworkPolicy() {
+ NetworkTemplate template = new NetworkTemplate(NetworkTemplate.MATCH_MOBILE_ALL, "subId",
+ "GoogleGuest");
+ int cycleDay = sRandom.nextInt();
+ String cycleTimezone = "timezone";
+ long warningBytes = sRandom.nextLong();
+ long limitBytes = sRandom.nextLong();
+ long lastWarningSnooze = sRandom.nextLong();
+ long lastLimitSnooze = sRandom.nextLong();
+ boolean metered = sRandom.nextInt() % 2 == 0;
+ boolean inferred = sRandom.nextInt() % 2 == 0;
+ return new NetworkPolicy(template, cycleDay, cycleTimezone, warningBytes, limitBytes,
+ lastWarningSnooze, lastLimitSnooze, metered, inferred);
+ }
+
+}