FileDocCategorySizeDatePackage
WifiServiceImpl.javaAPI DocAndroid 5.1 API68892Thu Mar 12 22:22:52 GMT 2015com.android.server.wifi

WifiServiceImpl

public final class WifiServiceImpl extends IWifiManager.Stub
WifiService handles remote WiFi operation requests by implementing the IWifiManager interface.
hide

Fields Summary
private static final String
TAG
private static final boolean
DBG
final WifiStateMachine
mWifiStateMachine
private final android.content.Context
mContext
final LockList
mLocks
private int
mFullHighPerfLocksAcquired
private int
mFullHighPerfLocksReleased
private int
mFullLocksAcquired
private int
mFullLocksReleased
private int
mScanLocksAcquired
private int
mScanLocksReleased
private final List
mMulticasters
private int
mMulticastEnabled
private int
mMulticastDisabled
private final com.android.internal.app.IBatteryStats
mBatteryStats
private final android.app.AppOpsManager
mAppOps
private String
mInterfaceName
private int
scanRequestCounter
private WifiNotificationController
mNotificationController
private WifiTrafficPoller
mTrafficPoller
final WifiSettingsStore
mSettingsStore
final boolean
mBatchedScanSupported
private com.android.internal.util.AsyncChannel
mWifiStateMachineChannel
Asynchronous channel to WifiStateMachine
private ClientHandler
mClientHandler
WifiStateMachineHandler
mWifiStateMachineHandler
private WifiWatchdogStateMachine
mWifiWatchdogStateMachine
private WifiController
mWifiController
private final List
mBatchedScanners
private final android.content.BroadcastReceiver
mReceiver
Constructors Summary
public WifiServiceImpl(android.content.Context context)

        mContext = context;

        mInterfaceName =  SystemProperties.get("wifi.interface", "wlan0");

        mTrafficPoller = new WifiTrafficPoller(mContext, mInterfaceName);
        mWifiStateMachine = new WifiStateMachine(mContext, mInterfaceName, mTrafficPoller);
        mWifiStateMachine.enableRssiPolling(true);
        mBatteryStats = BatteryStatsService.getService();
        mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);

        mNotificationController = new WifiNotificationController(mContext, mWifiStateMachine);
        mSettingsStore = new WifiSettingsStore(mContext);

        HandlerThread wifiThread = new HandlerThread("WifiService");
        wifiThread.start();
        mClientHandler = new ClientHandler(wifiThread.getLooper());
        mWifiStateMachineHandler = new WifiStateMachineHandler(wifiThread.getLooper());
        mWifiController = new WifiController(mContext, this, wifiThread.getLooper());

        mBatchedScanSupported = mContext.getResources().getBoolean(
                R.bool.config_wifi_batched_scan_supported);
    
Methods Summary
public voidacquireMulticastLock(android.os.IBinder binder, java.lang.String tag)

        enforceMulticastChangePermission();

        synchronized (mMulticasters) {
            mMulticastEnabled++;
            mMulticasters.add(new Multicaster(tag, binder));
            // Note that we could call stopFilteringMulticastV4Packets only when
            // our new size == 1 (first call), but this function won't
            // be called often and by making the stopPacket call each
            // time we're less fragile and self-healing.
            mWifiStateMachine.stopFilteringMulticastV4Packets();
        }

        int uid = Binder.getCallingUid();
        final long ident = Binder.clearCallingIdentity();
        try {
            mBatteryStats.noteWifiMulticastEnabled(uid);
        } catch (RemoteException e) {
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
    
public booleanacquireWifiLock(android.os.IBinder binder, int lockMode, java.lang.String tag, android.os.WorkSource ws)

        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
        if (lockMode != WifiManager.WIFI_MODE_FULL &&
                lockMode != WifiManager.WIFI_MODE_SCAN_ONLY &&
                lockMode != WifiManager.WIFI_MODE_FULL_HIGH_PERF) {
            Slog.e(TAG, "Illegal argument, lockMode= " + lockMode);
            if (DBG) throw new IllegalArgumentException("lockMode=" + lockMode);
            return false;
        }
        if (ws != null && ws.size() == 0) {
            ws = null;
        }
        if (ws != null) {
            enforceWakeSourcePermission(Binder.getCallingUid(), Binder.getCallingPid());
        }
        if (ws == null) {
            ws = new WorkSource(Binder.getCallingUid());
        }
        WifiLock wifiLock = new WifiLock(lockMode, tag, binder, ws);
        synchronized (mLocks) {
            return acquireWifiLockLocked(wifiLock);
        }
    
private booleanacquireWifiLockLocked(com.android.server.wifi.WifiServiceImpl$WifiLock wifiLock)

        if (DBG) Slog.d(TAG, "acquireWifiLockLocked: " + wifiLock);

        mLocks.addLock(wifiLock);

        long ident = Binder.clearCallingIdentity();
        try {
            noteAcquireWifiLock(wifiLock);
            switch(wifiLock.mMode) {
            case WifiManager.WIFI_MODE_FULL:
                ++mFullLocksAcquired;
                break;
            case WifiManager.WIFI_MODE_FULL_HIGH_PERF:
                ++mFullHighPerfLocksAcquired;
                break;

            case WifiManager.WIFI_MODE_SCAN_ONLY:
                ++mScanLocksAcquired;
                break;
            }
            mWifiController.sendMessage(CMD_LOCKS_CHANGED);
            return true;
        } catch (RemoteException e) {
            return false;
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
    
public intaddOrUpdateNetwork(WifiConfiguration config)
see {@link android.net.wifi.WifiManager#addOrUpdateNetwork(WifiConfiguration)}

return
the supplicant-assigned identifier for the new or updated network if the operation succeeds, or {@code -1} if it fails

        enforceChangePermission();
        if (config.isValid()) {
            //TODO: pass the Uid the WifiStateMachine as a message parameter
            Slog.e("addOrUpdateNetwork", " uid = " + Integer.toString(Binder.getCallingUid())
                    + " SSID " + config.SSID
                    + " nid=" + Integer.toString(config.networkId));
            if (config.networkId == WifiConfiguration.INVALID_NETWORK_ID) {
                config.creatorUid = Binder.getCallingUid();
            } else {
                config.lastUpdateUid = Binder.getCallingUid();
            }
            if (mWifiStateMachineChannel != null) {
                return mWifiStateMachine.syncAddOrUpdateNetwork(mWifiStateMachineChannel, config);
            } else {
                Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
                return -1;
            }
        } else {
            Slog.e(TAG, "bad network configuration");
            return -1;
        }
    
public voidaddToBlacklist(java.lang.String bssid)
see {@link android.net.wifi.WifiManager#addToBlacklist}

        enforceChangePermission();

        mWifiStateMachine.addToBlacklist(bssid);
    
public voidcheckAndStartWifi()
Check if Wi-Fi needs to be enabled and start if needed This function is used only at boot time

        /* Check if wi-fi needs to be enabled */
        boolean wifiEnabled = mSettingsStore.isWifiToggleEnabled();
        Slog.i(TAG, "WifiService starting up with Wi-Fi " +
                (wifiEnabled ? "enabled" : "disabled"));

        registerForScanModeChange();
        mContext.registerReceiver(
                new BroadcastReceiver() {
                    @Override
                    public void onReceive(Context context, Intent intent) {
                        if (mSettingsStore.handleAirplaneModeToggled()) {
                            mWifiController.sendMessage(CMD_AIRPLANE_TOGGLED);
                        }
                    }
                },
                new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED));

        // Adding optimizations of only receiving broadcasts when wifi is enabled
        // can result in race conditions when apps toggle wifi in the background
        // without active user involvement. Always receive broadcasts.
        registerForBroadcasts();

        mWifiController.start();

        // If we are already disabled (could be due to airplane mode), avoid changing persist
        // state here
        if (wifiEnabled) setWifiEnabled(wifiEnabled);

        mWifiWatchdogStateMachine = WifiWatchdogStateMachine.
               makeWifiWatchdogStateMachine(mContext, mWifiStateMachine.getMessenger());
    
private booleancheckInteractAcrossUsersFull()
Returns true if the caller holds INTERACT_ACROSS_USERS_FULL.

        return mContext.checkCallingOrSelfPermission(
                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
                == PackageManager.PERMISSION_GRANTED;
    
public voidclearBlacklist()
see {@link android.net.wifi.WifiManager#clearBlacklist}

        enforceChangePermission();

        mWifiStateMachine.clearBlacklist();
    
public voiddisableEphemeralNetwork(java.lang.String SSID)
Disable an ephemeral network, i.e. network that is created thru a WiFi Scorer

        enforceAccessPermission();
        enforceChangePermission();
        mWifiStateMachine.disableEphemeralNetwork(SSID);
    
public booleandisableNetwork(int netId)
See {@link android.net.wifi.WifiManager#disableNetwork(int)}

param
netId the integer that identifies the network configuration to the supplicant
return
{@code true} if the operation succeeded

        enforceChangePermission();
        if (mWifiStateMachineChannel != null) {
            return mWifiStateMachine.syncDisableNetwork(mWifiStateMachineChannel, netId);
        } else {
            Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
            return false;
        }
    
public voiddisconnect()
see {@link android.net.wifi.WifiManager#disconnect()}

        enforceChangePermission();
        mWifiStateMachine.disconnectCommand();
    
protected voiddump(java.io.FileDescriptor fd, java.io.PrintWriter pw, java.lang.String[] args)

        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
                != PackageManager.PERMISSION_GRANTED) {
            pw.println("Permission Denial: can't dump WifiService from from pid="
                    + Binder.getCallingPid()
                    + ", uid=" + Binder.getCallingUid());
            return;
        }
        pw.println("Wi-Fi is " + mWifiStateMachine.syncGetWifiStateByName());
        pw.println("Stay-awake conditions: " +
                Settings.Global.getInt(mContext.getContentResolver(),
                                       Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0));
        pw.println("mMulticastEnabled " + mMulticastEnabled);
        pw.println("mMulticastDisabled " + mMulticastDisabled);
        mWifiController.dump(fd, pw, args);
        mSettingsStore.dump(fd, pw, args);
        mNotificationController.dump(fd, pw, args);
        mTrafficPoller.dump(fd, pw, args);

        pw.println("Latest scan results:");
        List<ScanResult> scanResults = mWifiStateMachine.syncGetScanResultsList();
        long nowMs = System.currentTimeMillis();
        if (scanResults != null && scanResults.size() != 0) {
            pw.println("    BSSID              Frequency  RSSI    Age      SSID " +
                    "                                Flags");
            for (ScanResult r : scanResults) {
                long ageSec = 0;
                long ageMilli = 0;
                if (nowMs > r.seen && r.seen > 0) {
                    ageSec = (nowMs - r.seen) / 1000;
                    ageMilli = (nowMs - r.seen) % 1000;
                }
                String candidate = " ";
                if (r.isAutoJoinCandidate > 0) candidate = "+";
                pw.printf("  %17s  %9d  %5d  %3d.%03d%s   %-32s  %s\n",
                                         r.BSSID,
                                         r.frequency,
                                         r.level,
                                         ageSec, ageMilli,
                                         candidate,
                                         r.SSID == null ? "" : r.SSID,
                                         r.capabilities);
            }
        }
        pw.println();
        pw.println("Locks acquired: " + mFullLocksAcquired + " full, " +
                mFullHighPerfLocksAcquired + " full high perf, " +
                mScanLocksAcquired + " scan");
        pw.println("Locks released: " + mFullLocksReleased + " full, " +
                mFullHighPerfLocksReleased + " full high perf, " +
                mScanLocksReleased + " scan");
        pw.println();
        pw.println("Locks held:");
        mLocks.dump(pw);

        mWifiWatchdogStateMachine.dump(fd, pw, args);
        pw.println();
        mWifiStateMachine.dump(fd, pw, args);
        pw.println();
    
public voidenableAggressiveHandover(int enabled)

        enforceAccessPermission();
        mWifiStateMachine.enableAggressiveHandover(enabled);
    
public booleanenableNetwork(int netId, boolean disableOthers)
See {@link android.net.wifi.WifiManager#enableNetwork(int, boolean)}

param
netId the integer that identifies the network configuration to the supplicant
param
disableOthers if true, disable all other networks.
return
{@code true} if the operation succeeded

        enforceChangePermission();
        if (mWifiStateMachineChannel != null) {
            return mWifiStateMachine.syncEnableNetwork(mWifiStateMachineChannel, netId,
                    disableOthers);
        } else {
            Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
            return false;
        }
    
public voidenableTdls(java.lang.String remoteAddress, boolean enable)

        if (remoteAddress == null) {
          throw new IllegalArgumentException("remoteAddress cannot be null");
        }

        TdlsTaskParams params = new TdlsTaskParams();
        params.remoteIpAddress = remoteAddress;
        params.enable = enable;
        new TdlsTask().execute(params);
    
public voidenableTdlsWithMacAddress(java.lang.String remoteMacAddress, boolean enable)

        if (remoteMacAddress == null) {
          throw new IllegalArgumentException("remoteMacAddress cannot be null");
        }

        mWifiStateMachine.enableTdls(remoteMacAddress, enable);
    
public voidenableVerboseLogging(int verbose)

        enforceAccessPermission();
        mWifiStateMachine.enableVerboseLogging(verbose);
    
private voidenforceAccessPermission()

        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_WIFI_STATE,
                "WifiService");
    
private voidenforceChangePermission()

        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CHANGE_WIFI_STATE,
                                                "WifiService");
    
private voidenforceConnectivityInternalPermission()

        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.CONNECTIVITY_INTERNAL,
                "ConnectivityService");
    
private voidenforceLocationHardwarePermission()

        mContext.enforceCallingOrSelfPermission(Manifest.permission.LOCATION_HARDWARE,
                "LocationHardware");
    
private voidenforceMulticastChangePermission()

        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.CHANGE_WIFI_MULTICAST_STATE,
                "WifiService");
    
private voidenforceReadCredentialPermission()

        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.READ_WIFI_CREDENTIAL,
                                                "WifiService");
    
voidenforceWakeSourcePermission(int uid, int pid)

        if (uid == android.os.Process.myUid()) {
            return;
        }
        mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
                pid, uid, null);
    
private voidenforceWorkSourcePermission()

        mContext.enforceCallingPermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
                "WifiService");

    
public intgetAggressiveHandover()

        enforceAccessPermission();
        return mWifiStateMachine.getAggressiveHandover();
    
public intgetAllowScansWithTraffic()

        enforceAccessPermission();
        return mWifiStateMachine.getAllowScansWithTraffic();
    
public java.util.ListgetBatchedScanResults(java.lang.String callingPackage)

        enforceAccessPermission();
        if (mBatchedScanSupported == false) return new ArrayList<BatchedScanResult>();
        int uid = Binder.getCallingUid();
        int userId = UserHandle.getCallingUserId();
        boolean hasInteractUsersFull = checkInteractAcrossUsersFull();
        long ident = Binder.clearCallingIdentity();
        try {
            if (mAppOps.noteOp(AppOpsManager.OP_WIFI_SCAN, uid, callingPackage)
                    != AppOpsManager.MODE_ALLOWED) {
                return new ArrayList<BatchedScanResult>();
            }
            if (!isCurrentProfile(userId) && !hasInteractUsersFull) {
                return new ArrayList<BatchedScanResult>();
            }
            return mWifiStateMachine.syncGetBatchedScanResultsList();
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
    
public java.util.ListgetChannelList()
see {@link android.net.wifi.WifiManager#getChannelList}

        enforceAccessPermission();
        if (mWifiStateMachineChannel != null) {
            return mWifiStateMachine.syncGetChannelList(mWifiStateMachineChannel);
        } else {
            Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
            return null;
        }
    
public java.lang.StringgetConfigFile()
Get the IP and proxy configuration file

        enforceAccessPermission();
        return mWifiStateMachine.getConfigFile();
    
public java.util.ListgetConfiguredNetworks()
see {@link android.net.wifi.WifiManager#getConfiguredNetworks()}

return
the list of configured networks

        enforceAccessPermission();
        if (mWifiStateMachineChannel != null) {
            return mWifiStateMachine.syncGetConfiguredNetworks(Binder.getCallingUid(),
                    mWifiStateMachineChannel);
        } else {
            Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
            return null;
        }
    
public WifiInfogetConnectionInfo()
See {@link android.net.wifi.WifiManager#getConnectionInfo()}

return
the Wi-Fi information, contained in {@link WifiInfo}.

        enforceAccessPermission();
        /*
         * Make sure we have the latest information, by sending
         * a status request to the supplicant.
         */
        return mWifiStateMachine.syncRequestConnectionInfo();
    
public WifiConnectionStatisticsgetConnectionStatistics()

        enforceAccessPermission();
        enforceReadCredentialPermission();
        if (mWifiStateMachineChannel != null) {
            return mWifiStateMachine.syncGetConnectionStatistics(mWifiStateMachineChannel);
        } else {
            Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
            return null;
        }
    
public android.net.DhcpInfogetDhcpInfo()
Return the DHCP-assigned addresses from the last successful DHCP request, if any.

return
the DHCP information
deprecated

        enforceAccessPermission();
        DhcpResults dhcpResults = mWifiStateMachine.syncGetDhcpResults();

        DhcpInfo info = new DhcpInfo();

        if (dhcpResults.ipAddress != null &&
                dhcpResults.ipAddress.getAddress() instanceof Inet4Address) {
            info.ipAddress = NetworkUtils.inetAddressToInt((Inet4Address) dhcpResults.ipAddress.getAddress());
        }

        if (dhcpResults.gateway != null) {
            info.gateway = NetworkUtils.inetAddressToInt((Inet4Address) dhcpResults.gateway);
        }

        int dnsFound = 0;
        for (InetAddress dns : dhcpResults.dnsServers) {
            if (dns instanceof Inet4Address) {
                if (dnsFound == 0) {
                    info.dns1 = NetworkUtils.inetAddressToInt((Inet4Address)dns);
                } else {
                    info.dns2 = NetworkUtils.inetAddressToInt((Inet4Address)dns);
                }
                if (++dnsFound > 1) break;
            }
        }
        InetAddress serverAddress = dhcpResults.serverAddress;
        if (serverAddress instanceof Inet4Address) {
            info.serverAddress = NetworkUtils.inetAddressToInt((Inet4Address)serverAddress);
        }
        info.leaseDuration = dhcpResults.leaseDuration;

        return info;
    
public intgetFrequencyBand()
Get the operational frequency band

        enforceAccessPermission();
        return mWifiStateMachine.getFrequencyBand();
    
public java.util.ListgetPrivilegedConfiguredNetworks()
see {@link android.net.wifi.WifiManager#getPrivilegedConfiguredNetworks()}

return
the list of configured networks with real preSharedKey

        enforceReadCredentialPermission();
        enforceAccessPermission();
        if (mWifiStateMachineChannel != null) {
            return mWifiStateMachine.syncGetPrivilegedConfiguredNetwork(mWifiStateMachineChannel);
        } else {
            Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
            return null;
        }
    
public java.util.ListgetScanResults(java.lang.String callingPackage)
Return the results of the most recent access point scan, in the form of a list of {@link ScanResult} objects.

return
the list of results

        enforceAccessPermission();
        int userId = UserHandle.getCallingUserId();
        int uid = Binder.getCallingUid();
        boolean hasInteractUsersFull = checkInteractAcrossUsersFull();
        long ident = Binder.clearCallingIdentity();
        try {
            if (mAppOps.noteOp(AppOpsManager.OP_WIFI_SCAN, uid, callingPackage)
                    != AppOpsManager.MODE_ALLOWED) {
                return new ArrayList<ScanResult>();
            }
            if (!isCurrentProfile(userId) && !hasInteractUsersFull) {
                return new ArrayList<ScanResult>();
            }
            return mWifiStateMachine.syncGetScanResultsList();
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
    
public intgetSupportedFeatures()
see {@link android.net.wifi.WifiManager#getSupportedFeatures}

        enforceAccessPermission();
        if (mWifiStateMachineChannel != null) {
            return mWifiStateMachine.syncGetSupportedFeatures(mWifiStateMachineChannel);
        } else {
            Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
            return 0;
        }
    
public intgetVerboseLoggingLevel()

        enforceAccessPermission();
        return mWifiStateMachine.getVerboseLoggingLevel();
    
public WifiConfigurationgetWifiApConfiguration()
see {@link WifiManager#getWifiApConfiguration()}

return
soft access point configuration

        enforceAccessPermission();
        return mWifiStateMachine.syncGetWifiApConfiguration();
    
public intgetWifiApEnabledState()
see {@link WifiManager#getWifiApState()}

return
One of {@link WifiManager#WIFI_AP_STATE_DISABLED}, {@link WifiManager#WIFI_AP_STATE_DISABLING}, {@link WifiManager#WIFI_AP_STATE_ENABLED}, {@link WifiManager#WIFI_AP_STATE_ENABLING}, {@link WifiManager#WIFI_AP_STATE_FAILED}

        enforceAccessPermission();
        return mWifiStateMachine.syncGetWifiApState();
    
public intgetWifiEnabledState()
see {@link WifiManager#getWifiState()}

return
One of {@link WifiManager#WIFI_STATE_DISABLED}, {@link WifiManager#WIFI_STATE_DISABLING}, {@link WifiManager#WIFI_STATE_ENABLED}, {@link WifiManager#WIFI_STATE_ENABLING}, {@link WifiManager#WIFI_STATE_UNKNOWN}

        enforceAccessPermission();
        return mWifiStateMachine.syncGetWifiState();
    
public WifiMonitorgetWifiMonitor()

        return mWifiStateMachine.getWifiMonitor();
    
public android.os.MessengergetWifiServiceMessenger()
Get a reference to handler. This is used by a client to establish an AsyncChannel communication with WifiService

        enforceAccessPermission();
        enforceChangePermission();
        return new Messenger(mClientHandler);
    
public java.lang.StringgetWpsNfcConfigurationToken(int netId)

        enforceConnectivityInternalPermission();
        return mWifiStateMachine.syncGetWpsNfcConfigurationToken(netId);
    
public voidinitializeMulticastFiltering()

        enforceMulticastChangePermission();

        synchronized (mMulticasters) {
            // if anybody had requested filters be off, leave off
            if (mMulticasters.size() != 0) {
                return;
            } else {
                mWifiStateMachine.startFilteringMulticastV4Packets();
            }
        }
    
public booleanisBatchedScanSupported()


       
        return mBatchedScanSupported;
    
private booleanisCurrentProfile(int userId)
Returns true if the calling user is the current one or a profile of the current user..

        int currentUser = ActivityManager.getCurrentUser();
        if (userId == currentUser) {
            return true;
        }
        List<UserInfo> profiles = UserManager.get(mContext).getProfiles(currentUser);
        for (UserInfo user : profiles) {
            if (userId == user.id) {
                return true;
            }
        }
        return false;
    
public booleanisDualBandSupported()

        //TODO: Should move towards adding a driver API that checks at runtime
        return mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_wifi_dual_band_support);
    
public booleanisMulticastEnabled()

        enforceAccessPermission();

        synchronized (mMulticasters) {
            return (mMulticasters.size() > 0);
        }
    
private booleanisOwner(int uid)
Returns true if uid is an application running under the owner or a profile of the owner. Note: Should not be called if identity is cleared.

        long ident = Binder.clearCallingIdentity();
        int userId = UserHandle.getUserId(uid);
        try {
            int ownerUser = UserHandle.USER_OWNER;
            if (userId == ownerUser) {
                return true;
            }
            List<UserInfo> profiles = UserManager.get(mContext).getProfiles(ownerUser);
            for (UserInfo profile : profiles) {
                if (userId == profile.id) {
                    return true;
                }
            }
            return false;
        }
        finally {
            Binder.restoreCallingIdentity(ident);
        }
    
public booleanisScanAlwaysAvailable()

param
enable {@code true} to enable, {@code false} to disable.
return
{@code true} if the enable/disable operation was started or is already in the queue.

        enforceAccessPermission();
        return mSettingsStore.isScanAlwaysAvailable();
    
private voidnoteAcquireWifiLock(com.android.server.wifi.WifiServiceImpl$WifiLock wifiLock)

        switch(wifiLock.mMode) {
            case WifiManager.WIFI_MODE_FULL:
            case WifiManager.WIFI_MODE_FULL_HIGH_PERF:
            case WifiManager.WIFI_MODE_SCAN_ONLY:
                mBatteryStats.noteFullWifiLockAcquiredFromSource(wifiLock.mWorkSource);
                break;
        }
    
private voidnoteReleaseWifiLock(com.android.server.wifi.WifiServiceImpl$WifiLock wifiLock)

        switch(wifiLock.mMode) {
            case WifiManager.WIFI_MODE_FULL:
            case WifiManager.WIFI_MODE_FULL_HIGH_PERF:
            case WifiManager.WIFI_MODE_SCAN_ONLY:
                mBatteryStats.noteFullWifiLockReleasedFromSource(wifiLock.mWorkSource);
                break;
        }
    
public booleanpingSupplicant()
see {@link android.net.wifi.WifiManager#pingSupplicant()}

return
{@code true} if the operation succeeds, {@code false} otherwise

        enforceAccessPermission();
        if (mWifiStateMachineChannel != null) {
            return mWifiStateMachine.syncPingSupplicant(mWifiStateMachineChannel);
        } else {
            Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
            return false;
        }
    
public voidpollBatchedScan()

        enforceChangePermission();
        if (mBatchedScanSupported == false) return;
        mWifiStateMachine.requestBatchedScanPoll();
    
public voidreassociate()
see {@link android.net.wifi.WifiManager#reassociate()}

        enforceChangePermission();
        mWifiStateMachine.reassociateCommand();
    
public voidreconnect()
see {@link android.net.wifi.WifiManager#reconnect()}

        enforceChangePermission();
        mWifiStateMachine.reconnectCommand();
    
private voidregisterForBroadcasts()

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(Intent.ACTION_SCREEN_ON);
        intentFilter.addAction(Intent.ACTION_USER_PRESENT);
        intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
        intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
        intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        intentFilter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
        intentFilter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
        mContext.registerReceiver(mReceiver, intentFilter);
    
private voidregisterForScanModeChange()
Observes settings changes to scan always mode.


                
       
        ContentObserver contentObserver = new ContentObserver(null) {
            @Override
            public void onChange(boolean selfChange) {
                mSettingsStore.handleWifiScanAlwaysAvailableToggled();
                mWifiController.sendMessage(CMD_SCAN_ALWAYS_MODE_CHANGED);
            }
        };

        mContext.getContentResolver().registerContentObserver(
                Settings.Global.getUriFor(Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE),
                false, contentObserver);
    
public voidreleaseMulticastLock()

        enforceMulticastChangePermission();

        int uid = Binder.getCallingUid();
        synchronized (mMulticasters) {
            mMulticastDisabled++;
            int size = mMulticasters.size();
            for (int i = size - 1; i >= 0; i--) {
                Multicaster m = mMulticasters.get(i);
                if ((m != null) && (m.getUid() == uid)) {
                    removeMulticasterLocked(i, uid);
                }
            }
        }
    
public booleanreleaseWifiLock(android.os.IBinder lock)

        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
        synchronized (mLocks) {
            return releaseWifiLockLocked(lock);
        }
    
private booleanreleaseWifiLockLocked(android.os.IBinder lock)

        boolean hadLock;

        WifiLock wifiLock = mLocks.removeLock(lock);

        if (DBG) Slog.d(TAG, "releaseWifiLockLocked: " + wifiLock);

        hadLock = (wifiLock != null);

        long ident = Binder.clearCallingIdentity();
        try {
            if (hadLock) {
                noteReleaseWifiLock(wifiLock);
                switch(wifiLock.mMode) {
                    case WifiManager.WIFI_MODE_FULL:
                        ++mFullLocksReleased;
                        break;
                    case WifiManager.WIFI_MODE_FULL_HIGH_PERF:
                        ++mFullHighPerfLocksReleased;
                        break;
                    case WifiManager.WIFI_MODE_SCAN_ONLY:
                        ++mScanLocksReleased;
                        break;
                }
                mWifiController.sendMessage(CMD_LOCKS_CHANGED);
            }
        } catch (RemoteException e) {
        } finally {
            Binder.restoreCallingIdentity(ident);
        }

        return hadLock;
    
private voidremoveMulticasterLocked(int i, int uid)

        Multicaster removed = mMulticasters.remove(i);

        if (removed != null) {
            removed.unlinkDeathRecipient();
        }
        if (mMulticasters.size() == 0) {
            mWifiStateMachine.startFilteringMulticastV4Packets();
        }

        final long ident = Binder.clearCallingIdentity();
        try {
            mBatteryStats.noteWifiMulticastDisabled(uid);
        } catch (RemoteException e) {
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
    
public booleanremoveNetwork(int netId)
See {@link android.net.wifi.WifiManager#removeNetwork(int)}

param
netId the integer that identifies the network configuration to the supplicant
return
{@code true} if the operation succeeded

        enforceChangePermission();

        if (!isOwner(Binder.getCallingUid())) {
            Slog.e(TAG, "Remove is not authorized for user");
            return false;
        }

        if (mWifiStateMachineChannel != null) {
            return mWifiStateMachine.syncRemoveNetwork(mWifiStateMachineChannel, netId);
        } else {
            Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
            return false;
        }
    
public WifiActivityEnergyInforeportActivityInfo()
see {@link android.net.wifi.WifiAdapter#reportActivityInfo}

        enforceAccessPermission();
        WifiLinkLayerStats stats;
        WifiActivityEnergyInfo energyInfo = null;
        if (mWifiStateMachineChannel != null) {
            stats = mWifiStateMachine.syncGetLinkLayerStats(mWifiStateMachineChannel);
            if (stats != null) {
                // Convert the LinkLayerStats into EnergyActivity
                energyInfo = new WifiActivityEnergyInfo(
                        WifiActivityEnergyInfo.STACK_STATE_STATE_IDLE, stats.tx_time,
                        stats.rx_time, stats.on_time - stats.tx_time - stats.rx_time,
                        0 /* TBD */);
            }
            return energyInfo;
        } else {
            Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
            return null;
        }
    
public booleanrequestBatchedScan(BatchedScanSettings requested, android.os.IBinder binder, android.os.WorkSource workSource)
see {@link android.net.wifi.WifiManager#requestBatchedScan()}

        enforceChangePermission();
        if (workSource != null) {
            enforceWorkSourcePermission();
            // WifiManager currently doesn't use names, so need to clear names out of the
            // supplied WorkSource to allow future WorkSource combining.
            workSource.clearNames();
        }
        if (mBatchedScanSupported == false) return false;
        requested = new BatchedScanSettings(requested);
        if (requested.isInvalid()) return false;
        BatchedScanRequest r = new BatchedScanRequest(requested, binder, workSource);
        synchronized(mBatchedScanners) {
            mBatchedScanners.add(r);
            resolveBatchedScannersLocked();
        }
        return true;
    
private voidresolveBatchedScannersLocked()

        BatchedScanSettings setting = new BatchedScanSettings();
        WorkSource responsibleWorkSource = null;
        int responsibleUid = 0;
        double responsibleCsph = 0; // Channel Scans Per Hour

        if (mBatchedScanners.size() == 0) {
            mWifiStateMachine.setBatchedScanSettings(null, 0, 0, null);
            return;
        }
        for (BatchedScanRequest r : mBatchedScanners) {
            BatchedScanSettings s = r.settings;

            // evaluate responsibility
            int currentChannelCount;
            int currentScanInterval;
            double currentCsph;

            if (s.channelSet == null || s.channelSet.isEmpty()) {
                // all channels - 11 B and 9 A channels roughly.
                currentChannelCount = 9 + 11;
            } else {
                currentChannelCount = s.channelSet.size();
                // these are rough est - no real need to correct for reg-domain;
                if (s.channelSet.contains("A")) currentChannelCount += (9 - 1);
                if (s.channelSet.contains("B")) currentChannelCount += (11 - 1);

            }
            if (s.scanIntervalSec == BatchedScanSettings.UNSPECIFIED) {
                currentScanInterval = BatchedScanSettings.DEFAULT_INTERVAL_SEC;
            } else {
                currentScanInterval = s.scanIntervalSec;
            }
            currentCsph = 60 * 60 * currentChannelCount / currentScanInterval;

            if (currentCsph > responsibleCsph) {
                responsibleUid = r.uid;
                responsibleWorkSource = r.workSource;
                responsibleCsph = currentCsph;
            }

            if (s.maxScansPerBatch != BatchedScanSettings.UNSPECIFIED &&
                    s.maxScansPerBatch < setting.maxScansPerBatch) {
                setting.maxScansPerBatch = s.maxScansPerBatch;
            }
            if (s.maxApPerScan != BatchedScanSettings.UNSPECIFIED &&
                    (setting.maxApPerScan == BatchedScanSettings.UNSPECIFIED ||
                    s.maxApPerScan > setting.maxApPerScan)) {
                setting.maxApPerScan = s.maxApPerScan;
            }
            if (s.scanIntervalSec != BatchedScanSettings.UNSPECIFIED &&
                    s.scanIntervalSec < setting.scanIntervalSec) {
                setting.scanIntervalSec = s.scanIntervalSec;
            }
            if (s.maxApForDistance != BatchedScanSettings.UNSPECIFIED &&
                    (setting.maxApForDistance == BatchedScanSettings.UNSPECIFIED ||
                    s.maxApForDistance > setting.maxApForDistance)) {
                setting.maxApForDistance = s.maxApForDistance;
            }
            if (s.channelSet != null && s.channelSet.size() != 0) {
                if (setting.channelSet == null || setting.channelSet.size() != 0) {
                    if (setting.channelSet == null) setting.channelSet = new ArrayList<String>();
                    for (String i : s.channelSet) {
                        if (setting.channelSet.contains(i) == false) setting.channelSet.add(i);
                    }
                } // else, ignore the constraint - we already use all channels
            } else {
                if (setting.channelSet == null || setting.channelSet.size() != 0) {
                    setting.channelSet = new ArrayList<String>();
                }
            }
        }

        setting.constrain();
        mWifiStateMachine.setBatchedScanSettings(setting, responsibleUid, (int)responsibleCsph,
                responsibleWorkSource);
    
public booleansaveConfiguration()
Tell the supplicant to persist the current list of configured networks.

return
{@code true} if the operation succeeded TODO: deprecate this

        boolean result = true;
        enforceChangePermission();
        if (mWifiStateMachineChannel != null) {
            return mWifiStateMachine.syncSaveConfig(mWifiStateMachineChannel);
        } else {
            Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
            return false;
        }
    
public voidsetAllowScansWithTraffic(int enabled)

        enforceAccessPermission();
        mWifiStateMachine.setAllowScansWithTraffic(enabled);
    
public voidsetCountryCode(java.lang.String countryCode, boolean persist)
Set the country code

param
countryCode ISO 3166 country code.
param
persist {@code true} if the setting should be remembered. The persist behavior exists so that wifi can fall back to the last persisted country code on a restart, when the locale information is not available from telephony.

        Slog.i(TAG, "WifiService trying to set country code to " + countryCode +
                " with persist set to " + persist);
        enforceConnectivityInternalPermission();
        final long token = Binder.clearCallingIdentity();
        try {
            mWifiStateMachine.setCountryCode(countryCode, persist);
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    
public voidsetFrequencyBand(int band, boolean persist)
Set the operational frequency band

param
band One of {@link WifiManager#WIFI_FREQUENCY_BAND_AUTO}, {@link WifiManager#WIFI_FREQUENCY_BAND_5GHZ}, {@link WifiManager#WIFI_FREQUENCY_BAND_2GHZ},
param
persist {@code true} if the setting should be remembered.

        enforceChangePermission();
        if (!isDualBandSupported()) return;
        Slog.i(TAG, "WifiService trying to set frequency band to " + band +
                " with persist set to " + persist);
        final long token = Binder.clearCallingIdentity();
        try {
            mWifiStateMachine.setFrequencyBand(band, persist);
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    
public voidsetWifiApConfiguration(WifiConfiguration wifiConfig)
see {@link WifiManager#setWifiApConfiguration(WifiConfiguration)}

param
wifiConfig WifiConfiguration details for soft access point

        enforceChangePermission();
        if (wifiConfig == null)
            return;
        if (wifiConfig.isValid()) {
            mWifiStateMachine.setWifiApConfiguration(wifiConfig);
        } else {
            Slog.e(TAG, "Invalid WifiConfiguration");
        }
    
public voidsetWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled)
see {@link android.net.wifi.WifiManager#setWifiApEnabled(WifiConfiguration, boolean)}

param
wifiConfig SSID, security and channel details as part of WifiConfiguration
param
enabled true to enable and false to disable

        enforceChangePermission();
        ConnectivityManager.enforceTetherChangePermission(mContext);
        UserManager um = UserManager.get(mContext);
        if (um.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING)) {
            throw new SecurityException("DISALLOW_CONFIG_TETHERING is enabled for this user.");
        }
        // null wifiConfig is a meaningful input for CMD_SET_AP
        if (wifiConfig == null || wifiConfig.isValid()) {
            mWifiController.obtainMessage(CMD_SET_AP, enabled ? 1 : 0, 0, wifiConfig).sendToTarget();
        } else {
            Slog.e(TAG, "Invalid WifiConfiguration");
        }
    
public synchronized booleansetWifiEnabled(boolean enable)
see {@link android.net.wifi.WifiManager#setWifiEnabled(boolean)}

param
enable {@code true} to enable, {@code false} to disable.
return
{@code true} if the enable/disable operation was started or is already in the queue.

        enforceChangePermission();
        Slog.d(TAG, "setWifiEnabled: " + enable + " pid=" + Binder.getCallingPid()
                    + ", uid=" + Binder.getCallingUid());
        if (DBG) {
            Slog.e(TAG, "Invoking mWifiStateMachine.setWifiEnabled\n");
        }

        /*
        * Caller might not have WRITE_SECURE_SETTINGS,
        * only CHANGE_WIFI_STATE is enforced
        */

        long ident = Binder.clearCallingIdentity();
        try {
            if (! mSettingsStore.handleWifiToggled(enable)) {
                // Nothing to do if wifi cannot be toggled
                return true;
            }
        } finally {
            Binder.restoreCallingIdentity(ident);
        }

        mWifiController.sendMessage(CMD_WIFI_TOGGLED);
        return true;
    
public voidstartLocationRestrictedScan(android.os.WorkSource workSource)

        enforceChangePermission();
        enforceLocationHardwarePermission();
        List<WifiChannel> channels = getChannelList();
        if (channels == null) {
            Slog.e(TAG, "startLocationRestrictedScan cant get channels");
            return;
        }
        ScanSettings settings = new ScanSettings();
        for (WifiChannel channel : channels) {
            if (!channel.isDFS) {
                settings.channelSet.add(channel);
            }
        }
        if (workSource == null) {
            // Make sure we always have a workSource indicating the origin of the scan
            // hence if there is none, pick an internal WifiStateMachine one
            workSource = new WorkSource(WifiStateMachine.DFS_RESTRICTED_SCAN_REQUEST);
        }
        startScan(settings, workSource);
    
public voidstartScan(ScanSettings settings, android.os.WorkSource workSource)
see {@link android.net.wifi.WifiManager#startScan} and {@link android.net.wifi.WifiManager#startCustomizedScan}

param
settings If null, use default parameter, i.e. full scan.
param
workSource If null, all blame is given to the calling uid.

        enforceChangePermission();
        if (settings != null) {
            settings = new ScanSettings(settings);
            if (!settings.isValid()) {
                Slog.e(TAG, "invalid scan setting");
                return;
            }
        }
        if (workSource != null) {
            enforceWorkSourcePermission();
            // WifiManager currently doesn't use names, so need to clear names out of the
            // supplied WorkSource to allow future WorkSource combining.
            workSource.clearNames();
        }
        mWifiStateMachine.startScan(Binder.getCallingUid(), scanRequestCounter++,
                settings, workSource);
    
public voidstartWifi()
see {@link android.net.wifi.WifiManager#startWifi}

        enforceConnectivityInternalPermission();
        /* TODO: may be add permissions for access only to connectivity service
         * TODO: if a start issued, keep wifi alive until a stop issued irrespective
         * of WifiLock & device idle status unless wifi enabled status is toggled
         */

        mWifiStateMachine.setDriverStart(true);
        mWifiStateMachine.reconnectCommand();
    
public voidstopBatchedScan(BatchedScanSettings settings)

        enforceChangePermission();
        if (mBatchedScanSupported == false) return;
        stopBatchedScan(settings, getCallingUid(), getCallingPid());
    
private voidstopBatchedScan(BatchedScanSettings settings, int uid, int pid)

        ArrayList<BatchedScanRequest> found = new ArrayList<BatchedScanRequest>();
        synchronized(mBatchedScanners) {
            for (BatchedScanRequest r : mBatchedScanners) {
                if (r.isSameApp(uid, pid) && (settings == null || settings.equals(r.settings))) {
                    found.add(r);
                    if (settings != null) break;
                }
            }
            for (BatchedScanRequest r : found) {
                mBatchedScanners.remove(r);
            }
            if (found.size() != 0) {
                resolveBatchedScannersLocked();
            }
        }
    
public voidstopWifi()
see {@link android.net.wifi.WifiManager#stopWifi}

        enforceConnectivityInternalPermission();
        /*
         * TODO: if a stop is issued, wifi is brought up only by startWifi
         * unless wifi enabled status is toggled
         */
        mWifiStateMachine.setDriverStart(false);
    
public voidupdateWifiLockWorkSource(android.os.IBinder lock, android.os.WorkSource ws)

        int uid = Binder.getCallingUid();
        int pid = Binder.getCallingPid();
        if (ws != null && ws.size() == 0) {
            ws = null;
        }
        if (ws != null) {
            enforceWakeSourcePermission(uid, pid);
        }
        long ident = Binder.clearCallingIdentity();
        try {
            synchronized (mLocks) {
                int index = mLocks.findLockByBinder(lock);
                if (index < 0) {
                    throw new IllegalArgumentException("Wifi lock not active");
                }
                WifiLock wl = mLocks.mList.get(index);
                noteReleaseWifiLock(wl);
                wl.mWorkSource = ws != null ? new WorkSource(ws) : new WorkSource(uid);
                noteAcquireWifiLock(wl);
            }
        } catch (RemoteException e) {
        } finally {
            Binder.restoreCallingIdentity(ident);
        }