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

Commit 9c9088a5 authored by Irfan Sheriff's avatar Irfan Sheriff Committed by Android (Google) Code Review
Browse files

Merge "Move softap config handling to WifiConfigStore" into honeycomb-mr2

parents 51fb9703 ffcea7ae
Loading
Loading
Loading
Loading
+6 −45
Original line number Diff line number Diff line
@@ -559,31 +559,10 @@ public class WifiService extends IWifiManager.Stub {
     * @param wifiConfig SSID, security and channel details as
     *        part of WifiConfiguration
     * @param enabled true to enable and false to disable
     * @return {@code true} if the start operation was
     *         started or is already in the queue.
     */
    public synchronized boolean setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) {
    public void setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) {
        enforceChangePermission();

        if (enabled) {
            /* Use default config if there is no existing config */
            if (wifiConfig == null && ((wifiConfig = getWifiApConfiguration()) == null)) {
                wifiConfig = new WifiConfiguration();
                wifiConfig.SSID = mContext.getString(R.string.wifi_tether_configure_ssid_default);
                wifiConfig.allowedKeyManagement.set(KeyMgmt.NONE);
            }
            /*
             * Caller might not have WRITE_SECURE_SETTINGS,
             * only CHANGE_WIFI_STATE is enforced
             */
            long ident = Binder.clearCallingIdentity();
            setWifiApConfiguration(wifiConfig);
            Binder.restoreCallingIdentity(ident);
        }

        mWifiStateMachine.setWifiApEnabled(wifiConfig, enabled);

        return true;
    }

    /**
@@ -603,38 +582,20 @@ public class WifiService extends IWifiManager.Stub {
     * see {@link WifiManager#getWifiApConfiguration()}
     * @return soft access point configuration
     */
    public synchronized WifiConfiguration getWifiApConfiguration() {
        final ContentResolver cr = mContext.getContentResolver();
        WifiConfiguration wifiConfig = new WifiConfiguration();
        int authType;
        try {
            wifiConfig.SSID = Settings.Secure.getString(cr, Settings.Secure.WIFI_AP_SSID);
            if (wifiConfig.SSID == null)
                return null;
            authType = Settings.Secure.getInt(cr, Settings.Secure.WIFI_AP_SECURITY);
            wifiConfig.allowedKeyManagement.set(authType);
            wifiConfig.preSharedKey = Settings.Secure.getString(cr, Settings.Secure.WIFI_AP_PASSWD);
            return wifiConfig;
        } catch (Settings.SettingNotFoundException e) {
            Slog.e(TAG,"AP settings not found, returning");
            return null;
        }
    public WifiConfiguration getWifiApConfiguration() {
        enforceAccessPermission();
        return mWifiStateMachine.syncGetWifiApConfiguration(mWifiStateMachineChannel);
    }

    /**
     * see {@link WifiManager#setWifiApConfiguration(WifiConfiguration)}
     * @param wifiConfig WifiConfiguration details for soft access point
     */
    public synchronized void setWifiApConfiguration(WifiConfiguration wifiConfig) {
    public void setWifiApConfiguration(WifiConfiguration wifiConfig) {
        enforceChangePermission();
        final ContentResolver cr = mContext.getContentResolver();
        if (wifiConfig == null)
            return;
        int authType = wifiConfig.getAuthType();
        Settings.Secure.putString(cr, Settings.Secure.WIFI_AP_SSID, wifiConfig.SSID);
        Settings.Secure.putInt(cr, Settings.Secure.WIFI_AP_SECURITY, authType);
        if (authType != KeyMgmt.NONE)
            Settings.Secure.putString(cr, Settings.Secure.WIFI_AP_PASSWD, wifiConfig.preSharedKey);
        mWifiStateMachine.setWifiApConfiguration(wifiConfig);
    }

    /**
+1 −1
Original line number Diff line number Diff line
@@ -87,7 +87,7 @@ interface IWifiManager

    void releaseMulticastLock();

    boolean setWifiApEnabled(in WifiConfiguration wifiConfig, boolean enable);
    void setWifiApEnabled(in WifiConfiguration wifiConfig, boolean enable);

    int getWifiApEnabledState();

+181 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2010 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.net.wifi;

import android.content.Context;
import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.os.Environment;
import android.os.Message;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.util.UUID;

import com.android.internal.R;


/**
 * Provides API to the WifiStateMachine for doing read/write access
 * to soft access point configuration
 */
class WifiApConfigStore {

    private static Context sContext;
    private static final String TAG = "WifiApConfigStore";

    private static final String AP_CONFIG_FILE = Environment.getDataDirectory() +
        "/misc/wifi/softap.conf";

    private static final int AP_CONFIG_FILE_VERSION = 1;

    private static WifiConfiguration sApConfig = new WifiConfiguration();
    private static final Object sApConfigLock = new Object();

    private static FileReadWriteHandler sFileReadWriteHandler;
    private static final int READ_AP_CONFIG               = 1;
    private static final int WRITE_AP_CONFIG              = 2;

    static void initialize(Context context) {
        sContext = context;

        /* File operations happen on a seperate thread */
        HandlerThread configThread = new HandlerThread("WifiApConfigStore");
        configThread.start();
        sFileReadWriteHandler = new FileReadWriteHandler(configThread.getLooper());
        Message.obtain(sFileReadWriteHandler, READ_AP_CONFIG).sendToTarget();
    }


    static void setApConfiguration(WifiConfiguration config) {
        synchronized (sApConfigLock) {
            sApConfig = config;
        }
        Message.obtain(sFileReadWriteHandler, WRITE_AP_CONFIG, new WifiConfiguration(config))
            .sendToTarget();
    }

    static WifiConfiguration getApConfiguration() {
        synchronized (sApConfigLock) {
            return new WifiConfiguration(sApConfig);
        }
    }

    /**
     * File read/write handler
     */
    private static class FileReadWriteHandler extends Handler {

        public FileReadWriteHandler(android.os.Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case WRITE_AP_CONFIG:
                    writeApConfiguration((WifiConfiguration) msg.obj);
                    break;
                case READ_AP_CONFIG:
                    readApConfiguration();
                    break;
                default:
                    Log.e(TAG, "Unknown command in FileReadWriteHandler: " + msg);
                    break;
            }
        }

        private static void writeApConfiguration(final WifiConfiguration config) {
            DataOutputStream out = null;
            try {
                out = new DataOutputStream(new BufferedOutputStream(
                            new FileOutputStream(AP_CONFIG_FILE)));

                out.writeInt(AP_CONFIG_FILE_VERSION);
                out.writeUTF(config.SSID);
                int authType = config.getAuthType();
                out.writeInt(authType);
                if(authType != KeyMgmt.NONE) {
                    out.writeUTF(config.preSharedKey);
                }
            } catch (IOException e) {
                Log.e(TAG, "Error writing hotspot configuration" + e);
            } finally {
                if (out != null) {
                    try {
                        out.close();
                    } catch (IOException e) {}
                }
            }
        }

        private static void readApConfiguration() {
            DataInputStream in = null;
            try {
                WifiConfiguration config = new WifiConfiguration();
                in = new DataInputStream(new BufferedInputStream(new FileInputStream(
                                AP_CONFIG_FILE)));

                int version = in.readInt();
                if (version != 1) {
                    Log.e(TAG, "Bad version on hotspot configuration file, set defaults");
                    setDefaultApConfiguration();
                    return;
                }
                config.SSID = in.readUTF();
                int authType = in.readInt();
                config.allowedKeyManagement.set(authType);
                if (authType != KeyMgmt.NONE) {
                    config.preSharedKey = in.readUTF();
                }
                synchronized (sApConfigLock) {
                    sApConfig = config;
                }
            } catch (IOException ignore) {
                setDefaultApConfiguration();
            } finally {
                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException e) {}
                }
            }
        }

        /* Generate a default WPA2 based configuration with a random password.
           We are changing the Wifi Ap configuration storage from secure settings to a
           flat file accessible only by the system. A WPA2 based default configuration
           will keep the device secure after the update */
        private static void setDefaultApConfiguration() {
            WifiConfiguration config = new WifiConfiguration();
            config.SSID = sContext.getString(R.string.wifi_tether_configure_ssid_default);
            config.allowedKeyManagement.set(KeyMgmt.WPA2_PSK);
            String randomUUID = UUID.randomUUID().toString();
            //first 12 chars from xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
            config.preSharedKey = randomUUID.substring(0, 8) + randomUUID.substring(9,13);
            setApConfiguration(config);
        }
    }
}
+2 −1
Original line number Diff line number Diff line
@@ -898,7 +898,8 @@ public class WifiManager {
     */
    public boolean setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) {
        try {
            return mService.setWifiApEnabled(wifiConfig, enabled);
            mService.setWifiApEnabled(wifiConfig, enabled);
            return true;
        } catch (RemoteException e) {
            return false;
        }
+67 −35
Original line number Diff line number Diff line
@@ -200,8 +200,12 @@ public class WifiStateMachine extends HierarchicalStateMachine {
    static final int CMD_START_AP                         = BASE + 21;
    /* Stop the soft access point */
    static final int CMD_STOP_AP                          = BASE + 22;
    /* Set the soft access point configuration */
    static final int CMD_SET_AP_CONFIG                    = BASE + 23;
    /* Get the soft access point configuration */
    static final int CMD_GET_AP_CONFIG                    = BASE + 24;

    static final int CMD_BLUETOOTH_ADAPTER_STATE_CHANGE   = BASE + 23;
    static final int CMD_BLUETOOTH_ADAPTER_STATE_CHANGE   = BASE + 25;

    /* Supplicant events */
    /* Connection to supplicant established */
@@ -355,6 +359,10 @@ public class WifiStateMachine extends HierarchicalStateMachine {
    private static final int MIN_RSSI = -200;
    private static final int MAX_RSSI = 256;

    /* Constants to indicate if soft ap is running or stopped */
    private static final int SOFT_AP_STOPPED = 0;
    private static final int SOFT_AP_RUNNING = 1;

    /* Default parent state */
    private HierarchicalState mDefaultState = new DefaultState();
    /* Temporary initial state */
@@ -593,6 +601,17 @@ public class WifiStateMachine extends HierarchicalStateMachine {
        }
    }

    public void setWifiApConfiguration(WifiConfiguration config) {
        sendMessage(obtainMessage(CMD_SET_AP_CONFIG, config));
    }

    public WifiConfiguration syncGetWifiApConfiguration(AsyncChannel channel) {
        Message resultMsg = channel.sendMessageSynchronously(CMD_GET_AP_CONFIG);
        WifiConfiguration ret = (WifiConfiguration) resultMsg.obj;
        resultMsg.recycle();
        return ret;
    }

    /**
     * TODO: doc
     */
@@ -1517,7 +1536,31 @@ public class WifiStateMachine extends HierarchicalStateMachine {
         */
        WifiNative.disconnectCommand();
        WifiNative.reconnectCommand();
    }

    private boolean startSoftApWithConfig(WifiConfiguration config, int currentStatus) {
        if (config == null) {
            config = WifiApConfigStore.getApConfiguration();
        } else {
            WifiApConfigStore.setApConfiguration(config);
        }
        try {
            if (currentStatus == SOFT_AP_STOPPED) {
                nwService.startAccessPoint(config, mInterfaceName, SOFTAP_IFACE);
            } else if (currentStatus == SOFT_AP_RUNNING) {
                nwService.setAccessPoint(config, mInterfaceName, SOFTAP_IFACE);
            }
        } catch (Exception e) {
            Log.e(TAG, "Exception in softap start " + e);
            try {
                nwService.stopAccessPoint();
                nwService.startAccessPoint(config, mInterfaceName, SOFTAP_IFACE);
            } catch (Exception ee) {
                Log.e(TAG, "Exception during softap restart : " + ee);
                return false;
            }
        }
        return true;
    }


@@ -1655,6 +1698,13 @@ public class WifiStateMachine extends HierarchicalStateMachine {
                case CMD_ENABLE_BACKGROUND_SCAN:
                    mEnableBackgroundScan = (message.arg1 == 1);
                    break;
                case CMD_SET_AP_CONFIG:
                    WifiApConfigStore.setApConfiguration((WifiConfiguration) message.obj);
                    break;
                case CMD_GET_AP_CONFIG:
                    WifiConfiguration config = WifiApConfigStore.getApConfiguration();
                    mReplyChannel.replyToMessage(message, message.what, config);
                    break;
                    /* Discard */
                case CMD_LOAD_DRIVER:
                case CMD_UNLOAD_DRIVER:
@@ -1717,6 +1767,8 @@ public class WifiStateMachine extends HierarchicalStateMachine {
            // 50021 wifi_state_changed (custom|1|5)
            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());

            WifiApConfigStore.initialize(mContext);

            if (WifiNative.isDriverLoaded()) {
                transitionTo(mDriverLoadedState);
            }
@@ -1829,26 +1881,14 @@ public class WifiStateMachine extends HierarchicalStateMachine {
                    }
                    break;
                case CMD_START_AP:
                    try {
                        nwService.startAccessPoint((WifiConfiguration) message.obj,
                                    mInterfaceName,
                                    SOFTAP_IFACE);
                    } catch (Exception e) {
                        Log.e(TAG, "Exception in softap start " + e);
                        try {
                            nwService.stopAccessPoint();
                            nwService.startAccessPoint((WifiConfiguration) message.obj,
                                    mInterfaceName,
                                    SOFTAP_IFACE);
                        } catch (Exception ee) {
                            Log.e(TAG, "Exception during softap restart : " + ee);
                            sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_FAILED, 0));
                            break;
                        }
                    }
                    if (startSoftApWithConfig((WifiConfiguration) message.obj, SOFT_AP_STOPPED)) {
                        Log.d(TAG, "Soft AP start successful");
                        setWifiApState(WIFI_AP_STATE_ENABLED);
                        transitionTo(mSoftApStartedState);
                    } else {
                        Log.d(TAG, "Soft AP start failed");
                        sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_FAILED, 0));
                    }
                    break;
                default:
                    return NOT_HANDLED;
@@ -2999,22 +3039,14 @@ public class WifiStateMachine extends HierarchicalStateMachine {
                    break;
                case CMD_START_AP:
                    Log.d(TAG,"SoftAP set on a running access point");
                    try {
                        nwService.setAccessPoint((WifiConfiguration) message.obj,
                                    mInterfaceName,
                                    SOFTAP_IFACE);
                    } catch(Exception e) {
                        Log.e(TAG, "Exception in softap set " + e);
                        try {
                            nwService.stopAccessPoint();
                            nwService.startAccessPoint((WifiConfiguration) message.obj,
                                    mInterfaceName,
                                    SOFTAP_IFACE);
                        } catch (Exception ee) {
                            Log.e(TAG, "Could not restart softap after set failed " + ee);
                    if (startSoftApWithConfig((WifiConfiguration) message.obj, SOFT_AP_RUNNING)) {
                        Log.d(TAG, "Soft AP start successful");
                        setWifiApState(WIFI_AP_STATE_ENABLED);
                        transitionTo(mSoftApStartedState);
                    } else {
                        Log.d(TAG, "Soft AP start failed");
                        sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_FAILED, 0));
                    }
                    }
                    break;
                /* Fail client mode operation when soft AP is enabled */
                case CMD_START_SUPPLICANT: