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

Commit d488bc0e authored by Christopher Tate's avatar Christopher Tate
Browse files

Defer wifi bounce following restore for 1 minute...

...to allow network-reliant restore actions by apps to get underway.

Bug 7304761

Change-Id: Ia1d2321ef86609588efbc7add043c24a12ec6a20
parent 64cb35c0
Loading
Loading
Loading
Loading
+80 −41
Original line number Original line Diff line number Diff line
@@ -26,6 +26,7 @@ import android.database.Cursor;
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.FileUtils;
import android.os.Handler;
import android.os.ParcelFileDescriptor;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.Process;
import android.provider.Settings;
import android.provider.Settings;
@@ -61,12 +62,6 @@ public class SettingsBackupAgent extends BackupAgentHelper {
    private static final boolean DEBUG = false;
    private static final boolean DEBUG = false;
    private static final boolean DEBUG_BACKUP = DEBUG || false;
    private static final boolean DEBUG_BACKUP = DEBUG || false;


    /* Don't restore wifi config until we have new logic for parsing the
     * saved wifi config and configuring the new APs without having to
     * disable and re-enable wifi
     */
    private static final boolean NAIVE_WIFI_RESTORE = false;

    private static final String KEY_SYSTEM = "system";
    private static final String KEY_SYSTEM = "system";
    private static final String KEY_SECURE = "secure";
    private static final String KEY_SECURE = "secure";
    private static final String KEY_GLOBAL = "global";
    private static final String KEY_GLOBAL = "global";
@@ -127,10 +122,16 @@ public class SettingsBackupAgent extends BackupAgentHelper {
    // stored in the full-backup tarfile as well, so should not be changed.
    // stored in the full-backup tarfile as well, so should not be changed.
    private static final String STAGE_FILE = "flattened-data";
    private static final String STAGE_FILE = "flattened-data";


    // Delay in milliseconds between the restore operation and when we will bounce
    // wifi in order to rewrite the supplicant config etc.
    private static final long WIFI_BOUNCE_DELAY_MILLIS = 60 * 1000; // one minute

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


    WifiRestoreRunnable mWifiRestore = null;

    // Class for capturing a network definition from the wifi supplicant config file
    // Class for capturing a network definition from the wifi supplicant config file
    static class Network {
    static class Network {
        String ssid = "";  // equals() and hashCode() need these to be non-null
        String ssid = "";  // equals() and hashCode() need these to be non-null
@@ -297,6 +298,66 @@ public class SettingsBackupAgent extends BackupAgentHelper {
        writeNewChecksums(stateChecksums, newState);
        writeNewChecksums(stateChecksums, newState);
    }
    }


    class WifiRestoreRunnable implements Runnable {
        private byte[] restoredSupplicantData;
        private byte[] restoredWifiConfigFile;

        void incorporateWifiSupplicant(BackupDataInput data) {
            restoredSupplicantData = new byte[data.getDataSize()];
            if (restoredSupplicantData.length <= 0) return;
            try {
                data.readEntityData(restoredSupplicantData, 0, data.getDataSize());
            } catch (IOException e) {
                Log.w(TAG, "Unable to read supplicant data");
                restoredSupplicantData = null;
            }
        }

        void incorporateWifiConfigFile(BackupDataInput data) {
            restoredWifiConfigFile = new byte[data.getDataSize()];
            if (restoredWifiConfigFile.length <= 0) return;
            try {
                data.readEntityData(restoredWifiConfigFile, 0, data.getDataSize());
            } catch (IOException e) {
                Log.w(TAG, "Unable to read config file");
                restoredWifiConfigFile = null;
            }
        }

        @Override
        public void run() {
            if (restoredSupplicantData != null || restoredWifiConfigFile != null) {
                if (DEBUG_BACKUP) {
                    Log.v(TAG, "Starting deferred restore of wifi data");
                }
                final int retainedWifiState = enableWifi(false);
                if (restoredSupplicantData != null) {
                    restoreWifiSupplicant(FILE_WIFI_SUPPLICANT,
                            restoredSupplicantData, restoredSupplicantData.length);
                    FileUtils.setPermissions(FILE_WIFI_SUPPLICANT,
                            FileUtils.S_IRUSR | FileUtils.S_IWUSR |
                            FileUtils.S_IRGRP | FileUtils.S_IWGRP,
                            Process.myUid(), Process.WIFI_UID);
                }
                if (restoredWifiConfigFile != null) {
                    restoreFileData(mWifiConfigFile,
                            restoredWifiConfigFile, restoredWifiConfigFile.length);
                }
                // restore the previous WIFI state.
                enableWifi(retainedWifiState == WifiManager.WIFI_STATE_ENABLED ||
                        retainedWifiState == WifiManager.WIFI_STATE_ENABLING);
            }
        }
    }

    // Instantiate the wifi-config restore runnable, scheduling it for execution
    // a minute hence
    void initWifiRestoreIfNecessary() {
        if (mWifiRestore == null) {
            mWifiRestore = new WifiRestoreRunnable();
        }
    }

    @Override
    @Override
    public void onRestore(BackupDataInput data, int appVersionCode,
    public void onRestore(BackupDataInput data, int appVersionCode,
            ParcelFileDescriptor newState) throws IOException {
            ParcelFileDescriptor newState) throws IOException {
@@ -315,26 +376,26 @@ public class SettingsBackupAgent extends BackupAgentHelper {
                restoreSettings(data, Settings.Secure.CONTENT_URI, movedToGlobal);
                restoreSettings(data, Settings.Secure.CONTENT_URI, movedToGlobal);
            } else if (KEY_GLOBAL.equals(key)) {
            } else if (KEY_GLOBAL.equals(key)) {
                restoreSettings(data, Settings.Global.CONTENT_URI, null);
                restoreSettings(data, Settings.Global.CONTENT_URI, null);
            } else if (NAIVE_WIFI_RESTORE && KEY_WIFI_SUPPLICANT.equals(key)) {
            } else if (KEY_WIFI_SUPPLICANT.equals(key)) {
                int retainedWifiState = enableWifi(false);
                initWifiRestoreIfNecessary();
                restoreWifiSupplicant(FILE_WIFI_SUPPLICANT, data);
                mWifiRestore.incorporateWifiSupplicant(data);
                FileUtils.setPermissions(FILE_WIFI_SUPPLICANT,
                        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);
            } else if (KEY_LOCALE.equals(key)) {
            } else if (KEY_LOCALE.equals(key)) {
                byte[] localeData = new byte[size];
                byte[] localeData = new byte[size];
                data.readEntityData(localeData, 0, size);
                data.readEntityData(localeData, 0, size);
                mSettingsHelper.setLocaleData(localeData, size);
                mSettingsHelper.setLocaleData(localeData, size);
            } else if (NAIVE_WIFI_RESTORE && KEY_WIFI_CONFIG.equals(key)) {
            } else if (KEY_WIFI_CONFIG.equals(key)) {
                restoreFileData(mWifiConfigFile, data);
                initWifiRestoreIfNecessary();
                mWifiRestore.incorporateWifiConfigFile(data);
             } else {
             } else {
                data.skipEntityData();
                data.skipEntityData();
            }
            }
        }
        }

        // If we have wifi data to restore, post a runnable to perform the
        // bounce-and-update operation a little ways in the future.
        if (mWifiRestore != null) {
            new Handler(getMainLooper()).postDelayed(mWifiRestore, WIFI_BOUNCE_DELAY_MILLIS);
        }
    }
    }


    @Override
    @Override
@@ -619,7 +680,7 @@ public class SettingsBackupAgent extends BackupAgentHelper {
                getContentResolver().insert(destination, contentValues);
                getContentResolver().insert(destination, contentValues);
            }
            }


            if (DEBUG || true) {
            if (DEBUG) {
                Log.d(TAG, "Restored setting: " + destination + " : "+ key + "=" + value);
                Log.d(TAG, "Restored setting: " + destination + " : "+ key + "=" + value);
            }
            }
        }
        }
@@ -731,17 +792,6 @@ public class SettingsBackupAgent extends BackupAgentHelper {


    }
    }


    private void restoreFileData(String filename, BackupDataInput data) {
        byte[] bytes = new byte[data.getDataSize()];
        if (bytes.length <= 0) return;
        try {
            data.readEntityData(bytes, 0, data.getDataSize());
            restoreFileData(filename, bytes, bytes.length);
        } catch (IOException e) {
            Log.w(TAG, "Unable to read file data for " + filename);
        }
    }

    private void restoreFileData(String filename, byte[] bytes, int size) {
    private void restoreFileData(String filename, byte[] bytes, int size) {
        try {
        try {
            File file = new File(filename);
            File file = new File(filename);
@@ -794,17 +844,6 @@ public class SettingsBackupAgent extends BackupAgentHelper {
        }
        }
    }
    }


    private void restoreWifiSupplicant(String filename, BackupDataInput data) {
        byte[] bytes = new byte[data.getDataSize()];
        if (bytes.length <= 0) return;
        try {
            data.readEntityData(bytes, 0, data.getDataSize());
            restoreWifiSupplicant(filename, bytes, bytes.length);
        } catch (IOException e) {
            Log.w(TAG, "Unable to read supplicant data");
        }
    }

    private void restoreWifiSupplicant(String filename, byte[] bytes, int size) {
    private void restoreWifiSupplicant(String filename, byte[] bytes, int size) {
        try {
        try {
            WifiNetworkSettings supplicantImage = new WifiNetworkSettings();
            WifiNetworkSettings supplicantImage = new WifiNetworkSettings();