summaryrefslogtreecommitdiffstats
path: root/service/java/com/android/server/wifi/WifiServiceImpl.java
diff options
context:
space:
mode:
Diffstat (limited to 'service/java/com/android/server/wifi/WifiServiceImpl.java')
-rw-r--r--service/java/com/android/server/wifi/WifiServiceImpl.java1591
1 files changed, 0 insertions, 1591 deletions
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
deleted file mode 100644
index 897e55eff..000000000
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ /dev/null
@@ -1,1591 +0,0 @@
-/*
- * 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 com.android.server.wifi;
-
-import android.app.ActivityManager;
-import android.app.AppOpsManager;
-import android.bluetooth.BluetoothAdapter;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.database.ContentObserver;
-import android.net.DhcpInfo;
-import android.net.DhcpResults;
-import android.net.LinkAddress;
-import android.net.NetworkUtils;
-import android.net.RouteInfo;
-import android.net.wifi.IWifiManager;
-import android.net.wifi.ScanResult;
-import android.net.wifi.BatchedScanResult;
-import android.net.wifi.BatchedScanSettings;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiConfiguration.ProxySettings;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.Messenger;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.os.WorkSource;
-import android.os.AsyncTask;
-import android.provider.Settings;
-import android.util.Slog;
-
-import java.io.FileNotFoundException;
-import java.io.BufferedReader;
-import java.io.FileDescriptor;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.PrintWriter;
-
-import java.lang.Override;
-import java.net.InetAddress;
-import java.net.Inet4Address;
-import java.util.ArrayList;
-import java.util.List;
-
-import com.android.internal.R;
-import com.android.internal.app.IBatteryStats;
-import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.util.AsyncChannel;
-import com.android.server.SystemService;
-import com.android.server.am.BatteryStatsService;
-import static com.android.server.wifi.WifiController.CMD_AIRPLANE_TOGGLED;
-import static com.android.server.wifi.WifiController.CMD_BATTERY_CHANGED;
-import static com.android.server.wifi.WifiController.CMD_EMERGENCY_MODE_CHANGED;
-import static com.android.server.wifi.WifiController.CMD_LOCKS_CHANGED;
-import static com.android.server.wifi.WifiController.CMD_SCAN_ALWAYS_MODE_CHANGED;
-import static com.android.server.wifi.WifiController.CMD_SCREEN_OFF;
-import static com.android.server.wifi.WifiController.CMD_SCREEN_ON;
-import static com.android.server.wifi.WifiController.CMD_SET_AP;
-import static com.android.server.wifi.WifiController.CMD_USER_PRESENT;
-import static com.android.server.wifi.WifiController.CMD_WIFI_TOGGLED;
-/**
- * WifiService handles remote WiFi operation requests by implementing
- * the IWifiManager interface.
- *
- * @hide
- */
-public final class WifiServiceImpl extends IWifiManager.Stub {
- private static final String TAG = "WifiService";
- private static final boolean DBG = false;
-
- final WifiStateMachine mWifiStateMachine;
-
- private final Context mContext;
-
- final LockList mLocks = new LockList();
- // some wifi lock statistics
- private int mFullHighPerfLocksAcquired;
- private int mFullHighPerfLocksReleased;
- private int mFullLocksAcquired;
- private int mFullLocksReleased;
- private int mScanLocksAcquired;
- private int mScanLocksReleased;
-
- private final List<Multicaster> mMulticasters =
- new ArrayList<Multicaster>();
- private int mMulticastEnabled;
- private int mMulticastDisabled;
-
- private final IBatteryStats mBatteryStats;
- private final AppOpsManager mAppOps;
-
- private String mInterfaceName;
-
- /* Tracks the open wi-fi network notification */
- private WifiNotificationController mNotificationController;
- /* Polls traffic stats and notifies clients */
- private WifiTrafficPoller mTrafficPoller;
- /* Tracks the persisted states for wi-fi & airplane mode */
- final WifiSettingsStore mSettingsStore;
-
- final boolean mBatchedScanSupported;
-
- /**
- * Asynchronous channel to WifiStateMachine
- */
- private AsyncChannel mWifiStateMachineChannel;
-
- /**
- * Handles client connections
- */
- private class ClientHandler extends Handler {
-
- ClientHandler(android.os.Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: {
- if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
- if (DBG) Slog.d(TAG, "New client listening to asynchronous messages");
- // We track the clients by the Messenger
- // since it is expected to be always available
- mTrafficPoller.addClient(msg.replyTo);
- } else {
- Slog.e(TAG, "Client connection failure, error=" + msg.arg1);
- }
- break;
- }
- case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
- if (msg.arg1 == AsyncChannel.STATUS_SEND_UNSUCCESSFUL) {
- if (DBG) Slog.d(TAG, "Send failed, client connection lost");
- } else {
- if (DBG) Slog.d(TAG, "Client connection lost with reason: " + msg.arg1);
- }
- mTrafficPoller.removeClient(msg.replyTo);
- break;
- }
- case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: {
- AsyncChannel ac = new AsyncChannel();
- ac.connect(mContext, this, msg.replyTo);
- break;
- }
- /* Client commands are forwarded to state machine */
- case WifiManager.CONNECT_NETWORK:
- case WifiManager.SAVE_NETWORK: {
- WifiConfiguration config = (WifiConfiguration) msg.obj;
- int networkId = msg.arg1;
- if (config != null && config.isValid()) {
- // This is restricted because there is no UI for the user to
- // monitor/control PAC.
- if (config.proxySettings != ProxySettings.PAC) {
- if (DBG) Slog.d(TAG, "Connect with config" + config);
- mWifiStateMachine.sendMessage(Message.obtain(msg));
- } else {
- Slog.e(TAG, "ClientHandler.handleMessage cannot process msg with PAC");
- if (msg.what == WifiManager.CONNECT_NETWORK) {
- replyFailed(msg, WifiManager.CONNECT_NETWORK_FAILED);
- } else {
- replyFailed(msg, WifiManager.SAVE_NETWORK_FAILED);
- }
- }
- } else if (config == null
- && networkId != WifiConfiguration.INVALID_NETWORK_ID) {
- if (DBG) Slog.d(TAG, "Connect with networkId" + networkId);
- mWifiStateMachine.sendMessage(Message.obtain(msg));
- } else {
- Slog.e(TAG, "ClientHandler.handleMessage ignoring invalid msg=" + msg);
- if (msg.what == WifiManager.CONNECT_NETWORK) {
- replyFailed(msg, WifiManager.CONNECT_NETWORK_FAILED);
- } else {
- replyFailed(msg, WifiManager.SAVE_NETWORK_FAILED);
- }
- }
- break;
- }
- case WifiManager.FORGET_NETWORK:
- case WifiManager.START_WPS:
- case WifiManager.CANCEL_WPS:
- case WifiManager.DISABLE_NETWORK:
- case WifiManager.RSSI_PKTCNT_FETCH: {
- mWifiStateMachine.sendMessage(Message.obtain(msg));
- break;
- }
- default: {
- Slog.d(TAG, "ClientHandler.handleMessage ignoring msg=" + msg);
- break;
- }
- }
- }
-
- private void replyFailed(Message msg, int what) {
- Message reply = msg.obtain();
- reply.what = what;
- reply.arg1 = WifiManager.INVALID_ARGS;
- try {
- msg.replyTo.send(reply);
- } catch (RemoteException e) {
- // There's not much we can do if reply can't be sent!
- }
- }
- }
- private ClientHandler mClientHandler;
-
- /**
- * Handles interaction with WifiStateMachine
- */
- private class WifiStateMachineHandler extends Handler {
- private AsyncChannel mWsmChannel;
-
- WifiStateMachineHandler(android.os.Looper looper) {
- super(looper);
- mWsmChannel = new AsyncChannel();
- mWsmChannel.connect(mContext, this, mWifiStateMachine.getHandler());
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: {
- if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
- mWifiStateMachineChannel = mWsmChannel;
- } else {
- Slog.e(TAG, "WifiStateMachine connection failure, error=" + msg.arg1);
- mWifiStateMachineChannel = null;
- }
- break;
- }
- case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
- Slog.e(TAG, "WifiStateMachine channel lost, msg.arg1 =" + msg.arg1);
- mWifiStateMachineChannel = null;
- //Re-establish connection to state machine
- mWsmChannel.connect(mContext, this, mWifiStateMachine.getHandler());
- break;
- }
- default: {
- Slog.d(TAG, "WifiStateMachineHandler.handleMessage ignoring msg=" + msg);
- break;
- }
- }
- }
- }
-
- WifiStateMachineHandler mWifiStateMachineHandler;
-
- private WifiWatchdogStateMachine mWifiWatchdogStateMachine;
-
- private WifiController mWifiController;
-
- public WifiServiceImpl(Context context) {
- mContext = context;
-
- mInterfaceName = SystemProperties.get("wifi.interface", "wlan0");
-
- mWifiStateMachine = new WifiStateMachine(mContext, mInterfaceName);
- mWifiStateMachine.enableRssiPolling(true);
- mBatteryStats = BatteryStatsService.getService();
- mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
-
- mNotificationController = new WifiNotificationController(mContext, mWifiStateMachine);
- mTrafficPoller = new WifiTrafficPoller(mContext, mInterfaceName);
- 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());
- mWifiController.start();
-
- mBatchedScanSupported = mContext.getResources().getBoolean(
- R.bool.config_wifi_batched_scan_supported);
-
- 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();
- }
-
-
- /**
- * Check if Wi-Fi needs to be enabled and start
- * if needed
- *
- * This function is used only at boot time
- */
- public void checkAndStartWifi() {
- /* Check if wi-fi needs to be enabled */
- boolean wifiEnabled = mSettingsStore.isWifiToggleEnabled();
- Slog.i(TAG, "WifiService starting up with Wi-Fi " +
- (wifiEnabled ? "enabled" : "disabled"));
-
- // If we are already disabled (could be due to airplane mode), avoid changing persist
- // state here
- if (wifiEnabled) setWifiEnabled(wifiEnabled);
-
- mWifiWatchdogStateMachine = WifiWatchdogStateMachine.
- makeWifiWatchdogStateMachine(mContext);
-
- }
-
- /**
- * see {@link android.net.wifi.WifiManager#pingSupplicant()}
- * @return {@code true} if the operation succeeds, {@code false} otherwise
- */
- public boolean pingSupplicant() {
- enforceAccessPermission();
- if (mWifiStateMachineChannel != null) {
- return mWifiStateMachine.syncPingSupplicant(mWifiStateMachineChannel);
- } else {
- Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
- return false;
- }
- }
-
- /**
- * see {@link android.net.wifi.WifiManager#startScan()}
- *
- * <p>If workSource is null, all blame is given to the calling uid.
- */
- public void startScan(WorkSource workSource) {
- 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();
- }
- mWifiStateMachine.startScan(Binder.getCallingUid(), workSource);
- }
-
- private class BatchedScanRequest extends DeathRecipient {
- final BatchedScanSettings settings;
- final int uid;
- final int pid;
- final WorkSource workSource;
-
- BatchedScanRequest(BatchedScanSettings settings, IBinder binder, WorkSource ws) {
- super(0, null, binder, null);
- this.settings = settings;
- this.uid = getCallingUid();
- this.pid = getCallingPid();
- workSource = ws;
- }
- public void binderDied() {
- stopBatchedScan(settings, uid, pid);
- }
- public String toString() {
- return "BatchedScanRequest{settings=" + settings + ", binder=" + mBinder + "}";
- }
-
- public boolean isSameApp(int uid, int pid) {
- return (this.uid == uid && this.pid == pid);
- }
- }
-
- private final List<BatchedScanRequest> mBatchedScanners = new ArrayList<BatchedScanRequest>();
-
- public boolean isBatchedScanSupported() {
- return mBatchedScanSupported;
- }
-
- public void pollBatchedScan() {
- enforceChangePermission();
- if (mBatchedScanSupported == false) return;
- mWifiStateMachine.requestBatchedScanPoll();
- }
-
- /**
- * see {@link android.net.wifi.WifiManager#requestBatchedScan()}
- */
- public boolean requestBatchedScan(BatchedScanSettings requested, IBinder binder,
- WorkSource workSource) {
- 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;
- }
-
- public List<BatchedScanResult> getBatchedScanResults(String callingPackage) {
- enforceAccessPermission();
- if (mBatchedScanSupported == false) return new ArrayList<BatchedScanResult>();
- int userId = UserHandle.getCallingUserId();
- int uid = Binder.getCallingUid();
- long ident = Binder.clearCallingIdentity();
- try {
- if (mAppOps.noteOp(AppOpsManager.OP_WIFI_SCAN, uid, callingPackage)
- != AppOpsManager.MODE_ALLOWED) {
- return new ArrayList<BatchedScanResult>();
- }
- int currentUser = ActivityManager.getCurrentUser();
- if (userId != currentUser) {
- return new ArrayList<BatchedScanResult>();
- } else {
- return mWifiStateMachine.syncGetBatchedScanResultsList();
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
-
- public void stopBatchedScan(BatchedScanSettings settings) {
- enforceChangePermission();
- if (mBatchedScanSupported == false) return;
- stopBatchedScan(settings, getCallingUid(), getCallingPid());
- }
-
- private void stopBatchedScan(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();
- }
- }
- }
-
- private void resolveBatchedScannersLocked() {
- 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);
- }
-
- private void enforceAccessPermission() {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_WIFI_STATE,
- "WifiService");
- }
-
- private void enforceChangePermission() {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CHANGE_WIFI_STATE,
- "WifiService");
-
- }
-
- private void enforceWorkSourcePermission() {
- mContext.enforceCallingPermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
- "WifiService");
-
- }
-
- private void enforceMulticastChangePermission() {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.CHANGE_WIFI_MULTICAST_STATE,
- "WifiService");
- }
-
- private void enforceConnectivityInternalPermission() {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.CONNECTIVITY_INTERNAL,
- "ConnectivityService");
- }
-
- /**
- * 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.
- */
- public synchronized boolean setWifiEnabled(boolean enable) {
- 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;
- }
-
- /**
- * 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}
- */
- public int getWifiEnabledState() {
- enforceAccessPermission();
- return mWifiStateMachine.syncGetWifiState();
- }
-
- /**
- * 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
- */
- public void setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) {
- enforceChangePermission();
- // 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");
- }
- }
-
- /**
- * 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}
- */
- public int getWifiApEnabledState() {
- enforceAccessPermission();
- return mWifiStateMachine.syncGetWifiApState();
- }
-
- /**
- * see {@link WifiManager#getWifiApConfiguration()}
- * @return soft access point configuration
- */
- public WifiConfiguration getWifiApConfiguration() {
- enforceAccessPermission();
- return mWifiStateMachine.syncGetWifiApConfiguration();
- }
-
- /**
- * see {@link WifiManager#setWifiApConfiguration(WifiConfiguration)}
- * @param wifiConfig WifiConfiguration details for soft access point
- */
- public void setWifiApConfiguration(WifiConfiguration wifiConfig) {
- enforceChangePermission();
- if (wifiConfig == null)
- return;
- if (wifiConfig.isValid()) {
- mWifiStateMachine.setWifiApConfiguration(wifiConfig);
- } else {
- Slog.e(TAG, "Invalid WifiConfiguration");
- }
- }
-
- /**
- * @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.
- */
- public boolean isScanAlwaysAvailable() {
- enforceAccessPermission();
- return mSettingsStore.isScanAlwaysAvailable();
- }
-
- /**
- * see {@link android.net.wifi.WifiManager#disconnect()}
- */
- public void disconnect() {
- enforceChangePermission();
- mWifiStateMachine.disconnectCommand();
- }
-
- /**
- * see {@link android.net.wifi.WifiManager#reconnect()}
- */
- public void reconnect() {
- enforceChangePermission();
- mWifiStateMachine.reconnectCommand();
- }
-
- /**
- * see {@link android.net.wifi.WifiManager#reassociate()}
- */
- public void reassociate() {
- enforceChangePermission();
- mWifiStateMachine.reassociateCommand();
- }
-
- /**
- * see {@link android.net.wifi.WifiManager#getConfiguredNetworks()}
- * @return the list of configured networks
- */
- public List<WifiConfiguration> getConfiguredNetworks() {
- enforceAccessPermission();
- if (mWifiStateMachineChannel != null) {
- return mWifiStateMachine.syncGetConfiguredNetworks(mWifiStateMachineChannel);
- } else {
- Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
- return null;
- }
- }
-
- /**
- * 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
- */
- public int addOrUpdateNetwork(WifiConfiguration config) {
- enforceChangePermission();
- if (config.proxySettings == ProxySettings.PAC) {
- enforceConnectivityInternalPermission();
- }
- if (config.isValid()) {
- 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;
- }
- }
-
- /**
- * 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
- */
- public boolean removeNetwork(int netId) {
- enforceChangePermission();
- if (mWifiStateMachineChannel != null) {
- return mWifiStateMachine.syncRemoveNetwork(mWifiStateMachineChannel, netId);
- } else {
- Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
- return false;
- }
- }
-
- /**
- * 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
- */
- public boolean enableNetwork(int netId, boolean disableOthers) {
- enforceChangePermission();
- if (mWifiStateMachineChannel != null) {
- return mWifiStateMachine.syncEnableNetwork(mWifiStateMachineChannel, netId,
- disableOthers);
- } else {
- Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
- return false;
- }
- }
-
- /**
- * 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
- */
- public boolean disableNetwork(int netId) {
- enforceChangePermission();
- if (mWifiStateMachineChannel != null) {
- return mWifiStateMachine.syncDisableNetwork(mWifiStateMachineChannel, netId);
- } else {
- Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
- return false;
- }
- }
-
- /**
- * See {@link android.net.wifi.WifiManager#getConnectionInfo()}
- * @return the Wi-Fi information, contained in {@link WifiInfo}.
- */
- public WifiInfo getConnectionInfo() {
- enforceAccessPermission();
- /*
- * Make sure we have the latest information, by sending
- * a status request to the supplicant.
- */
- return mWifiStateMachine.syncRequestConnectionInfo();
- }
-
- /**
- * 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
- */
- public List<ScanResult> getScanResults(String callingPackage) {
- enforceAccessPermission();
- int userId = UserHandle.getCallingUserId();
- int uid = Binder.getCallingUid();
- long ident = Binder.clearCallingIdentity();
- try {
- if (mAppOps.noteOp(AppOpsManager.OP_WIFI_SCAN, uid, callingPackage)
- != AppOpsManager.MODE_ALLOWED) {
- return new ArrayList<ScanResult>();
- }
- int currentUser = ActivityManager.getCurrentUser();
- if (userId != currentUser) {
- return new ArrayList<ScanResult>();
- } else {
- return mWifiStateMachine.syncGetScanResultsList();
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- /**
- * Tell the supplicant to persist the current list of configured networks.
- * @return {@code true} if the operation succeeded
- *
- * TODO: deprecate this
- */
- public boolean saveConfiguration() {
- boolean result = true;
- enforceChangePermission();
- if (mWifiStateMachineChannel != null) {
- return mWifiStateMachine.syncSaveConfig(mWifiStateMachineChannel);
- } else {
- Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
- return false;
- }
- }
-
- /**
- * 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.
- */
- public void setCountryCode(String countryCode, boolean persist) {
- Slog.i(TAG, "WifiService trying to set country code to " + countryCode +
- " with persist set to " + persist);
- enforceChangePermission();
- final long token = Binder.clearCallingIdentity();
- try {
- mWifiStateMachine.setCountryCode(countryCode, persist);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- /**
- * 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.
- *
- */
- public void setFrequencyBand(int band, boolean persist) {
- 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);
- }
- }
-
-
- /**
- * Get the operational frequency band
- */
- public int getFrequencyBand() {
- enforceAccessPermission();
- return mWifiStateMachine.getFrequencyBand();
- }
-
- public boolean isDualBandSupported() {
- //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);
- }
-
- /**
- * Return the DHCP-assigned addresses from the last successful DHCP request,
- * if any.
- * @return the DHCP information
- * @deprecated
- */
- public DhcpInfo getDhcpInfo() {
- enforceAccessPermission();
- DhcpResults dhcpResults = mWifiStateMachine.syncGetDhcpResults();
- if (dhcpResults.linkProperties == null) return null;
-
- DhcpInfo info = new DhcpInfo();
- for (LinkAddress la : dhcpResults.linkProperties.getLinkAddresses()) {
- InetAddress addr = la.getAddress();
- if (addr instanceof Inet4Address) {
- info.ipAddress = NetworkUtils.inetAddressToInt((Inet4Address)addr);
- break;
- }
- }
- for (RouteInfo r : dhcpResults.linkProperties.getRoutes()) {
- if (r.isDefaultRoute()) {
- InetAddress gateway = r.getGateway();
- if (gateway instanceof Inet4Address) {
- info.gateway = NetworkUtils.inetAddressToInt((Inet4Address)gateway);
- }
- } else if (r.hasGateway() == false) {
- LinkAddress dest = r.getDestination();
- if (dest.getAddress() instanceof Inet4Address) {
- info.netmask = NetworkUtils.prefixLengthToNetmaskInt(
- dest.getNetworkPrefixLength());
- }
- }
- }
- int dnsFound = 0;
- for (InetAddress dns : dhcpResults.linkProperties.getDnses()) {
- 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;
- }
-
- /**
- * see {@link android.net.wifi.WifiManager#startWifi}
- *
- */
- public void 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();
- }
-
- /**
- * see {@link android.net.wifi.WifiManager#stopWifi}
- *
- */
- public void stopWifi() {
- enforceConnectivityInternalPermission();
- /*
- * TODO: if a stop is issued, wifi is brought up only by startWifi
- * unless wifi enabled status is toggled
- */
- mWifiStateMachine.setDriverStart(false);
- }
-
- /**
- * see {@link android.net.wifi.WifiManager#addToBlacklist}
- *
- */
- public void addToBlacklist(String bssid) {
- enforceChangePermission();
-
- mWifiStateMachine.addToBlacklist(bssid);
- }
-
- /**
- * see {@link android.net.wifi.WifiManager#clearBlacklist}
- *
- */
- public void clearBlacklist() {
- enforceChangePermission();
-
- mWifiStateMachine.clearBlacklist();
- }
-
- /**
- * enable TDLS for the local NIC to remote NIC
- * The APPs don't know the remote MAC address to identify NIC though,
- * so we need to do additional work to find it from remote IP address
- */
-
- class TdlsTaskParams {
- public String remoteIpAddress;
- public boolean enable;
- }
-
- class TdlsTask extends AsyncTask<TdlsTaskParams, Integer, Integer> {
- @Override
- protected Integer doInBackground(TdlsTaskParams... params) {
-
- // Retrieve parameters for the call
- TdlsTaskParams param = params[0];
- String remoteIpAddress = param.remoteIpAddress.trim();
- boolean enable = param.enable;
-
- // Get MAC address of Remote IP
- String macAddress = null;
-
- BufferedReader reader = null;
-
- try {
- reader = new BufferedReader(new FileReader("/proc/net/arp"));
-
- // Skip over the line bearing colum titles
- String line = reader.readLine();
-
- while ((line = reader.readLine()) != null) {
- String[] tokens = line.split("[ ]+");
- if (tokens.length < 6) {
- continue;
- }
-
- // ARP column format is
- // Address HWType HWAddress Flags Mask IFace
- String ip = tokens[0];
- String mac = tokens[3];
-
- if (remoteIpAddress.equals(ip)) {
- macAddress = mac;
- break;
- }
- }
-
- if (macAddress == null) {
- Slog.w(TAG, "Did not find remoteAddress {" + remoteIpAddress + "} in " +
- "/proc/net/arp");
- } else {
- enableTdlsWithMacAddress(macAddress, enable);
- }
-
- } catch (FileNotFoundException e) {
- Slog.e(TAG, "Could not open /proc/net/arp to lookup mac address");
- } catch (IOException e) {
- Slog.e(TAG, "Could not read /proc/net/arp to lookup mac address");
- } finally {
- try {
- if (reader != null) {
- reader.close();
- }
- }
- catch (IOException e) {
- // Do nothing
- }
- }
-
- return 0;
- }
- }
-
- public void enableTdls(String remoteAddress, boolean enable) {
- TdlsTaskParams params = new TdlsTaskParams();
- params.remoteIpAddress = remoteAddress;
- params.enable = enable;
- new TdlsTask().execute(params);
- }
-
-
- public void enableTdlsWithMacAddress(String remoteMacAddress, boolean enable) {
- mWifiStateMachine.enableTdls(remoteMacAddress, enable);
- }
-
- /**
- * Get a reference to handler. This is used by a client to establish
- * an AsyncChannel communication with WifiService
- */
- public Messenger getWifiServiceMessenger() {
- enforceAccessPermission();
- enforceChangePermission();
- return new Messenger(mClientHandler);
- }
-
- /** Get a reference to WifiStateMachine handler for AsyncChannel communication */
- public Messenger getWifiStateMachineMessenger() {
- enforceAccessPermission();
- enforceChangePermission();
- return mWifiStateMachine.getMessenger();
- }
-
- /**
- * Get the IP and proxy configuration file
- */
- public String getConfigFile() {
- enforceAccessPermission();
- return mWifiStateMachine.getConfigFile();
- }
-
- private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action.equals(Intent.ACTION_SCREEN_ON)) {
- mWifiController.sendMessage(CMD_SCREEN_ON);
- } else if (action.equals(Intent.ACTION_USER_PRESENT)) {
- mWifiController.sendMessage(CMD_USER_PRESENT);
- } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
- mWifiController.sendMessage(CMD_SCREEN_OFF);
- } else if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
- int pluggedType = intent.getIntExtra("plugged", 0);
- mWifiController.sendMessage(CMD_BATTERY_CHANGED, pluggedType, 0, null);
- } else if (action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) {
- int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE,
- BluetoothAdapter.STATE_DISCONNECTED);
- mWifiStateMachine.sendBluetoothAdapterStateChange(state);
- } else if (action.equals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED)) {
- boolean emergencyMode = intent.getBooleanExtra("phoneinECMState", false);
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, emergencyMode ? 1 : 0, 0);
- }
- }
- };
-
- /**
- * Observes settings changes to scan always mode.
- */
- private void registerForScanModeChange() {
- 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);
- }
-
- private void registerForBroadcasts() {
- 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);
- }
-
- @Override
- protected void dump(FileDescriptor fd, PrintWriter pw, 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();
- if (scanResults != null && scanResults.size() != 0) {
- pw.println(" BSSID Frequency RSSI Flags SSID");
- for (ScanResult r : scanResults) {
- pw.printf(" %17s %9d %5d %-16s %s%n",
- r.BSSID,
- r.frequency,
- r.level,
- r.capabilities,
- r.SSID == null ? "" : r.SSID);
- }
- }
- 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();
- }
-
- private class WifiLock extends DeathRecipient {
- WifiLock(int lockMode, String tag, IBinder binder, WorkSource ws) {
- super(lockMode, tag, binder, ws);
- }
-
- public void binderDied() {
- synchronized (mLocks) {
- releaseWifiLockLocked(mBinder);
- }
- }
-
- public String toString() {
- return "WifiLock{" + mTag + " type=" + mMode + " binder=" + mBinder + "}";
- }
- }
-
- class LockList {
- private List<WifiLock> mList;
-
- private LockList() {
- mList = new ArrayList<WifiLock>();
- }
-
- synchronized boolean hasLocks() {
- return !mList.isEmpty();
- }
-
- synchronized int getStrongestLockMode() {
- if (mList.isEmpty()) {
- return WifiManager.WIFI_MODE_FULL;
- }
-
- if (mFullHighPerfLocksAcquired > mFullHighPerfLocksReleased) {
- return WifiManager.WIFI_MODE_FULL_HIGH_PERF;
- }
-
- if (mFullLocksAcquired > mFullLocksReleased) {
- return WifiManager.WIFI_MODE_FULL;
- }
-
- return WifiManager.WIFI_MODE_SCAN_ONLY;
- }
-
- synchronized void updateWorkSource(WorkSource ws) {
- for (int i = 0; i < mLocks.mList.size(); i++) {
- ws.add(mLocks.mList.get(i).mWorkSource);
- }
- }
-
- private void addLock(WifiLock lock) {
- if (findLockByBinder(lock.mBinder) < 0) {
- mList.add(lock);
- }
- }
-
- private WifiLock removeLock(IBinder binder) {
- int index = findLockByBinder(binder);
- if (index >= 0) {
- WifiLock ret = mList.remove(index);
- ret.unlinkDeathRecipient();
- return ret;
- } else {
- return null;
- }
- }
-
- private int findLockByBinder(IBinder binder) {
- int size = mList.size();
- for (int i = size - 1; i >= 0; i--) {
- if (mList.get(i).mBinder == binder)
- return i;
- }
- return -1;
- }
-
- private void dump(PrintWriter pw) {
- for (WifiLock l : mList) {
- pw.print(" ");
- pw.println(l);
- }
- }
- }
-
- void enforceWakeSourcePermission(int uid, int pid) {
- if (uid == android.os.Process.myUid()) {
- return;
- }
- mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
- pid, uid, null);
- }
-
- public boolean acquireWifiLock(IBinder binder, int lockMode, String tag, 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 void noteAcquireWifiLock(WifiLock wifiLock) throws RemoteException {
- 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 void noteReleaseWifiLock(WifiLock wifiLock) throws RemoteException {
- 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;
- }
- }
-
- private boolean acquireWifiLockLocked(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 void updateWifiLockWorkSource(IBinder lock, 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);
- }
- }
-
- public boolean releaseWifiLock(IBinder lock) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
- synchronized (mLocks) {
- return releaseWifiLockLocked(lock);
- }
- }
-
- private boolean releaseWifiLockLocked(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 abstract class DeathRecipient
- implements IBinder.DeathRecipient {
- String mTag;
- int mMode;
- IBinder mBinder;
- WorkSource mWorkSource;
-
- DeathRecipient(int mode, String tag, IBinder binder, WorkSource ws) {
- super();
- mTag = tag;
- mMode = mode;
- mBinder = binder;
- mWorkSource = ws;
- try {
- mBinder.linkToDeath(this, 0);
- } catch (RemoteException e) {
- binderDied();
- }
- }
-
- void unlinkDeathRecipient() {
- mBinder.unlinkToDeath(this, 0);
- }
- }
-
- private class Multicaster extends DeathRecipient {
- Multicaster(String tag, IBinder binder) {
- super(Binder.getCallingUid(), tag, binder, null);
- }
-
- public void binderDied() {
- Slog.e(TAG, "Multicaster binderDied");
- synchronized (mMulticasters) {
- int i = mMulticasters.indexOf(this);
- if (i != -1) {
- removeMulticasterLocked(i, mMode);
- }
- }
- }
-
- public String toString() {
- return "Multicaster{" + mTag + " binder=" + mBinder + "}";
- }
-
- public int getUid() {
- return mMode;
- }
- }
-
- public void initializeMulticastFiltering() {
- enforceMulticastChangePermission();
-
- synchronized (mMulticasters) {
- // if anybody had requested filters be off, leave off
- if (mMulticasters.size() != 0) {
- return;
- } else {
- mWifiStateMachine.startFilteringMulticastV4Packets();
- }
- }
- }
-
- public void acquireMulticastLock(IBinder binder, 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 void releaseMulticastLock() {
- 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);
- }
- }
- }
- }
-
- private void removeMulticasterLocked(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 boolean isMulticastEnabled() {
- enforceAccessPermission();
-
- synchronized (mMulticasters) {
- return (mMulticasters.size() > 0);
- }
- }
-}