Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 16f95814 authored by Ritesh Reddy's avatar Ritesh Reddy Committed by android-build-merger
Browse files

Merge "Enabling SoftAP Configuration Backup." into mm-wireless-dev am: c4a1188a

am: 70cffc57

* commit '70cffc57':
  Enabling SoftAP Configuration Backup.
parents aac64bf7 70cffc57
Loading
Loading
Loading
Loading
+54 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.util;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

/**
 * Utility methods for Backup/Restore
 * @hide
 */
public class BackupUtils {

    public static final int NULL = 0;
    public static final int NOT_NULL = 1;

    /**
     * Thrown when there is a backup version mismatch
     * between the data received and what the system can handle
     */
    public static class BadVersionException extends Exception {
        public BadVersionException(String message) {
            super(message);
        }
    }

    public static String readString(DataInputStream in) throws IOException {
        return (in.readByte() == NOT_NULL) ? in.readUTF() : null;
    }

    public static void writeString(DataOutputStream out, String val) throws IOException {
        if (val != null) {
            out.writeByte(NOT_NULL);
            out.writeUTF(val);
        } else {
            out.writeByte(NULL);
        }
    }
}
 No newline at end of file
+136 −63
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.BackupUtils;
import android.util.Log;

import com.android.internal.widget.LockPatternUtils;
@@ -81,10 +82,11 @@ public class SettingsBackupAgent extends BackupAgentHelper {
    private static final String KEY_GLOBAL = "global";
    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";

    // Versioning of the state file.  Increment this version
    // number any time the set of state items is altered.
    private static final int STATE_VERSION = 4;
    private static final int STATE_VERSION = 5;

    // Slots in the checksum array.  Never insert new items in the middle
    // of this array; new slots must be appended.
@@ -95,8 +97,9 @@ public class SettingsBackupAgent extends BackupAgentHelper {
    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_SOFTAP_CONFIG   = 7;

    private static final int STATE_SIZE            = 7; // The current number of state items
    private static final int STATE_SIZE            = 8; // The current number of state items

    // Number of entries in the checksum array at various version numbers
    private static final int STATE_SIZES[] = {
@@ -104,13 +107,16 @@ public class SettingsBackupAgent extends BackupAgentHelper {
            4,              // version 1
            5,              // version 2 added STATE_WIFI_CONFIG
            6,              // version 3 added STATE_GLOBAL
        STATE_SIZE      // version 4 added STATE_LOCK_SETTINGS
            7,              // version 4 added STATE_LOCK_SETTINGS
            STATE_SIZE      // version 5 added STATE_SOFTAP_CONFIG
    };

    // Versioning of the 'full backup' format
    private static final int FULL_BACKUP_VERSION = 3;
    // Increment this version any time a new item is added
    private static final int FULL_BACKUP_VERSION = 4;
    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 INTEGER_BYTE_COUNT = Integer.SIZE / Byte.SIZE;

@@ -146,7 +152,7 @@ public class SettingsBackupAgent extends BackupAgentHelper {

    private SettingsHelper mSettingsHelper;
    private WifiManager mWfm;
    private static String mWifiConfigFile;
    private String mWifiConfigFile;

    // Chain of asynchronous operations used when rewriting the wifi supplicant config file
    WifiDisableRunnable mWifiDisable = null;
@@ -405,6 +411,7 @@ public class SettingsBackupAgent extends BackupAgentHelper {
        byte[] locale = mSettingsHelper.getLocaleData();
        byte[] wifiSupplicantData = getWifiSupplicant(FILE_WIFI_SUPPLICANT);
        byte[] wifiConfigData = getFileData(mWifiConfigFile);
        byte[] softApConfigData = getSoftAPConfiguration();

        long[] stateChecksums = readOldChecksums(oldState);

@@ -425,6 +432,9 @@ public class SettingsBackupAgent extends BackupAgentHelper {
        stateChecksums[STATE_LOCK_SETTINGS] =
                writeIfChanged(stateChecksums[STATE_LOCK_SETTINGS], KEY_LOCK_SETTINGS,
                        lockSettingsData, data);
        stateChecksums[STATE_SOFTAP_CONFIG] =
                writeIfChanged(stateChecksums[STATE_SOFTAP_CONFIG], KEY_SOFTAP_CONFIG,
                        softApConfigData, data);

        writeNewChecksums(stateChecksums, newState);
    }
@@ -503,8 +513,8 @@ public class SettingsBackupAgent extends BackupAgentHelper {
                    restoreWifiSupplicant(FILE_WIFI_SUPPLICANT,
                            restoredSupplicantData, restoredSupplicantData.length);
                    FileUtils.setPermissions(FILE_WIFI_SUPPLICANT,
                            FileUtils.S_IRUSR | FileUtils.S_IWUSR |
                            FileUtils.S_IRGRP | FileUtils.S_IWGRP,
                            FileUtils.S_IRUSR | FileUtils.S_IWUSR
                            | FileUtils.S_IRGRP | FileUtils.S_IWGRP,
                            Process.myUid(), Process.WIFI_UID);
                }
                if (restoredWifiConfigFile != null) {
@@ -516,8 +526,8 @@ public class SettingsBackupAgent extends BackupAgentHelper {
                    Settings.Global.putInt(getContentResolver(),
                            Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, scanAlways);
                }
                enableWifi(retainedWifiState == WifiManager.WIFI_STATE_ENABLED ||
                        retainedWifiState == WifiManager.WIFI_STATE_ENABLING);
                enableWifi(retainedWifiState == WifiManager.WIFI_STATE_ENABLED
                        || retainedWifiState == WifiManager.WIFI_STATE_ENABLING);
            }
        }
    }
@@ -542,27 +552,49 @@ public class SettingsBackupAgent extends BackupAgentHelper {
        while (data.readNextHeader()) {
            final String key = data.getKey();
            final int size = data.getDataSize();
            if (KEY_SYSTEM.equals(key)) {
            switch (key) {
                case KEY_SYSTEM :
                    restoreSettings(data, Settings.System.CONTENT_URI, movedToGlobal);
                    mSettingsHelper.applyAudioSettings();
            } else if (KEY_SECURE.equals(key)) {
                    break;

                case KEY_SECURE :
                    restoreSettings(data, Settings.Secure.CONTENT_URI, movedToGlobal);
            } else if (KEY_GLOBAL.equals(key)) {
                    break;

                case KEY_GLOBAL :
                    restoreSettings(data, Settings.Global.CONTENT_URI, null);
            } else if (KEY_WIFI_SUPPLICANT.equals(key)) {
                    break;

                case KEY_WIFI_SUPPLICANT :
                    initWifiRestoreIfNecessary();
                    mWifiRestore.incorporateWifiSupplicant(data);
            } else if (KEY_LOCALE.equals(key)) {
                    break;

                case KEY_LOCALE :
                    byte[] localeData = new byte[size];
                    data.readEntityData(localeData, 0, size);
                    mSettingsHelper.setLocaleData(localeData, size);
            } else if (KEY_WIFI_CONFIG.equals(key)) {
                    break;

                case KEY_WIFI_CONFIG :
                    initWifiRestoreIfNecessary();
                    mWifiRestore.incorporateWifiConfigFile(data);
            } else if (KEY_LOCK_SETTINGS.equals(key)) {
                    break;

                case KEY_LOCK_SETTINGS :
                    restoreLockSettings(data);
             } else {
                    break;

                case KEY_SOFTAP_CONFIG :
                    byte[] softapData = new byte[size];
                    data.readEntityData(softapData, 0, size);
                    restoreSoftApConfiguration(softapData);
                    break;

                default :
                    data.skipEntityData();

            }
        }

@@ -589,6 +621,7 @@ public class SettingsBackupAgent extends BackupAgentHelper {
        byte[] locale = mSettingsHelper.getLocaleData();
        byte[] wifiSupplicantData = getWifiSupplicant(FILE_WIFI_SUPPLICANT);
        byte[] wifiConfigData = getFileData(mWifiConfigFile);
        byte[] softApConfigData = getSoftAPConfiguration();

        // Write the data to the staging file, then emit that as our tarfile
        // representation of the backed-up settings.
@@ -605,16 +638,22 @@ public class SettingsBackupAgent extends BackupAgentHelper {
            if (DEBUG_BACKUP) Log.d(TAG, systemSettingsData.length + " bytes of settings data");
            out.writeInt(systemSettingsData.length);
            out.write(systemSettingsData);
            if (DEBUG_BACKUP) Log.d(TAG, secureSettingsData.length + " bytes of secure settings data");
            if (DEBUG_BACKUP) {
                Log.d(TAG, secureSettingsData.length + " bytes of secure settings data");
            }
            out.writeInt(secureSettingsData.length);
            out.write(secureSettingsData);
            if (DEBUG_BACKUP) Log.d(TAG, globalSettingsData.length + " bytes of global settings data");
            if (DEBUG_BACKUP) {
                Log.d(TAG, globalSettingsData.length + " bytes of global settings data");
            }
            out.writeInt(globalSettingsData.length);
            out.write(globalSettingsData);
            if (DEBUG_BACKUP) Log.d(TAG, locale.length + " bytes of locale data");
            out.writeInt(locale.length);
            out.write(locale);
            if (DEBUG_BACKUP) Log.d(TAG, wifiSupplicantData.length + " bytes of wifi supplicant data");
            if (DEBUG_BACKUP) {
                Log.d(TAG, wifiSupplicantData.length + " bytes of wifi supplicant data");
            }
            out.writeInt(wifiSupplicantData.length);
            out.write(wifiSupplicantData);
            if (DEBUG_BACKUP) Log.d(TAG, wifiConfigData.length + " bytes of wifi config data");
@@ -623,6 +662,9 @@ public class SettingsBackupAgent extends BackupAgentHelper {
            if (DEBUG_BACKUP) Log.d(TAG, lockSettingsData.length + " bytes of lock settings data");
            out.writeInt(lockSettingsData.length);
            out.write(lockSettingsData);
            if (DEBUG_BACKUP) Log.d(TAG, softApConfigData.length + " bytes of softap config data");
            out.writeInt(softApConfigData.length);
            out.write(softApConfigData);

            out.flush();    // also flushes downstream

@@ -691,12 +733,12 @@ public class SettingsBackupAgent extends BackupAgentHelper {
            int retainedWifiState = enableWifi(false);
            restoreWifiSupplicant(FILE_WIFI_SUPPLICANT, buffer, nBytes);
            FileUtils.setPermissions(FILE_WIFI_SUPPLICANT,
                    FileUtils.S_IRUSR | FileUtils.S_IWUSR |
                    FileUtils.S_IRGRP | FileUtils.S_IWGRP,
                    FileUtils.S_IRUSR | FileUtils.S_IWUSR
                    | FileUtils.S_IRGRP | FileUtils.S_IWGRP,
                    Process.myUid(), Process.WIFI_UID);
            // retain the previous WIFI state.
            enableWifi(retainedWifiState == WifiManager.WIFI_STATE_ENABLED ||
                    retainedWifiState == WifiManager.WIFI_STATE_ENABLING);
            enableWifi(retainedWifiState == WifiManager.WIFI_STATE_ENABLED
                    || retainedWifiState == WifiManager.WIFI_STATE_ENABLING);

            // wifi config
            nBytes = in.readInt();
@@ -714,6 +756,16 @@ public class SettingsBackupAgent extends BackupAgentHelper {
                    restoreLockSettings(buffer, nBytes);
                }
            }
            // softap config
            if (version >= FULL_BACKUP_ADDED_SOFTAP_CONF) {
                nBytes = in.readInt();
                if (DEBUG_BACKUP) Log.d(TAG, nBytes + " bytes of softap config data");
                if (nBytes > buffer.length) buffer = new byte[nBytes];
                if (nBytes > 0) {
                    in.readFully(buffer, 0, nBytes);
                    restoreSoftApConfiguration(buffer);
                }
            }

            if (DEBUG_BACKUP) Log.d(TAG, "Full restore complete.");
        } else {
@@ -1165,6 +1217,28 @@ public class SettingsBackupAgent extends BackupAgentHelper {
        }
    }

    private byte[] getSoftAPConfiguration() {
        WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
        try {
            return wifiManager.getWifiApConfiguration().getBytesForBackup();
        } catch (IOException ioe) {
            Log.e(TAG, "Failed to marshal SoftAPConfiguration" + ioe.getMessage());
            return new byte[0];
        }
    }

    private void restoreSoftApConfiguration(byte[] data) {
        WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
        try {
            WifiConfiguration config = WifiConfiguration
                    .getWifiConfigFromBackup(new DataInputStream(new ByteArrayInputStream(data)));
            if (DEBUG) Log.d(TAG, "Successfully unMarshaled WifiConfiguration ");
            wifiManager.setWifiApConfiguration(config);
        } catch (IOException | BackupUtils.BadVersionException e) {
            Log.e(TAG, "Failed to unMarshal SoftAPConfiguration " + e.getMessage());
        }
    }

    /**
     * Write an int in BigEndian into the byte array.
     * @param out byte array
@@ -1186,11 +1260,10 @@ public class SettingsBackupAgent extends BackupAgentHelper {
    }

    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;
    }

+57 −10
Original line number Diff line number Diff line
@@ -26,7 +26,12 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.BackupUtils;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.BitSet;
import java.util.HashMap;
@@ -37,6 +42,10 @@ import java.util.HashMap;
 */
public class WifiConfiguration implements Parcelable {
    private static final String TAG = "WifiConfiguration";
    /**
     * Current Version of the Backup Serializer.
    */
    private static final int BACKUP_VERSION = 2;
    /** {@hide} */
    public static final String ssidVarName = "ssid";
    /** {@hide} */
@@ -1453,7 +1462,7 @@ public class WifiConfiguration implements Parcelable {
                sbuf.append(" blackListed: ").append(Long.toString(diff / 1000)).append("sec ");
            }
        }
        if (creatorUid != 0)  sbuf.append(" cuid=" + Integer.toString(creatorUid));
        if (creatorUid != 0) sbuf.append(" cuid=" + creatorUid);
        if (creatorName != null) sbuf.append(" cname=" + creatorName);
        if (lastUpdateUid != 0) sbuf.append(" luid=" + lastUpdateUid);
        if (lastUpdateName != null) sbuf.append(" lname=" + lastUpdateName);
@@ -1500,7 +1509,6 @@ public class WifiConfiguration implements Parcelable {
                sbuf.append('\n');
            }
        }

        sbuf.append("triggeredLow: ").append(this.numUserTriggeredWifiDisableLowRSSI);
        sbuf.append(" triggeredBad: ").append(this.numUserTriggeredWifiDisableBadRSSI);
        sbuf.append(" triggeredNotHigh: ").append(this.numUserTriggeredWifiDisableNotHighRSSI);
@@ -1990,4 +1998,43 @@ public class WifiConfiguration implements Parcelable {
                return new WifiConfiguration[size];
            }
        };

    /**
     * Serializes the object for backup
     * @hide
     */
    public byte[] getBytesForBackup() throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DataOutputStream out = new DataOutputStream(baos);

        out.writeInt(BACKUP_VERSION);
        BackupUtils.writeString(out, SSID);
        out.writeInt(apBand);
        out.writeInt(apChannel);
        BackupUtils.writeString(out, preSharedKey);
        out.writeInt(getAuthType());
        return baos.toByteArray();
    }

    /**
     * Deserializes a byte array into the WiFiConfiguration Object
     * @hide
     */
    public static WifiConfiguration getWifiConfigFromBackup(DataInputStream in) throws IOException,
            BackupUtils.BadVersionException {
        WifiConfiguration config = new WifiConfiguration();
        int version = in.readInt();
        if (version < 1 || version > BACKUP_VERSION) {
            throw new BackupUtils.BadVersionException("Unknown Backup Serialization Version");
        }

        if (version == 1) return null; // Version 1 is a bad dataset.

        config.SSID = BackupUtils.readString(in);
        config.apBand = in.readInt();
        config.apChannel = in.readInt();
        config.preSharedKey = BackupUtils.readString(in);
        config.allowedKeyManagement.set(in.readInt());
        return config;
    }
}
 No newline at end of file