19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 2a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff * Copyright (C) 2010 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.server; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19330b1875747561e1f4dfdc062bf15d3c345806edIrfan Sheriffimport android.app.ActivityManager; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.AlarmManager; 210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.app.Notification; 220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.app.NotificationManager; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.PendingIntent; 24d56b4d1db34bd6928f599e7e9a7321c2a81cb995Adam Powellimport android.app.TaskStackBuilder; 257440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganeshimport android.bluetooth.BluetoothAdapter; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.BroadcastReceiver; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ContentResolver; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.IntentFilter; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager; 320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.database.ContentObserver; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.wifi.IWifiManager; 344aeca7c5908387bc7efb0785830aea1053264062Irfan Sheriffimport android.net.wifi.ScanResult; 354aeca7c5908387bc7efb0785830aea1053264062Irfan Sheriffimport android.net.wifi.SupplicantState; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.wifi.WifiInfo; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.wifi.WifiManager; 380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.net.wifi.WifiStateMachine; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.wifi.WifiConfiguration; 40654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levyimport android.net.wifi.WifiWatchdogStateMachine; 419ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriffimport android.net.wifi.WifiConfiguration.KeyMgmt; 42651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriffimport android.net.wifi.WpsInfo; 43e4c56c9655bf936454e2f3ee434aacb403876c7dIrfan Sheriffimport android.net.wifi.WpsResult; 445321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriffimport android.net.ConnectivityManager; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.DhcpInfo; 460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.net.NetworkInfo; 470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.net.NetworkInfo.State; 48227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriffimport android.net.NetworkInfo.DetailedState; 49227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriffimport android.net.TrafficStats; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder; 510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.Handler; 52227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriffimport android.os.Messenger; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.HandlerThread; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 555321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriffimport android.os.INetworkManagementService; 560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.os.Message; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 5847873e55268eb636b2f9ada0266a0b60f52ca365Amith Yamasaniimport android.os.ServiceManager; 59227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriffimport android.os.SystemProperties; 60330b1875747561e1f4dfdc062bf15d3c345806edIrfan Sheriffimport android.os.UserHandle; 617e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackbornimport android.os.WorkSource; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.provider.Settings; 630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriffimport android.text.TextUtils; 646ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pellyimport android.util.Log; 658a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog; 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 688cef06798ef1f67641f8b15165aca39abd6c46caIrfan Sheriffimport java.util.HashMap; 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 70084c665421502b13271e94bd0a342b0ddbbaa7caJaikumar Ganeshimport java.util.Set; 71658772f0e6bcf2b0a3e26778c2fc47accbdfeb2eIrfan Sheriffimport java.util.concurrent.atomic.AtomicInteger; 72a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriffimport java.util.concurrent.atomic.AtomicBoolean; 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor; 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.PrintWriter; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 76105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport com.android.internal.app.IBatteryStats; 77616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriffimport com.android.internal.telephony.TelephonyIntents; 784b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Savilleimport com.android.internal.util.AsyncChannel; 79105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport com.android.server.am.BatteryStatsService; 809ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriffimport com.android.internal.R; 81105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WifiService handles remote WiFi operation requests by implementing 84a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff * the IWifiManager interface. 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 88a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff//TODO: Clean up multiple locks and implement WifiService 89a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff// as a SM to track soft AP/client/adhoc bring up based 90a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff// on device idle state, airplane mode and boot. 91a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class WifiService extends IWifiManager.Stub { 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "WifiService"; 945fd2169eabd77e6bfafaf456e58051a3bafb2bcaDianne Hackborn private static final boolean DBG = false; 95a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff 960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff private final WifiStateMachine mWifiStateMachine; 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Context mContext; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private AlarmManager mAlarmManager; 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private PendingIntent mIdleIntent; 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int IDLE_REQUEST = 0; 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mScreenOff; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mDeviceIdle; 105616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriff private boolean mEmergencyCallbackMode = false; 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mPluggedType; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final LockList mLocks = new LockList(); 1095711fadfc48f0e77bc25a91ef36c76acb0d2f55aEric Shienbrood // some wifi lock statistics 1105876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff private int mFullHighPerfLocksAcquired; 1115876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff private int mFullHighPerfLocksReleased; 1125711fadfc48f0e77bc25a91ef36c76acb0d2f55aEric Shienbrood private int mFullLocksAcquired; 1135711fadfc48f0e77bc25a91ef36c76acb0d2f55aEric Shienbrood private int mFullLocksReleased; 1145711fadfc48f0e77bc25a91ef36c76acb0d2f55aEric Shienbrood private int mScanLocksAcquired; 1155711fadfc48f0e77bc25a91ef36c76acb0d2f55aEric Shienbrood private int mScanLocksReleased; 116105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 11758ff0217a617d5b03d18f0ef532f254f8ba6de2bRobert Greenwalt private final List<Multicaster> mMulticasters = 11858ff0217a617d5b03d18f0ef532f254f8ba6de2bRobert Greenwalt new ArrayList<Multicaster>(); 1195347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt private int mMulticastEnabled; 1205347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt private int mMulticastDisabled; 1215347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt 122105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private final IBatteryStats mBatteryStats; 123084c665421502b13271e94bd0a342b0ddbbaa7caJaikumar Ganesh 124227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff private boolean mEnableTrafficStatsPoll = false; 125227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff private int mTrafficStatsPollToken = 0; 126227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff private long mTxPkts; 127227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff private long mRxPkts; 128227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff /* Tracks last reported data activity */ 129227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff private int mDataActivity; 130227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff private String mInterfaceName; 131227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff 132227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff /** 133227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff * Interval in milliseconds between polling for traffic 134227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff * statistics 135227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff */ 136227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff private static final int POLL_TRAFFIC_STATS_INTERVAL_MSECS = 1000; 137227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1396f5a9a96523ecf97a9828a410dd1226df47ec4e6Christopher Tate * See {@link Settings.Global#WIFI_IDLE_MS}. This is the default value if a 1406f5a9a96523ecf97a9828a410dd1226df47ec4e6Christopher Tate * Settings.Global value is not present. This timeout value is chosen as 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the approximate point at which the battery drain caused by Wi-Fi 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * being enabled but not active exceeds the battery drain caused by 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * re-establishing a connection to the mobile data network. 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1454f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff private static final long DEFAULT_IDLE_MS = 15 * 60 * 1000; /* 15 minutes */ 1464f5f7c968339a83b6af98ac8893a1ac33c7aa7bcIrfan Sheriff 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String ACTION_DEVICE_IDLE = 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "com.android.server.WifiManager.action.DEVICE_IDLE"; 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 150658772f0e6bcf2b0a3e26778c2fc47accbdfeb2eIrfan Sheriff private static final int WIFI_DISABLED = 0; 151658772f0e6bcf2b0a3e26778c2fc47accbdfeb2eIrfan Sheriff private static final int WIFI_ENABLED = 1; 152658772f0e6bcf2b0a3e26778c2fc47accbdfeb2eIrfan Sheriff /* Wifi enabled while in airplane mode */ 153658772f0e6bcf2b0a3e26778c2fc47accbdfeb2eIrfan Sheriff private static final int WIFI_ENABLED_AIRPLANE_OVERRIDE = 2; 15431b92e28a577f2f36f30b8a95147155fec038e30Irfan Sheriff /* Wifi disabled due to airplane mode on */ 15531b92e28a577f2f36f30b8a95147155fec038e30Irfan Sheriff private static final int WIFI_DISABLED_AIRPLANE_ON = 3; 156658772f0e6bcf2b0a3e26778c2fc47accbdfeb2eIrfan Sheriff 1575401f0b87b9bdcd603c55871a37fff07ab3054d7Irfan Sheriff /* Persisted state that tracks the wifi & airplane interaction from settings */ 1585401f0b87b9bdcd603c55871a37fff07ab3054d7Irfan Sheriff private AtomicInteger mPersistWifiState = new AtomicInteger(WIFI_DISABLED); 1595401f0b87b9bdcd603c55871a37fff07ab3054d7Irfan Sheriff /* Tracks current airplane mode state */ 160658772f0e6bcf2b0a3e26778c2fc47accbdfeb2eIrfan Sheriff private AtomicBoolean mAirplaneModeOn = new AtomicBoolean(false); 1615401f0b87b9bdcd603c55871a37fff07ab3054d7Irfan Sheriff /* Tracks whether wifi is enabled from WifiStateMachine's perspective */ 1625401f0b87b9bdcd603c55871a37fff07ab3054d7Irfan Sheriff private boolean mWifiEnabled; 163658772f0e6bcf2b0a3e26778c2fc47accbdfeb2eIrfan Sheriff 1646ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly /* The work source (UID) that triggered the current WIFI scan, synchronized 1656ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly * on this */ 1666ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly private WorkSource mScanWorkSource; 1676ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly 168a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff private boolean mIsReceiverRegistered = false; 169a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff 1700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 1710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff NetworkInfo mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, "WIFI", ""); 1720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 1730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff // Variables relating to the 'available networks' notification 1740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff /** 1750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * The icon to show in the 'available networks' notification. This will also 1760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * be the ID of the Notification given to the NotificationManager. 1770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */ 1780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff private static final int ICON_NETWORKS_AVAILABLE = 1790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff com.android.internal.R.drawable.stat_notify_wifi_in_range; 1800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff /** 1810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * When a notification is shown, we wait this amount before possibly showing it again. 1820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */ 1830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff private final long NOTIFICATION_REPEAT_DELAY_MS; 1840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff /** 1850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Whether the user has set the setting to show the 'available networks' notification. 1860d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */ 1870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff private boolean mNotificationEnabled; 1880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff /** 1890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Observes the user setting to keep {@link #mNotificationEnabled} in sync. 1900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */ 1910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff private NotificationEnabledSettingObserver mNotificationEnabledSettingObserver; 1920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff /** 1930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * The {@link System#currentTimeMillis()} must be at least this value for us 1940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * to show the notification again. 1950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */ 1960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff private long mNotificationRepeatTime; 1970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff /** 1980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * The Notification object given to the NotificationManager. 1990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */ 2000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff private Notification mNotification; 2010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff /** 2020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Whether the notification is being shown, as set by us. That is, if the 2030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * user cancels the notification, we will not receive the callback so this 2040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * will still be true. We only guarantee if this is false, then the 2050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * notification is not showing. 2060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */ 2070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff private boolean mNotificationShown; 2080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff /** 2090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * The number of continuous scans that must occur before consider the 2100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * supplicant in a scanning state. This allows supplicant to associate with 2110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * remembered networks that are in the scan results. 2120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */ 2130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff private static final int NUM_SCANS_BEFORE_ACTUALLY_SCANNING = 3; 2140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff /** 2150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * The number of scans since the last network state change. When this 2160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * exceeds {@link #NUM_SCANS_BEFORE_ACTUALLY_SCANNING}, we consider the 2170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * supplicant to actually be scanning. When the network state changes to 2180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * something other than scanning, we reset this to 0. 2190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */ 2200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff private int mNumScansSinceNetworkStateChange; 2217440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh 22203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn /** 2234b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville * Asynchronous channel to WifiStateMachine 2244b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville */ 225227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff private AsyncChannel mWifiStateMachineChannel; 2264b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville 2274b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville /** 228227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff * Clients receiving asynchronous messages 2294b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville */ 230227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff private List<AsyncChannel> mClients = new ArrayList<AsyncChannel>(); 2314b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville 232227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff /** 233227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff * Handles client connections 234227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff */ 235227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff private class AsyncServiceHandler extends Handler { 236227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff 237227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff AsyncServiceHandler(android.os.Looper looper) { 2384b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville super(looper); 2394b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville } 2404b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville 2414b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville @Override 2424b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville public void handleMessage(Message msg) { 2434b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville switch (msg.what) { 2444b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: { 2454b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { 2466bfc88876ab575913299b477528225a4d7bf8232Irfan Sheriff if (DBG) Slog.d(TAG, "New client listening to asynchronous messages"); 247227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff mClients.add((AsyncChannel) msg.obj); 2484b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville } else { 249227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff Slog.e(TAG, "Client connection failure, error=" + msg.arg1); 250227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff } 251227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff break; 252227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff } 253c23971b3e4f92ac31996d4f9f32eef3cb4ef65fdIrfan Sheriff case AsyncChannel.CMD_CHANNEL_DISCONNECTED: { 254c23971b3e4f92ac31996d4f9f32eef3cb4ef65fdIrfan Sheriff if (msg.arg1 == AsyncChannel.STATUS_SEND_UNSUCCESSFUL) { 2556bfc88876ab575913299b477528225a4d7bf8232Irfan Sheriff if (DBG) Slog.d(TAG, "Send failed, client connection lost"); 256c23971b3e4f92ac31996d4f9f32eef3cb4ef65fdIrfan Sheriff } else { 2576bfc88876ab575913299b477528225a4d7bf8232Irfan Sheriff if (DBG) Slog.d(TAG, "Client connection lost with reason: " + msg.arg1); 258c23971b3e4f92ac31996d4f9f32eef3cb4ef65fdIrfan Sheriff } 259c23971b3e4f92ac31996d4f9f32eef3cb4ef65fdIrfan Sheriff mClients.remove((AsyncChannel) msg.obj); 260c23971b3e4f92ac31996d4f9f32eef3cb4ef65fdIrfan Sheriff break; 261c23971b3e4f92ac31996d4f9f32eef3cb4ef65fdIrfan Sheriff } 262227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: { 263227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff AsyncChannel ac = new AsyncChannel(); 264227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff ac.connect(mContext, this, msg.replyTo); 265227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff break; 266227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff } 267d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff case WifiManager.ENABLE_TRAFFIC_STATS_POLL: { 268227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff mEnableTrafficStatsPoll = (msg.arg1 == 1); 269227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff mTrafficStatsPollToken++; 270227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff if (mEnableTrafficStatsPoll) { 271227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff notifyOnDataActivity(); 272d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff sendMessageDelayed(Message.obtain(this, WifiManager.TRAFFIC_STATS_POLL, 273227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff mTrafficStatsPollToken, 0), POLL_TRAFFIC_STATS_INTERVAL_MSECS); 274227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff } 275227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff break; 276227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff } 277d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff case WifiManager.TRAFFIC_STATS_POLL: { 278227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff if (msg.arg1 == mTrafficStatsPollToken) { 279227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff notifyOnDataActivity(); 280d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff sendMessageDelayed(Message.obtain(this, WifiManager.TRAFFIC_STATS_POLL, 281227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff mTrafficStatsPollToken, 0), POLL_TRAFFIC_STATS_INTERVAL_MSECS); 2824b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville } 2834b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville break; 2844b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville } 285d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff case WifiManager.CONNECT_NETWORK: { 286d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff mWifiStateMachine.sendMessage(Message.obtain(msg)); 287ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff break; 288ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff } 289d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff case WifiManager.SAVE_NETWORK: { 290d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff mWifiStateMachine.sendMessage(Message.obtain(msg)); 291ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff break; 292ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff } 293d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff case WifiManager.FORGET_NETWORK: { 294d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff mWifiStateMachine.sendMessage(Message.obtain(msg)); 295ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff break; 296ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff } 297d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff case WifiManager.START_WPS: { 298d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff mWifiStateMachine.sendMessage(Message.obtain(msg)); 299ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff break; 300ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff } 30186a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff case WifiManager.CANCEL_WPS: { 30286a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff mWifiStateMachine.sendMessage(Message.obtain(msg)); 30386a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff break; 30486a5f5b9afa97a4ed6f5a2466fb9359ea131e2fbIrfan Sheriff } 305d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff case WifiManager.DISABLE_NETWORK: { 306d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff mWifiStateMachine.sendMessage(Message.obtain(msg)); 3078dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy break; 3088dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy } 309f6307820c88e694e102824225b9d8caa6de75a30Yuhao Zheng case WifiManager.RSSI_PKTCNT_FETCH: { 310f6307820c88e694e102824225b9d8caa6de75a30Yuhao Zheng mWifiStateMachine.sendMessage(Message.obtain(msg)); 311f6307820c88e694e102824225b9d8caa6de75a30Yuhao Zheng break; 312f6307820c88e694e102824225b9d8caa6de75a30Yuhao Zheng } 3134b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville default: { 3144b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville Slog.d(TAG, "WifiServicehandler.handleMessage ignoring msg=" + msg); 3154b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville break; 3164b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville } 3174b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville } 3184b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville } 3194b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville } 320227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff private AsyncServiceHandler mAsyncServiceHandler; 321227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff 322227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff /** 323227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff * Handles interaction with WifiStateMachine 324227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff */ 325227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff private class WifiStateMachineHandler extends Handler { 326227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff private AsyncChannel mWsmChannel; 327227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff 328227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff WifiStateMachineHandler(android.os.Looper looper) { 329227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff super(looper); 330227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff mWsmChannel = new AsyncChannel(); 331227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff mWsmChannel.connect(mContext, this, mWifiStateMachine.getHandler()); 332227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff } 333227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff 334227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff @Override 335227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff public void handleMessage(Message msg) { 336227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff switch (msg.what) { 337227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: { 338227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { 339227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff mWifiStateMachineChannel = mWsmChannel; 340227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff } else { 341227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff Slog.e(TAG, "WifiStateMachine connection failure, error=" + msg.arg1); 342227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff mWifiStateMachineChannel = null; 343227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff } 344227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff break; 345227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff } 3466da83d5868907f64658d51f6a59261ed16c386a1Irfan Sheriff case AsyncChannel.CMD_CHANNEL_DISCONNECTED: { 3476da83d5868907f64658d51f6a59261ed16c386a1Irfan Sheriff Slog.e(TAG, "WifiStateMachine channel lost, msg.arg1 =" + msg.arg1); 3486da83d5868907f64658d51f6a59261ed16c386a1Irfan Sheriff mWifiStateMachineChannel = null; 3496da83d5868907f64658d51f6a59261ed16c386a1Irfan Sheriff //Re-establish connection to state machine 3506da83d5868907f64658d51f6a59261ed16c386a1Irfan Sheriff mWsmChannel.connect(mContext, this, mWifiStateMachine.getHandler()); 3516da83d5868907f64658d51f6a59261ed16c386a1Irfan Sheriff break; 3526da83d5868907f64658d51f6a59261ed16c386a1Irfan Sheriff } 353227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff default: { 354227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff Slog.d(TAG, "WifiStateMachineHandler.handleMessage ignoring msg=" + msg); 355227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff break; 356227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff } 357227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff } 358227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff } 359227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff } 360227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff WifiStateMachineHandler mWifiStateMachineHandler; 3614b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville 3624b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville /** 36303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn * Temporary for computing UIDS that are responsible for starting WIFI. 36403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn * Protected by mWifiStateTracker lock. 36503f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn */ 36603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn private final WorkSource mTmpWorkSource = new WorkSource(); 367654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private WifiWatchdogStateMachine mWifiWatchdogStateMachine; 3680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 3690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff WifiService(Context context) { 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 371227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff 372227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff mInterfaceName = SystemProperties.get("wifi.interface", "wlan0"); 373227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff 374227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff mWifiStateMachine = new WifiStateMachine(mContext, mInterfaceName); 3750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff mWifiStateMachine.enableRssiPolling(true); 376105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mBatteryStats = BatteryStatsService.getService(); 377084c665421502b13271e94bd0a342b0ddbbaa7caJaikumar Ganesh 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE); 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent idleIntent = new Intent(ACTION_DEVICE_IDLE, null); 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIdleIntent = PendingIntent.getBroadcast(mContext, IDLE_REQUEST, idleIntent, 0); 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.registerReceiver( 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new BroadcastReceiver() { 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onReceive(Context context, Intent intent) { 386658772f0e6bcf2b0a3e26778c2fc47accbdfeb2eIrfan Sheriff mAirplaneModeOn.set(isAirplaneModeOn()); 38742d73bba668aea978259e574675f37ede80dd34eIrfan Sheriff handleAirplaneModeToggled(mAirplaneModeOn.get()); 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateWifiState(); 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }, 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED)); 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff IntentFilter filter = new IntentFilter(); 3940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); 3950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); 3960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); 3970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 3980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff mContext.registerReceiver( 3990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff new BroadcastReceiver() { 4000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff @Override 4010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff public void onReceive(Context context, Intent intent) { 4020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff if (intent.getAction().equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { 4035401f0b87b9bdcd603c55871a37fff07ab3054d7Irfan Sheriff int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 4045401f0b87b9bdcd603c55871a37fff07ab3054d7Irfan Sheriff WifiManager.WIFI_STATE_DISABLED); 4055401f0b87b9bdcd603c55871a37fff07ab3054d7Irfan Sheriff 4065401f0b87b9bdcd603c55871a37fff07ab3054d7Irfan Sheriff mWifiEnabled = (wifiState == WifiManager.WIFI_STATE_ENABLED); 4075401f0b87b9bdcd603c55871a37fff07ab3054d7Irfan Sheriff 4085401f0b87b9bdcd603c55871a37fff07ab3054d7Irfan Sheriff // reset & clear notification on any wifi state change 4090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff resetNotification(); 4100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff } else if (intent.getAction().equals( 4110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff WifiManager.NETWORK_STATE_CHANGED_ACTION)) { 4120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff mNetworkInfo = (NetworkInfo) intent.getParcelableExtra( 4130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff WifiManager.EXTRA_NETWORK_INFO); 4140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff // reset & clear notification on a network connect & disconnect 4150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff switch(mNetworkInfo.getDetailedState()) { 4160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff case CONNECTED: 4170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff case DISCONNECTED: 418da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff case CAPTIVE_PORTAL_CHECK: 419227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff evaluateTrafficStatsPolling(); 4200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff resetNotification(); 4210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff break; 4220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff } 4230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff } else if (intent.getAction().equals( 4240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { 4256ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly noteScanEnd(); 4260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff checkAndSetNotification(); 4270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff } 4280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff } 4290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff }, filter); 4300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 431227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff HandlerThread wifiThread = new HandlerThread("WifiService"); 432227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff wifiThread.start(); 433227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff mAsyncServiceHandler = new AsyncServiceHandler(wifiThread.getLooper()); 434227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff mWifiStateMachineHandler = new WifiStateMachineHandler(wifiThread.getLooper()); 435227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff 4360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff // Setting is in seconds 4376f5a9a96523ecf97a9828a410dd1226df47ec4e6Christopher Tate NOTIFICATION_REPEAT_DELAY_MS = Settings.Global.getInt(context.getContentResolver(), 4386f5a9a96523ecf97a9828a410dd1226df47ec4e6Christopher Tate Settings.Global.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY, 900) * 1000l; 4390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff mNotificationEnabledSettingObserver = new NotificationEnabledSettingObserver(new Handler()); 4400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff mNotificationEnabledSettingObserver.register(); 4417b00978dc739ed2213ed8e511c69cfb412798109Irfan Sheriff } 4425321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff 4436ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly /** Tell battery stats about a new WIFI scan */ 4446ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly private void noteScanStart() { 4456ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly WorkSource scanWorkSource = null; 4466ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly synchronized (WifiService.this) { 4476ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly if (mScanWorkSource != null) { 4486ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly // Scan already in progress, don't add this one to battery stats 4496ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly return; 4506ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly } 4516ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly scanWorkSource = new WorkSource(Binder.getCallingUid()); 4526ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly mScanWorkSource = scanWorkSource; 4536ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly } 4546ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly 4556ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly long id = Binder.clearCallingIdentity(); 4566ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly try { 4576ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly mBatteryStats.noteWifiScanStartedFromSource(scanWorkSource); 4586ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly } catch (RemoteException e) { 4596ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly Log.w(TAG, e); 4606ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly } finally { 4616ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly Binder.restoreCallingIdentity(id); 4626ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly } 4636ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly } 4646ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly 4656ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly /** Tell battery stats that the current WIFI scan has completed */ 4666ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly private void noteScanEnd() { 4676ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly WorkSource scanWorkSource = null; 4686ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly synchronized (WifiService.this) { 4696ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly scanWorkSource = mScanWorkSource; 4706ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly mScanWorkSource = null; 4716ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly } 4726ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly if (scanWorkSource != null) { 4736ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly try { 4746ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly mBatteryStats.noteWifiScanStoppedFromSource(scanWorkSource); 4756ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly } catch (RemoteException e) { 4766ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly Log.w(TAG, e); 4776ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly } 4786ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly } 4796ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly } 4806ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly 4817b00978dc739ed2213ed8e511c69cfb412798109Irfan Sheriff /** 4827b00978dc739ed2213ed8e511c69cfb412798109Irfan Sheriff * Check if Wi-Fi needs to be enabled and start 4837b00978dc739ed2213ed8e511c69cfb412798109Irfan Sheriff * if needed 48460e3ba071d2b129906e92981d1615a46febd825aIrfan Sheriff * 48560e3ba071d2b129906e92981d1615a46febd825aIrfan Sheriff * This function is used only at boot time 4867b00978dc739ed2213ed8e511c69cfb412798109Irfan Sheriff */ 4870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff public void checkAndStartWifi() { 488658772f0e6bcf2b0a3e26778c2fc47accbdfeb2eIrfan Sheriff mAirplaneModeOn.set(isAirplaneModeOn()); 4895401f0b87b9bdcd603c55871a37fff07ab3054d7Irfan Sheriff mPersistWifiState.set(getPersistedWifiState()); 490658772f0e6bcf2b0a3e26778c2fc47accbdfeb2eIrfan Sheriff /* Start if Wi-Fi should be enabled or the saved state indicates Wi-Fi was on */ 491658772f0e6bcf2b0a3e26778c2fc47accbdfeb2eIrfan Sheriff boolean wifiEnabled = shouldWifiBeEnabled() || testAndClearWifiSavedState(); 4927b00978dc739ed2213ed8e511c69cfb412798109Irfan Sheriff Slog.i(TAG, "WifiService starting up with Wi-Fi " + 4937b00978dc739ed2213ed8e511c69cfb412798109Irfan Sheriff (wifiEnabled ? "enabled" : "disabled")); 494f03d62007c252271aa30360de90a50b3a974ee8fIrfan Sheriff 495f03d62007c252271aa30360de90a50b3a974ee8fIrfan Sheriff // If we are already disabled (could be due to airplane mode), avoid changing persist 496f03d62007c252271aa30360de90a50b3a974ee8fIrfan Sheriff // state here 497f03d62007c252271aa30360de90a50b3a974ee8fIrfan Sheriff if (wifiEnabled) setWifiEnabled(wifiEnabled); 498bc7dfb58bffea133ccf6d94470a26f8d193f4890Isaac Levy 499654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mWifiWatchdogStateMachine = WifiWatchdogStateMachine. 500654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy makeWifiWatchdogStateMachine(mContext); 501654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 5025321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff } 5035321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff 504a3bd409a0a5dea446bd1b6edca1b367f3f70b503Irfan Sheriff private boolean testAndClearWifiSavedState() { 505a3bd409a0a5dea446bd1b6edca1b367f3f70b503Irfan Sheriff final ContentResolver cr = mContext.getContentResolver(); 506a3bd409a0a5dea446bd1b6edca1b367f3f70b503Irfan Sheriff int wifiSavedState = 0; 507a3bd409a0a5dea446bd1b6edca1b367f3f70b503Irfan Sheriff try { 5086f5a9a96523ecf97a9828a410dd1226df47ec4e6Christopher Tate wifiSavedState = Settings.Global.getInt(cr, Settings.Global.WIFI_SAVED_STATE); 509a3bd409a0a5dea446bd1b6edca1b367f3f70b503Irfan Sheriff if(wifiSavedState == 1) 5106f5a9a96523ecf97a9828a410dd1226df47ec4e6Christopher Tate Settings.Global.putInt(cr, Settings.Global.WIFI_SAVED_STATE, 0); 511a3bd409a0a5dea446bd1b6edca1b367f3f70b503Irfan Sheriff } catch (Settings.SettingNotFoundException e) { 512a3bd409a0a5dea446bd1b6edca1b367f3f70b503Irfan Sheriff ; 513a3bd409a0a5dea446bd1b6edca1b367f3f70b503Irfan Sheriff } 514a3bd409a0a5dea446bd1b6edca1b367f3f70b503Irfan Sheriff return (wifiSavedState == 1); 515a3bd409a0a5dea446bd1b6edca1b367f3f70b503Irfan Sheriff } 516a3bd409a0a5dea446bd1b6edca1b367f3f70b503Irfan Sheriff 517658772f0e6bcf2b0a3e26778c2fc47accbdfeb2eIrfan Sheriff private int getPersistedWifiState() { 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ContentResolver cr = mContext.getContentResolver(); 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 5206f5a9a96523ecf97a9828a410dd1226df47ec4e6Christopher Tate return Settings.Global.getInt(cr, Settings.Global.WIFI_ON); 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Settings.SettingNotFoundException e) { 5226f5a9a96523ecf97a9828a410dd1226df47ec4e6Christopher Tate Settings.Global.putInt(cr, Settings.Global.WIFI_ON, WIFI_DISABLED); 523658772f0e6bcf2b0a3e26778c2fc47accbdfeb2eIrfan Sheriff return WIFI_DISABLED; 524658772f0e6bcf2b0a3e26778c2fc47accbdfeb2eIrfan Sheriff } 525658772f0e6bcf2b0a3e26778c2fc47accbdfeb2eIrfan Sheriff } 526658772f0e6bcf2b0a3e26778c2fc47accbdfeb2eIrfan Sheriff 527658772f0e6bcf2b0a3e26778c2fc47accbdfeb2eIrfan Sheriff private boolean shouldWifiBeEnabled() { 528658772f0e6bcf2b0a3e26778c2fc47accbdfeb2eIrfan Sheriff if (mAirplaneModeOn.get()) { 5295401f0b87b9bdcd603c55871a37fff07ab3054d7Irfan Sheriff return mPersistWifiState.get() == WIFI_ENABLED_AIRPLANE_OVERRIDE; 530658772f0e6bcf2b0a3e26778c2fc47accbdfeb2eIrfan Sheriff } else { 5315401f0b87b9bdcd603c55871a37fff07ab3054d7Irfan Sheriff return mPersistWifiState.get() != WIFI_DISABLED; 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 53542d73bba668aea978259e574675f37ede80dd34eIrfan Sheriff private void handleWifiToggled(boolean wifiEnabled) { 53642d73bba668aea978259e574675f37ede80dd34eIrfan Sheriff boolean airplaneEnabled = mAirplaneModeOn.get() && isAirplaneToggleable(); 53742d73bba668aea978259e574675f37ede80dd34eIrfan Sheriff if (wifiEnabled) { 53842d73bba668aea978259e574675f37ede80dd34eIrfan Sheriff if (airplaneEnabled) { 539f03d62007c252271aa30360de90a50b3a974ee8fIrfan Sheriff persistWifiState(WIFI_ENABLED_AIRPLANE_OVERRIDE); 540658772f0e6bcf2b0a3e26778c2fc47accbdfeb2eIrfan Sheriff } else { 541f03d62007c252271aa30360de90a50b3a974ee8fIrfan Sheriff persistWifiState(WIFI_ENABLED); 542658772f0e6bcf2b0a3e26778c2fc47accbdfeb2eIrfan Sheriff } 543658772f0e6bcf2b0a3e26778c2fc47accbdfeb2eIrfan Sheriff } else { 544f03d62007c252271aa30360de90a50b3a974ee8fIrfan Sheriff // When wifi state is disabled, we do not care 545f03d62007c252271aa30360de90a50b3a974ee8fIrfan Sheriff // if airplane mode is on or not. The scenario of 546f03d62007c252271aa30360de90a50b3a974ee8fIrfan Sheriff // wifi being disabled due to airplane mode being turned on 547f03d62007c252271aa30360de90a50b3a974ee8fIrfan Sheriff // is handled handleAirplaneModeToggled() 548f03d62007c252271aa30360de90a50b3a974ee8fIrfan Sheriff persistWifiState(WIFI_DISABLED); 549658772f0e6bcf2b0a3e26778c2fc47accbdfeb2eIrfan Sheriff } 550f03d62007c252271aa30360de90a50b3a974ee8fIrfan Sheriff } 5515401f0b87b9bdcd603c55871a37fff07ab3054d7Irfan Sheriff 55242d73bba668aea978259e574675f37ede80dd34eIrfan Sheriff private void handleAirplaneModeToggled(boolean airplaneEnabled) { 55342d73bba668aea978259e574675f37ede80dd34eIrfan Sheriff if (airplaneEnabled) { 554f03d62007c252271aa30360de90a50b3a974ee8fIrfan Sheriff // Wifi disabled due to airplane on 555f03d62007c252271aa30360de90a50b3a974ee8fIrfan Sheriff if (mWifiEnabled) { 556f03d62007c252271aa30360de90a50b3a974ee8fIrfan Sheriff persistWifiState(WIFI_DISABLED_AIRPLANE_ON); 557f03d62007c252271aa30360de90a50b3a974ee8fIrfan Sheriff } 558f03d62007c252271aa30360de90a50b3a974ee8fIrfan Sheriff } else { 559f03d62007c252271aa30360de90a50b3a974ee8fIrfan Sheriff /* On airplane mode disable, restore wifi state if necessary */ 560f03d62007c252271aa30360de90a50b3a974ee8fIrfan Sheriff if (testAndClearWifiSavedState() || 561f03d62007c252271aa30360de90a50b3a974ee8fIrfan Sheriff mPersistWifiState.get() == WIFI_ENABLED_AIRPLANE_OVERRIDE) { 562f03d62007c252271aa30360de90a50b3a974ee8fIrfan Sheriff persistWifiState(WIFI_ENABLED); 563f03d62007c252271aa30360de90a50b3a974ee8fIrfan Sheriff } 564f03d62007c252271aa30360de90a50b3a974ee8fIrfan Sheriff } 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 567f03d62007c252271aa30360de90a50b3a974ee8fIrfan Sheriff private void persistWifiState(int state) { 568f03d62007c252271aa30360de90a50b3a974ee8fIrfan Sheriff final ContentResolver cr = mContext.getContentResolver(); 569f03d62007c252271aa30360de90a50b3a974ee8fIrfan Sheriff mPersistWifiState.set(state); 5706f5a9a96523ecf97a9828a410dd1226df47ec4e6Christopher Tate Settings.Global.putInt(cr, Settings.Global.WIFI_ON, state); 571f03d62007c252271aa30360de90a50b3a974ee8fIrfan Sheriff } 572658772f0e6bcf2b0a3e26778c2fc47accbdfeb2eIrfan Sheriff 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * see {@link android.net.wifi.WifiManager#pingSupplicant()} 575a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff * @return {@code true} if the operation succeeds, {@code false} otherwise 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean pingSupplicant() { 578a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff enforceAccessPermission(); 579227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff if (mWifiStateMachineChannel != null) { 580227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff return mWifiStateMachine.syncPingSupplicant(mWifiStateMachineChannel); 5811406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff } else { 582227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff Slog.e(TAG, "mWifiStateMachineChannel is not initialized"); 5831406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff return false; 5841406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff } 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * see {@link android.net.wifi.WifiManager#startScan()} 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 590e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff public void startScan(boolean forceActive) { 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceChangePermission(); 592e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff mWifiStateMachine.startScan(forceActive); 5936ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly noteScanStart(); 594a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff } 595a8fbe1fb74d3bd40b73c90c85ac25e5176475ca5Irfan Sheriff 596a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff private void enforceAccessPermission() { 597a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_WIFI_STATE, 598a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff "WifiService"); 599a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff } 600a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff 601a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff private void enforceChangePermission() { 602a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CHANGE_WIFI_STATE, 603a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff "WifiService"); 604a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff 605a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff } 606a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff 607a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff private void enforceMulticastChangePermission() { 608a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff mContext.enforceCallingOrSelfPermission( 609a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff android.Manifest.permission.CHANGE_WIFI_MULTICAST_STATE, 610a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff "WifiService"); 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 613da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff private void enforceConnectivityInternalPermission() { 614da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff mContext.enforceCallingOrSelfPermission( 615da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff android.Manifest.permission.CONNECTIVITY_INTERNAL, 616da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff "ConnectivityService"); 617da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff } 618da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * see {@link android.net.wifi.WifiManager#setWifiEnabled(boolean)} 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param enable {@code true} to enable, {@code false} to disable. 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return {@code true} if the enable/disable operation was 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * started or is already in the queue. 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 625a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff public synchronized boolean setWifiEnabled(boolean enable) { 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceChangePermission(); 627bd21b78f0f018f1ea2fc750232ffc20263baa2e0Irfan Sheriff Slog.d(TAG, "setWifiEnabled: " + enable + " pid=" + Binder.getCallingPid() 628bd21b78f0f018f1ea2fc750232ffc20263baa2e0Irfan Sheriff + ", uid=" + Binder.getCallingUid()); 629a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff if (DBG) { 6300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff Slog.e(TAG, "Invoking mWifiStateMachine.setWifiEnabled\n"); 631cd7703712eafb68b735233146b5e13c8c8e17609Irfan Sheriff } 632cd7703712eafb68b735233146b5e13c8c8e17609Irfan Sheriff 63303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn if (enable) { 63403f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn reportStartWorkSource(); 635cd7703712eafb68b735233146b5e13c8c8e17609Irfan Sheriff } 6360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff mWifiStateMachine.setWifiEnabled(enable); 6376118069b1dc4c487d02d3df5b883e756dc42b605Irfan Sheriff 6386118069b1dc4c487d02d3df5b883e756dc42b605Irfan Sheriff /* 6396118069b1dc4c487d02d3df5b883e756dc42b605Irfan Sheriff * Caller might not have WRITE_SECURE_SETTINGS, 6406118069b1dc4c487d02d3df5b883e756dc42b605Irfan Sheriff * only CHANGE_WIFI_STATE is enforced 6416118069b1dc4c487d02d3df5b883e756dc42b605Irfan Sheriff */ 6425401f0b87b9bdcd603c55871a37fff07ab3054d7Irfan Sheriff 643f03d62007c252271aa30360de90a50b3a974ee8fIrfan Sheriff long ident = Binder.clearCallingIdentity(); 6443d33a633916be943eb294d3309701994095d80f2Irfan Sheriff try { 6453d33a633916be943eb294d3309701994095d80f2Irfan Sheriff handleWifiToggled(enable); 6463d33a633916be943eb294d3309701994095d80f2Irfan Sheriff } finally { 6473d33a633916be943eb294d3309701994095d80f2Irfan Sheriff Binder.restoreCallingIdentity(ident); 6483d33a633916be943eb294d3309701994095d80f2Irfan Sheriff } 649f91444c5e161bd0017c0a9a2a38f597da3805046Irfan Sheriff 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enable) { 651a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff if (!mIsReceiverRegistered) { 652a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff registerForBroadcasts(); 653a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff mIsReceiverRegistered = true; 654a8fbe1fb74d3bd40b73c90c85ac25e5176475ca5Irfan Sheriff } 6555401f0b87b9bdcd603c55871a37fff07ab3054d7Irfan Sheriff } else if (mIsReceiverRegistered) { 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.unregisterReceiver(mReceiver); 657a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff mIsReceiverRegistered = false; 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * see {@link WifiManager#getWifiState()} 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return One of {@link WifiManager#WIFI_STATE_DISABLED}, 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link WifiManager#WIFI_STATE_DISABLING}, 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link WifiManager#WIFI_STATE_ENABLED}, 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link WifiManager#WIFI_STATE_ENABLING}, 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link WifiManager#WIFI_STATE_UNKNOWN} 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getWifiEnabledState() { 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceAccessPermission(); 673d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff return mWifiStateMachine.syncGetWifiState(); 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 677c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff * see {@link android.net.wifi.WifiManager#setWifiApEnabled(WifiConfiguration, boolean)} 6785321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff * @param wifiConfig SSID, security and channel details as 6795321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff * part of WifiConfiguration 680a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff * @param enabled true to enable and false to disable 6815321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff */ 682ffcea7ae7316ab748a49f5e8f6c6798356f35719Irfan Sheriff public void setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) { 6835321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff enforceChangePermission(); 6840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff mWifiStateMachine.setWifiApEnabled(wifiConfig, enabled); 6855321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff } 6865321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff 687a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff /** 688a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff * see {@link WifiManager#getWifiApState()} 689a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff * @return One of {@link WifiManager#WIFI_AP_STATE_DISABLED}, 690a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff * {@link WifiManager#WIFI_AP_STATE_DISABLING}, 691a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff * {@link WifiManager#WIFI_AP_STATE_ENABLED}, 692a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff * {@link WifiManager#WIFI_AP_STATE_ENABLING}, 693a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff * {@link WifiManager#WIFI_AP_STATE_FAILED} 694a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff */ 695a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff public int getWifiApEnabledState() { 69617b232b5b59ab91ab543b87e849583678a000f9bIrfan Sheriff enforceAccessPermission(); 697d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff return mWifiStateMachine.syncGetWifiApState(); 698a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff } 699a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff 700a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff /** 701a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff * see {@link WifiManager#getWifiApConfiguration()} 702a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff * @return soft access point configuration 703a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff */ 704ffcea7ae7316ab748a49f5e8f6c6798356f35719Irfan Sheriff public WifiConfiguration getWifiApConfiguration() { 705ffcea7ae7316ab748a49f5e8f6c6798356f35719Irfan Sheriff enforceAccessPermission(); 7069575a1bea1787efe1686bd8562bcc70c72d01721Irfan Sheriff return mWifiStateMachine.syncGetWifiApConfiguration(); 7079ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff } 7089ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff 709a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff /** 710a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff * see {@link WifiManager#setWifiApConfiguration(WifiConfiguration)} 711a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff * @param wifiConfig WifiConfiguration details for soft access point 712a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff */ 713ffcea7ae7316ab748a49f5e8f6c6798356f35719Irfan Sheriff public void setWifiApConfiguration(WifiConfiguration wifiConfig) { 71417b232b5b59ab91ab543b87e849583678a000f9bIrfan Sheriff enforceChangePermission(); 7159ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff if (wifiConfig == null) 7169ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff return; 717ffcea7ae7316ab748a49f5e8f6c6798356f35719Irfan Sheriff mWifiStateMachine.setWifiApConfiguration(wifiConfig); 7189ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff } 7199ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff 7205321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff /** 721a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff * see {@link android.net.wifi.WifiManager#disconnect()} 7225321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff */ 723e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff public void disconnect() { 724a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff enforceChangePermission(); 725e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff mWifiStateMachine.disconnectCommand(); 7265321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff } 7275321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff 7285321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff /** 729a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff * see {@link android.net.wifi.WifiManager#reconnect()} 7305321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff */ 731e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff public void reconnect() { 732a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff enforceChangePermission(); 733e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff mWifiStateMachine.reconnectCommand(); 7345321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff } 7355321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff 736a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff /** 737a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff * see {@link android.net.wifi.WifiManager#reassociate()} 738a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff */ 739e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff public void reassociate() { 740a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff enforceChangePermission(); 741e498475b187277309c81b38240c7e71ec049e369Irfan Sheriff mWifiStateMachine.reassociateCommand(); 7425321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff } 7435321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * see {@link android.net.wifi.WifiManager#getConfiguredNetworks()} 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the list of configured networks 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public List<WifiConfiguration> getConfiguredNetworks() { 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceAccessPermission(); 750e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff if (mWifiStateMachineChannel != null) { 751e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff return mWifiStateMachine.syncGetConfiguredNetworks(mWifiStateMachineChannel); 752e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff } else { 753e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff Slog.e(TAG, "mWifiStateMachineChannel is not initialized"); 754e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff return null; 755e744cfff7ca5406f7bba17a14b89856c1ca83262Irfan Sheriff } 756a8d15941392956c383902e715028032afb583952Chung-yih Wang } 757a8d15941392956c383902e715028032afb583952Chung-yih Wang 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * see {@link android.net.wifi.WifiManager#addOrUpdateNetwork(WifiConfiguration)} 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the supplicant-assigned identifier for the new or updated 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * network if the operation succeeds, or {@code -1} if it fails 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7637aac5547daf54005243c5d685cf60c5a4ff74a44Irfan Sheriff public int addOrUpdateNetwork(WifiConfiguration config) { 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceChangePermission(); 765227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff if (mWifiStateMachineChannel != null) { 766227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff return mWifiStateMachine.syncAddOrUpdateNetwork(mWifiStateMachineChannel, config); 7671406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff } else { 768227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff Slog.e(TAG, "mWifiStateMachineChannel is not initialized"); 7691406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff return -1; 7701406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff } 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 773a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff /** 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See {@link android.net.wifi.WifiManager#removeNetwork(int)} 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param netId the integer that identifies the network configuration 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to the supplicant 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return {@code true} if the operation succeeded 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean removeNetwork(int netId) { 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceChangePermission(); 781227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff if (mWifiStateMachineChannel != null) { 782227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff return mWifiStateMachine.syncRemoveNetwork(mWifiStateMachineChannel, netId); 7834b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville } else { 784227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff Slog.e(TAG, "mWifiStateMachineChannel is not initialized"); 7854b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville return false; 7864b7ba09c8bf773dbd045b4bbe7831fa16e33653dWink Saville } 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See {@link android.net.wifi.WifiManager#enableNetwork(int, boolean)} 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param netId the integer that identifies the network configuration 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to the supplicant 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param disableOthers if true, disable all other networks. 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return {@code true} if the operation succeeded 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean enableNetwork(int netId, boolean disableOthers) { 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceChangePermission(); 798227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff if (mWifiStateMachineChannel != null) { 799227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff return mWifiStateMachine.syncEnableNetwork(mWifiStateMachineChannel, netId, 800227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff disableOthers); 8011406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff } else { 802227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff Slog.e(TAG, "mWifiStateMachineChannel is not initialized"); 8031406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff return false; 8041406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff } 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See {@link android.net.wifi.WifiManager#disableNetwork(int)} 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param netId the integer that identifies the network configuration 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to the supplicant 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return {@code true} if the operation succeeded 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean disableNetwork(int netId) { 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceChangePermission(); 815227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff if (mWifiStateMachineChannel != null) { 816227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff return mWifiStateMachine.syncDisableNetwork(mWifiStateMachineChannel, netId); 8171406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff } else { 818227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff Slog.e(TAG, "mWifiStateMachineChannel is not initialized"); 8191406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff return false; 8201406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff } 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See {@link android.net.wifi.WifiManager#getConnectionInfo()} 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the Wi-Fi information, contained in {@link WifiInfo}. 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public WifiInfo getConnectionInfo() { 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceAccessPermission(); 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Make sure we have the latest information, by sending 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a status request to the supplicant. 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 833d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff return mWifiStateMachine.syncRequestConnectionInfo(); 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the results of the most recent access point scan, in the form of 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a list of {@link ScanResult} objects. 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the list of results 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public List<ScanResult> getScanResults() { 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceAccessPermission(); 843db831da426602f36e4ccf2eae64e999fcc52736aIrfan Sheriff int userId = UserHandle.getCallingUserId(); 844db831da426602f36e4ccf2eae64e999fcc52736aIrfan Sheriff long ident = Binder.clearCallingIdentity(); 8453d33a633916be943eb294d3309701994095d80f2Irfan Sheriff try { 8463d33a633916be943eb294d3309701994095d80f2Irfan Sheriff int currentUser = ActivityManager.getCurrentUser(); 8473d33a633916be943eb294d3309701994095d80f2Irfan Sheriff if (userId != currentUser) { 8483d33a633916be943eb294d3309701994095d80f2Irfan Sheriff return new ArrayList<ScanResult>(); 8493d33a633916be943eb294d3309701994095d80f2Irfan Sheriff } else { 8503d33a633916be943eb294d3309701994095d80f2Irfan Sheriff return mWifiStateMachine.syncGetScanResultsList(); 8513d33a633916be943eb294d3309701994095d80f2Irfan Sheriff } 8523d33a633916be943eb294d3309701994095d80f2Irfan Sheriff } finally { 8533d33a633916be943eb294d3309701994095d80f2Irfan Sheriff Binder.restoreCallingIdentity(ident); 854330b1875747561e1f4dfdc062bf15d3c345806edIrfan Sheriff } 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Tell the supplicant to persist the current list of configured networks. 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return {@code true} if the operation succeeded 860a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff * 861a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff * TODO: deprecate this 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean saveConfiguration() { 864a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff boolean result = true; 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceChangePermission(); 866227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff if (mWifiStateMachineChannel != null) { 867227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff return mWifiStateMachine.syncSaveConfig(mWifiStateMachineChannel); 8681406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff } else { 869227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff Slog.e(TAG, "mWifiStateMachineChannel is not initialized"); 8701406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff return false; 8711406bcb75150e8386b4d858f27089cc1359e7f14Irfan Sheriff } 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 875ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff * Set the country code 876ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff * @param countryCode ISO 3166 country code. 877b5010cc3c33c74cc406a70f34f93d330a3f0db6aRobert Greenwalt * @param persist {@code true} if the setting should be remembered. 878ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff * 879ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff * The persist behavior exists so that wifi can fall back to the last 880ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff * persisted country code on a restart, when the locale information is 881ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff * not available from telephony. 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 883ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff public void setCountryCode(String countryCode, boolean persist) { 884ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff Slog.i(TAG, "WifiService trying to set country code to " + countryCode + 885ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff " with persist set to " + persist); 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceChangePermission(); 887ed4f28b492da3ff140bbaabbbda798a08c40ea5bIrfan Sheriff mWifiStateMachine.setCountryCode(countryCode, persist); 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 89136f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff * Set the operational frequency band 89236f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff * @param band One of 89336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff * {@link WifiManager#WIFI_FREQUENCY_BAND_AUTO}, 89436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff * {@link WifiManager#WIFI_FREQUENCY_BAND_5GHZ}, 89536f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff * {@link WifiManager#WIFI_FREQUENCY_BAND_2GHZ}, 89636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff * @param persist {@code true} if the setting should be remembered. 89736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff * 89836f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff */ 89936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff public void setFrequencyBand(int band, boolean persist) { 90036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff enforceChangePermission(); 90136f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff if (!isDualBandSupported()) return; 90236f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff Slog.i(TAG, "WifiService trying to set frequency band to " + band + 90336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff " with persist set to " + persist); 90436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff mWifiStateMachine.setFrequencyBand(band, persist); 90536f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff } 90636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff 90736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff 90836f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff /** 90936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff * Get the operational frequency band 91036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff */ 91136f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff public int getFrequencyBand() { 91236f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff enforceAccessPermission(); 91336f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff return mWifiStateMachine.getFrequencyBand(); 91436f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff } 91536f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff 91636f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff public boolean isDualBandSupported() { 91736f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff //TODO: Should move towards adding a driver API that checks at runtime 91836f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff return mContext.getResources().getBoolean( 91936f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff com.android.internal.R.bool.config_wifi_dual_band_support); 92036f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff } 92136f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff 92236f7413dabfab50699135019ba55151e9227f59dIrfan Sheriff /** 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the DHCP-assigned addresses from the last successful DHCP request, 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if any. 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the DHCP information 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public DhcpInfo getDhcpInfo() { 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceAccessPermission(); 929d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff return mWifiStateMachine.syncGetDhcpInfo(); 9300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff } 9310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 9320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff /** 9330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * see {@link android.net.wifi.WifiManager#startWifi} 9340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * 9350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */ 9360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff public void startWifi() { 937da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff enforceConnectivityInternalPermission(); 9380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff /* TODO: may be add permissions for access only to connectivity service 9390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * TODO: if a start issued, keep wifi alive until a stop issued irrespective 9400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * of WifiLock & device idle status unless wifi enabled status is toggled 9410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */ 9420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 9434494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff mWifiStateMachine.setDriverStart(true, mEmergencyCallbackMode); 9440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff mWifiStateMachine.reconnectCommand(); 9450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff } 9460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 947da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff public void captivePortalCheckComplete() { 948da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff enforceConnectivityInternalPermission(); 949da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff mWifiStateMachine.captivePortalCheckComplete(); 950da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff } 951da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff 9520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff /** 9530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * see {@link android.net.wifi.WifiManager#stopWifi} 9540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * 9550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */ 9560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff public void stopWifi() { 957da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff enforceConnectivityInternalPermission(); 958da6da0907b28d4704aabbdb1bbeb4300954670d1Irfan Sheriff /* 9590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * TODO: if a stop is issued, wifi is brought up only by startWifi 9600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * unless wifi enabled status is toggled 9610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */ 9624494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff mWifiStateMachine.setDriverStart(false, mEmergencyCallbackMode); 9630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff } 9640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 9650d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff /** 9660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * see {@link android.net.wifi.WifiManager#addToBlacklist} 9670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * 9680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */ 9690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff public void addToBlacklist(String bssid) { 9700d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff enforceChangePermission(); 9710d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 9720d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff mWifiStateMachine.addToBlacklist(bssid); 9730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff } 9740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 9750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff /** 9760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * see {@link android.net.wifi.WifiManager#clearBlacklist} 9770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * 9780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */ 9790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff public void clearBlacklist() { 9800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff enforceChangePermission(); 9810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 9820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff mWifiStateMachine.clearBlacklist(); 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 985227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff /** 986227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff * Get a reference to handler. This is used by a client to establish 987227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff * an AsyncChannel communication with WifiService 988227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff */ 98907573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff public Messenger getWifiServiceMessenger() { 99035bbe27d58ccf01ffd170b0f617a568bc843a49eIrfan Sheriff enforceAccessPermission(); 99135bbe27d58ccf01ffd170b0f617a568bc843a49eIrfan Sheriff enforceChangePermission(); 992227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff return new Messenger(mAsyncServiceHandler); 993227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff } 994227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff 99507573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff /** Get a reference to WifiStateMachine handler for AsyncChannel communication */ 99607573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff public Messenger getWifiStateMachineMessenger() { 99707573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff enforceAccessPermission(); 99807573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff enforceChangePermission(); 99907573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff return mWifiStateMachine.getMessenger(); 100007573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff } 100107573b32494acbabd21979d8b9584c1ed3f7a6adIrfan Sheriff 10024aeca7c5908387bc7efb0785830aea1053264062Irfan Sheriff /** 10034aeca7c5908387bc7efb0785830aea1053264062Irfan Sheriff * Get the IP and proxy configuration file 10044aeca7c5908387bc7efb0785830aea1053264062Irfan Sheriff */ 10054aeca7c5908387bc7efb0785830aea1053264062Irfan Sheriff public String getConfigFile() { 10064aeca7c5908387bc7efb0785830aea1053264062Irfan Sheriff enforceAccessPermission(); 10074aeca7c5908387bc7efb0785830aea1053264062Irfan Sheriff return mWifiStateMachine.getConfigFile(); 10084aeca7c5908387bc7efb0785830aea1053264062Irfan Sheriff } 10094aeca7c5908387bc7efb0785830aea1053264062Irfan Sheriff 10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onReceive(Context context, Intent intent) { 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String action = intent.getAction(); 10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 101543866e0c48bb0effe8805afd62b253e50ca7d591Doug Zongker long idleMillis = 10166f5a9a96523ecf97a9828a410dd1226df47ec4e6Christopher Tate Settings.Global.getLong(mContext.getContentResolver(), 10176f5a9a96523ecf97a9828a410dd1226df47ec4e6Christopher Tate Settings.Global.WIFI_IDLE_MS, DEFAULT_IDLE_MS); 10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int stayAwakeConditions = 10196f5a9a96523ecf97a9828a410dd1226df47ec4e6Christopher Tate Settings.Global.getInt(mContext.getContentResolver(), 10206f5a9a96523ecf97a9828a410dd1226df47ec4e6Christopher Tate Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0); 10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (action.equals(Intent.ACTION_SCREEN_ON)) { 1022431bb2269532f2514861b908d5fafda8fa64da79Joe Onorato if (DBG) { 1023431bb2269532f2514861b908d5fafda8fa64da79Joe Onorato Slog.d(TAG, "ACTION_SCREEN_ON"); 1024431bb2269532f2514861b908d5fafda8fa64da79Joe Onorato } 10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAlarmManager.cancel(mIdleIntent); 10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mScreenOff = false; 1027227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff evaluateTrafficStatsPolling(); 1028e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff setDeviceIdleAndUpdateWifi(false); 10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (action.equals(Intent.ACTION_SCREEN_OFF)) { 1030431bb2269532f2514861b908d5fafda8fa64da79Joe Onorato if (DBG) { 1031431bb2269532f2514861b908d5fafda8fa64da79Joe Onorato Slog.d(TAG, "ACTION_SCREEN_OFF"); 1032431bb2269532f2514861b908d5fafda8fa64da79Joe Onorato } 10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mScreenOff = true; 1034227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff evaluateTrafficStatsPolling(); 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set a timer to put Wi-Fi to sleep, but only if the screen is off 10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * AND the "stay on while plugged in" setting doesn't match the 10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * current power conditions (i.e, not plugged in, plugged in to USB, 10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or plugged in to AC). 10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!shouldWifiStayAwake(stayAwakeConditions, mPluggedType)) { 1042e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff //Delayed shutdown if wifi is connected 1043e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff if (mNetworkInfo.getDetailedState() == DetailedState.CONNECTED) { 1044e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff if (DBG) Slog.d(TAG, "setting ACTION_DEVICE_IDLE: " + idleMillis + " ms"); 1045e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff mAlarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() 1046e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff + idleMillis, mIdleIntent); 1047d9c32bc838cb618dcbc1e48df02a34b6596b8930Mike Lockwood } else { 1048e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff setDeviceIdleAndUpdateWifi(true); 1049d9c32bc838cb618dcbc1e48df02a34b6596b8930Mike Lockwood } 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (action.equals(ACTION_DEVICE_IDLE)) { 1052e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff setDeviceIdleAndUpdateWifi(true); 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (action.equals(Intent.ACTION_BATTERY_CHANGED)) { 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set a timer to put Wi-Fi to sleep, but only if the screen is off 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * AND we are transitioning from a state in which the device was supposed 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to stay awake to a state in which it is not supposed to stay awake. 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If "stay awake" state is not changing, we do nothing, to avoid resetting 10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the already-set timer. 10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int pluggedType = intent.getIntExtra("plugged", 0); 1062431bb2269532f2514861b908d5fafda8fa64da79Joe Onorato if (DBG) { 1063431bb2269532f2514861b908d5fafda8fa64da79Joe Onorato Slog.d(TAG, "ACTION_BATTERY_CHANGED pluggedType: " + pluggedType); 1064431bb2269532f2514861b908d5fafda8fa64da79Joe Onorato } 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mScreenOff && shouldWifiStayAwake(stayAwakeConditions, mPluggedType) && 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project !shouldWifiStayAwake(stayAwakeConditions, pluggedType)) { 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long triggerTime = System.currentTimeMillis() + idleMillis; 1068431bb2269532f2514861b908d5fafda8fa64da79Joe Onorato if (DBG) { 1069431bb2269532f2514861b908d5fafda8fa64da79Joe Onorato Slog.d(TAG, "setting ACTION_DEVICE_IDLE timer for " + idleMillis + "ms"); 1070431bb2269532f2514861b908d5fafda8fa64da79Joe Onorato } 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAlarmManager.set(AlarmManager.RTC_WAKEUP, triggerTime, mIdleIntent); 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10738cef06798ef1f67641f8b15165aca39abd6c46caIrfan Sheriff 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPluggedType = pluggedType; 107565eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff } else if (action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) { 107665eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, 107765eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff BluetoothAdapter.STATE_DISCONNECTED); 107865eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff mWifiStateMachine.sendBluetoothAdapterStateChange(state); 1079616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriff } else if (action.equals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED)) { 1080616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriff mEmergencyCallbackMode = intent.getBooleanExtra("phoneinECMState", false); 1081616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriff updateWifiState(); 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Determines whether the Wi-Fi chipset should stay awake or be put to 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * sleep. Looks at the setting for the sleep policy and the current 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * conditions. 1089084c665421502b13271e94bd0a342b0ddbbaa7caJaikumar Ganesh * 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #shouldDeviceStayAwake(int, int) 10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean shouldWifiStayAwake(int stayAwakeConditions, int pluggedType) { 1093739f6bc675c0caa11a1d46b18de24e6c884f723aIrfan Sheriff //Never sleep as long as the user has not changed the settings 109435d323a5206644029eb53ae751268feca430cc46Brian Muramatsu int wifiSleepPolicy = Settings.Global.getInt(mContext.getContentResolver(), 109535d323a5206644029eb53ae751268feca430cc46Brian Muramatsu Settings.Global.WIFI_SLEEP_POLICY, 109635d323a5206644029eb53ae751268feca430cc46Brian Muramatsu Settings.Global.WIFI_SLEEP_POLICY_NEVER); 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 109835d323a5206644029eb53ae751268feca430cc46Brian Muramatsu if (wifiSleepPolicy == Settings.Global.WIFI_SLEEP_POLICY_NEVER) { 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Never sleep 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 110135d323a5206644029eb53ae751268feca430cc46Brian Muramatsu } else if ((wifiSleepPolicy == Settings.Global.WIFI_SLEEP_POLICY_NEVER_WHILE_PLUGGED) && 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (pluggedType != 0)) { 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Never sleep while plugged, and we're plugged 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Default 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return shouldDeviceStayAwake(stayAwakeConditions, pluggedType); 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1110084c665421502b13271e94bd0a342b0ddbbaa7caJaikumar Ganesh 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Determine whether the bit value corresponding to {@code pluggedType} is set in 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the bit string {@code stayAwakeConditions}. Because a {@code pluggedType} value 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of {@code 0} isn't really a plugged type, but rather an indication that the 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * device isn't plugged in at all, there is no bit value corresponding to a 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@code pluggedType} value of {@code 0}. That is why we shift by 11174e8620f868e2490782ebb960404140ea9482c91dBen Dodson * {@code pluggedType - 1} instead of by {@code pluggedType}. 11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param stayAwakeConditions a bit string specifying which "plugged types" should 11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * keep the device (and hence Wi-Fi) awake. 11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param pluggedType the type of plug (USB, AC, or none) for which the check is 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * being made 11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return {@code true} if {@code pluggedType} indicates that the device is 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * supposed to stay awake, {@code false} otherwise. 11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean shouldDeviceStayAwake(int stayAwakeConditions, int pluggedType) { 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (stayAwakeConditions & pluggedType) != 0; 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1130e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff private void setDeviceIdleAndUpdateWifi(boolean deviceIdle) { 1131e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff mDeviceIdle = deviceIdle; 1132e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff reportStartWorkSource(); 1133e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff updateWifiState(); 1134e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff } 1135e6daca5f53dbb872d0ba6682d0f98831a99c5d9fIrfan Sheriff 113603f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn private synchronized void reportStartWorkSource() { 113703f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn mTmpWorkSource.clear(); 113803f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn if (mDeviceIdle) { 113903f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn for (int i=0; i<mLocks.mList.size(); i++) { 114003f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn mTmpWorkSource.add(mLocks.mList.get(i).mWorkSource); 114158e0eefeb5e2e270e2b04369bbf29fc22abda8d5Dianne Hackborn } 114258e0eefeb5e2e270e2b04369bbf29fc22abda8d5Dianne Hackborn } 114303f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn mWifiStateMachine.updateBatteryWorkSource(mTmpWorkSource); 114458e0eefeb5e2e270e2b04369bbf29fc22abda8d5Dianne Hackborn } 11457440fc2e0e0257043b967a80dceb0b33797d1d12Jaikumar Ganesh 11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void updateWifiState() { 11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean lockHeld = mLocks.hasLocks(); 11485876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff int strongestLockMode = WifiManager.WIFI_MODE_FULL; 1149616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriff boolean wifiShouldBeStarted; 1150616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriff 1151616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriff if (mEmergencyCallbackMode) { 1152616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriff wifiShouldBeStarted = false; 1153616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriff } else { 1154616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriff wifiShouldBeStarted = !mDeviceIdle || lockHeld; 1155616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriff } 11565876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff 11575876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff if (lockHeld) { 11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project strongestLockMode = mLocks.getStrongestLockMode(); 11595876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff } 11605876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff /* If device is not idle, lockmode cannot be scan only */ 11615876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff if (!mDeviceIdle && strongestLockMode == WifiManager.WIFI_MODE_SCAN_ONLY) { 11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project strongestLockMode = WifiManager.WIFI_MODE_FULL; 11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1165a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff /* Disable tethering when airplane mode is enabled */ 1166658772f0e6bcf2b0a3e26778c2fc47accbdfeb2eIrfan Sheriff if (mAirplaneModeOn.get()) { 11670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff mWifiStateMachine.setWifiApEnabled(null, false); 1168a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff } 1169b2e6c01f449f3fd4effee7029518684deb4e98f6Irfan Sheriff 1170658772f0e6bcf2b0a3e26778c2fc47accbdfeb2eIrfan Sheriff if (shouldWifiBeEnabled()) { 1171a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff if (wifiShouldBeStarted) { 117203f3cb083d708d4d3226b80ed42c9d2876a56edcDianne Hackborn reportStartWorkSource(); 11730d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff mWifiStateMachine.setWifiEnabled(true); 11740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff mWifiStateMachine.setScanOnlyMode( 1175a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff strongestLockMode == WifiManager.WIFI_MODE_SCAN_ONLY); 11764494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff mWifiStateMachine.setDriverStart(true, mEmergencyCallbackMode); 11775876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff mWifiStateMachine.setHighPerfModeEnabled(strongestLockMode 11785876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff == WifiManager.WIFI_MODE_FULL_HIGH_PERF); 11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 11804494c906168f1b93eb9d130096036d06cfa1e291Irfan Sheriff mWifiStateMachine.setDriverStart(false, mEmergencyCallbackMode); 11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1182a2a1b911a31dd94ee75e94845f762b91f1db1368Irfan Sheriff } else { 11830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff mWifiStateMachine.setWifiEnabled(false); 11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void registerForBroadcasts() { 11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IntentFilter intentFilter = new IntentFilter(); 11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentFilter.addAction(Intent.ACTION_SCREEN_ON); 11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentFilter.addAction(Intent.ACTION_SCREEN_OFF); 11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED); 11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentFilter.addAction(ACTION_DEVICE_IDLE); 119365eaec88f3670384ac6c63e8c21ca13c21d2a407Irfan Sheriff intentFilter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED); 1194616f3173e08ec6110cf5766c70f84c9e031fb7d7Irfan Sheriff intentFilter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED); 11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.registerReceiver(mReceiver, intentFilter); 11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1197084c665421502b13271e94bd0a342b0ddbbaa7caJaikumar Ganesh 11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean isAirplaneSensitive() { 1199c09cdce1b05075da808ae080b9905a14a3e1e627Christopher Tate String airplaneModeRadios = Settings.Global.getString(mContext.getContentResolver(), 1200c09cdce1b05075da808ae080b9905a14a3e1e627Christopher Tate Settings.Global.AIRPLANE_MODE_RADIOS); 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return airplaneModeRadios == null 1202c09cdce1b05075da808ae080b9905a14a3e1e627Christopher Tate || airplaneModeRadios.contains(Settings.Global.RADIO_WIFI); 12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1205bd5ddf01e4d629982fa8bb667d4be7c5ec3aa79fMike Lockwood private boolean isAirplaneToggleable() { 1206c09cdce1b05075da808ae080b9905a14a3e1e627Christopher Tate String toggleableRadios = Settings.Global.getString(mContext.getContentResolver(), 1207c09cdce1b05075da808ae080b9905a14a3e1e627Christopher Tate Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS); 1208bd5ddf01e4d629982fa8bb667d4be7c5ec3aa79fMike Lockwood return toggleableRadios != null 1209c09cdce1b05075da808ae080b9905a14a3e1e627Christopher Tate && toggleableRadios.contains(Settings.Global.RADIO_WIFI); 1210bd5ddf01e4d629982fa8bb667d4be7c5ec3aa79fMike Lockwood } 1211bd5ddf01e4d629982fa8bb667d4be7c5ec3aa79fMike Lockwood 12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if Wi-Fi is sensitive to airplane mode, and airplane mode is 12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * currently on. 12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return {@code true} if airplane mode is on. 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean isAirplaneModeOn() { 1218c09cdce1b05075da808ae080b9905a14a3e1e627Christopher Tate return isAirplaneSensitive() && Settings.Global.getInt(mContext.getContentResolver(), 1219c09cdce1b05075da808ae080b9905a14a3e1e627Christopher Tate Settings.Global.AIRPLANE_MODE_ON, 0) == 1; 12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED) { 12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println("Permission Denial: can't dump WifiService from from pid=" 12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Binder.getCallingPid() 12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ", uid=" + Binder.getCallingUid()); 12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1231d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff pw.println("Wi-Fi is " + mWifiStateMachine.syncGetWifiStateByName()); 12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println("Stay-awake conditions: " + 1233c09cdce1b05075da808ae080b9905a14a3e1e627Christopher Tate Settings.Global.getInt(mContext.getContentResolver(), 1234c09cdce1b05075da808ae080b9905a14a3e1e627Christopher Tate Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0)); 12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(); 12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println("Internal state:"); 12380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff pw.println(mWifiStateMachine); 12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(); 12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println("Latest scan results:"); 1241d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff List<ScanResult> scanResults = mWifiStateMachine.syncGetScanResultsList(); 12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (scanResults != null && scanResults.size() != 0) { 12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" BSSID Frequency RSSI Flags SSID"); 12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (ScanResult r : scanResults) { 12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.printf(" %17s %9d %5d %-16s %s%n", 12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r.BSSID, 12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r.frequency, 12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r.level, 12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r.capabilities, 12509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r.SSID == null ? "" : r.SSID); 12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(); 12545711fadfc48f0e77bc25a91ef36c76acb0d2f55aEric Shienbrood pw.println("Locks acquired: " + mFullLocksAcquired + " full, " + 12555876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff mFullHighPerfLocksAcquired + " full high perf, " + 12565711fadfc48f0e77bc25a91ef36c76acb0d2f55aEric Shienbrood mScanLocksAcquired + " scan"); 12575711fadfc48f0e77bc25a91ef36c76acb0d2f55aEric Shienbrood pw.println("Locks released: " + mFullLocksReleased + " full, " + 12585876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff mFullHighPerfLocksReleased + " full high perf, " + 12595711fadfc48f0e77bc25a91ef36c76acb0d2f55aEric Shienbrood mScanLocksReleased + " scan"); 12605711fadfc48f0e77bc25a91ef36c76acb0d2f55aEric Shienbrood pw.println(); 12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println("Locks held:"); 12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocks.dump(pw); 1263bc7dfb58bffea133ccf6d94470a26f8d193f4890Isaac Levy 1264bc7dfb58bffea133ccf6d94470a26f8d193f4890Isaac Levy pw.println(); 1265654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy pw.println("WifiWatchdogStateMachine dump"); 1266654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mWifiWatchdogStateMachine.dump(pw); 126760792375761c0b2aed11f7f2ccb60c2e59f9fec1Irfan Sheriff pw.println("WifiStateMachine dump"); 126860792375761c0b2aed11f7f2ccb60c2e59f9fec1Irfan Sheriff mWifiStateMachine.dump(fd, pw, args); 12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 127158ff0217a617d5b03d18f0ef532f254f8ba6de2bRobert Greenwalt private class WifiLock extends DeathRecipient { 12727e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn WifiLock(int lockMode, String tag, IBinder binder, WorkSource ws) { 12737e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn super(lockMode, tag, binder, ws); 12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void binderDied() { 12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLocks) { 12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseWifiLockLocked(mBinder); 12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 12835347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt return "WifiLock{" + mTag + " type=" + mMode + " binder=" + mBinder + "}"; 12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class LockList { 12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private List<WifiLock> mList; 12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private LockList() { 12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mList = new ArrayList<WifiLock>(); 12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private synchronized boolean hasLocks() { 12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return !mList.isEmpty(); 12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private synchronized int getStrongestLockMode() { 12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mList.isEmpty()) { 13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return WifiManager.WIFI_MODE_FULL; 13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13025876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff 13035876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff if (mFullHighPerfLocksAcquired > mFullHighPerfLocksReleased) { 13045876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff return WifiManager.WIFI_MODE_FULL_HIGH_PERF; 13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13065876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff 13075876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff if (mFullLocksAcquired > mFullLocksReleased) { 13085876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff return WifiManager.WIFI_MODE_FULL; 13095876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff } 13105876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff 13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return WifiManager.WIFI_MODE_SCAN_ONLY; 13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void addLock(WifiLock lock) { 13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (findLockByBinder(lock.mBinder) < 0) { 13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mList.add(lock); 13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private WifiLock removeLock(IBinder binder) { 13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index = findLockByBinder(binder); 13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (index >= 0) { 1323fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu WifiLock ret = mList.remove(index); 1324fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu ret.unlinkDeathRecipient(); 1325fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu return ret; 13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int findLockByBinder(IBinder binder) { 13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int size = mList.size(); 13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = size - 1; i >= 0; i--) 13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mList.get(i).mBinder == binder) 13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return i; 13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void dump(PrintWriter pw) { 13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (WifiLock l : mList) { 13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.print(" "); 13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(l); 13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13477e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn void enforceWakeSourcePermission(int uid, int pid) { 1348e746f03c6c8b8d0897d322ab524d545ace200fcdDianne Hackborn if (uid == android.os.Process.myUid()) { 13497e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn return; 13507e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn } 13517e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS, 13527e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn pid, uid, null); 13537e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn } 13547e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn 13557e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn public boolean acquireWifiLock(IBinder binder, int lockMode, String tag, WorkSource ws) { 13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null); 13575876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff if (lockMode != WifiManager.WIFI_MODE_FULL && 13585876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff lockMode != WifiManager.WIFI_MODE_SCAN_ONLY && 13595876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff lockMode != WifiManager.WIFI_MODE_FULL_HIGH_PERF) { 13605876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff Slog.e(TAG, "Illegal argument, lockMode= " + lockMode); 13615876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff if (DBG) throw new IllegalArgumentException("lockMode=" + lockMode); 13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13647e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn if (ws != null && ws.size() == 0) { 13657e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn ws = null; 13667e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn } 1367ecfd7f7d9588728a4579fab8af1722cefeb32d40Dianne Hackborn if (ws != null) { 1368ecfd7f7d9588728a4579fab8af1722cefeb32d40Dianne Hackborn enforceWakeSourcePermission(Binder.getCallingUid(), Binder.getCallingPid()); 1369ecfd7f7d9588728a4579fab8af1722cefeb32d40Dianne Hackborn } 13707e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn if (ws == null) { 13717e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn ws = new WorkSource(Binder.getCallingUid()); 13727e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn } 13737e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn WifiLock wifiLock = new WifiLock(lockMode, tag, binder, ws); 13749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLocks) { 13759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return acquireWifiLockLocked(wifiLock); 13769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13797e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn private void noteAcquireWifiLock(WifiLock wifiLock) throws RemoteException { 13807e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn switch(wifiLock.mMode) { 13817e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn case WifiManager.WIFI_MODE_FULL: 13825876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff case WifiManager.WIFI_MODE_FULL_HIGH_PERF: 13837e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn case WifiManager.WIFI_MODE_SCAN_ONLY: 13846ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly mBatteryStats.noteFullWifiLockAcquiredFromSource(wifiLock.mWorkSource); 13857e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn break; 13867e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn } 13877e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn } 13887e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn 13897e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn private void noteReleaseWifiLock(WifiLock wifiLock) throws RemoteException { 13907e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn switch(wifiLock.mMode) { 13917e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn case WifiManager.WIFI_MODE_FULL: 13925876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff case WifiManager.WIFI_MODE_FULL_HIGH_PERF: 13937e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn case WifiManager.WIFI_MODE_SCAN_ONLY: 13946ccaa540a18a69e5343e3e4d507f341880fcde5aNick Pelly mBatteryStats.noteFullWifiLockReleasedFromSource(wifiLock.mWorkSource); 13957e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn break; 13967e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn } 13977e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn } 13987e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn 13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean acquireWifiLockLocked(WifiLock wifiLock) { 1400c89dd54ceeec99173d51d1196e2c03a58f120211Irfan Sheriff if (DBG) Slog.d(TAG, "acquireWifiLockLocked: " + wifiLock); 1401f1acb2ddcde20638d592b3cdcf61cfaf01d3df7bRobert Greenwalt 14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocks.addLock(wifiLock); 1403f1acb2ddcde20638d592b3cdcf61cfaf01d3df7bRobert Greenwalt 1404105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project long ident = Binder.clearCallingIdentity(); 1405105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project try { 14067e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn noteAcquireWifiLock(wifiLock); 14075347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt switch(wifiLock.mMode) { 14085711fadfc48f0e77bc25a91ef36c76acb0d2f55aEric Shienbrood case WifiManager.WIFI_MODE_FULL: 14095711fadfc48f0e77bc25a91ef36c76acb0d2f55aEric Shienbrood ++mFullLocksAcquired; 14105711fadfc48f0e77bc25a91ef36c76acb0d2f55aEric Shienbrood break; 14115876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff case WifiManager.WIFI_MODE_FULL_HIGH_PERF: 14125876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff ++mFullHighPerfLocksAcquired; 14135876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff break; 14145876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff 14155711fadfc48f0e77bc25a91ef36c76acb0d2f55aEric Shienbrood case WifiManager.WIFI_MODE_SCAN_ONLY: 14165711fadfc48f0e77bc25a91ef36c76acb0d2f55aEric Shienbrood ++mScanLocksAcquired; 14175711fadfc48f0e77bc25a91ef36c76acb0d2f55aEric Shienbrood break; 1418105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 1419ecfd7f7d9588728a4579fab8af1722cefeb32d40Dianne Hackborn 1420ecfd7f7d9588728a4579fab8af1722cefeb32d40Dianne Hackborn // Be aggressive about adding new locks into the accounted state... 1421ecfd7f7d9588728a4579fab8af1722cefeb32d40Dianne Hackborn // we want to over-report rather than under-report. 1422ecfd7f7d9588728a4579fab8af1722cefeb32d40Dianne Hackborn reportStartWorkSource(); 1423ecfd7f7d9588728a4579fab8af1722cefeb32d40Dianne Hackborn 1424ecfd7f7d9588728a4579fab8af1722cefeb32d40Dianne Hackborn updateWifiState(); 1425ecfd7f7d9588728a4579fab8af1722cefeb32d40Dianne Hackborn return true; 1426105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } catch (RemoteException e) { 1427ecfd7f7d9588728a4579fab8af1722cefeb32d40Dianne Hackborn return false; 1428105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } finally { 1429105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Binder.restoreCallingIdentity(ident); 1430105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14337e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn public void updateWifiLockWorkSource(IBinder lock, WorkSource ws) { 14347e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn int uid = Binder.getCallingUid(); 14357e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn int pid = Binder.getCallingPid(); 14367e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn if (ws != null && ws.size() == 0) { 14377e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn ws = null; 14387e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn } 14397e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn if (ws != null) { 14407e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn enforceWakeSourcePermission(uid, pid); 14417e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn } 14427e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn long ident = Binder.clearCallingIdentity(); 14437e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn try { 14447e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn synchronized (mLocks) { 14457e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn int index = mLocks.findLockByBinder(lock); 14467e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn if (index < 0) { 14477e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn throw new IllegalArgumentException("Wifi lock not active"); 14487e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn } 14497e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn WifiLock wl = mLocks.mList.get(index); 14507e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn noteReleaseWifiLock(wl); 14517e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn wl.mWorkSource = ws != null ? new WorkSource(ws) : new WorkSource(uid); 14527e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn noteAcquireWifiLock(wl); 14537e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn } 14547e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn } catch (RemoteException e) { 14557e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn } finally { 14567e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn Binder.restoreCallingIdentity(ident); 14577e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn } 14587e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn } 14597e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn 14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean releaseWifiLock(IBinder lock) { 14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null); 14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLocks) { 14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return releaseWifiLockLocked(lock); 14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean releaseWifiLockLocked(IBinder lock) { 1468d4c5f8919b0522bcaab41a5863c313fec52d3a79Eric Shienbrood boolean hadLock; 1469f1acb2ddcde20638d592b3cdcf61cfaf01d3df7bRobert Greenwalt 1470105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project WifiLock wifiLock = mLocks.removeLock(lock); 1471f1acb2ddcde20638d592b3cdcf61cfaf01d3df7bRobert Greenwalt 1472c89dd54ceeec99173d51d1196e2c03a58f120211Irfan Sheriff if (DBG) Slog.d(TAG, "releaseWifiLockLocked: " + wifiLock); 1473f1acb2ddcde20638d592b3cdcf61cfaf01d3df7bRobert Greenwalt 1474d4c5f8919b0522bcaab41a5863c313fec52d3a79Eric Shienbrood hadLock = (wifiLock != null); 1475d4c5f8919b0522bcaab41a5863c313fec52d3a79Eric Shienbrood 1476ecfd7f7d9588728a4579fab8af1722cefeb32d40Dianne Hackborn long ident = Binder.clearCallingIdentity(); 1477ecfd7f7d9588728a4579fab8af1722cefeb32d40Dianne Hackborn try { 1478ecfd7f7d9588728a4579fab8af1722cefeb32d40Dianne Hackborn if (hadLock) { 1479ce0ea1f2b92c0e47941f8ae777c676ff6fe50d22Wink Saville noteReleaseWifiLock(wifiLock); 14805347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt switch(wifiLock.mMode) { 14815711fadfc48f0e77bc25a91ef36c76acb0d2f55aEric Shienbrood case WifiManager.WIFI_MODE_FULL: 14825711fadfc48f0e77bc25a91ef36c76acb0d2f55aEric Shienbrood ++mFullLocksReleased; 14835711fadfc48f0e77bc25a91ef36c76acb0d2f55aEric Shienbrood break; 14845876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff case WifiManager.WIFI_MODE_FULL_HIGH_PERF: 14855876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff ++mFullHighPerfLocksReleased; 14865876a4273e67271f0eca607af9520f7e5abbe4f3Irfan Sheriff break; 14875711fadfc48f0e77bc25a91ef36c76acb0d2f55aEric Shienbrood case WifiManager.WIFI_MODE_SCAN_ONLY: 14885711fadfc48f0e77bc25a91ef36c76acb0d2f55aEric Shienbrood ++mScanLocksReleased; 14895711fadfc48f0e77bc25a91ef36c76acb0d2f55aEric Shienbrood break; 1490d4c5f8919b0522bcaab41a5863c313fec52d3a79Eric Shienbrood } 1491105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 1492ecfd7f7d9588728a4579fab8af1722cefeb32d40Dianne Hackborn 1493ecfd7f7d9588728a4579fab8af1722cefeb32d40Dianne Hackborn // TODO - should this only happen if you hadLock? 1494ecfd7f7d9588728a4579fab8af1722cefeb32d40Dianne Hackborn updateWifiState(); 1495ecfd7f7d9588728a4579fab8af1722cefeb32d40Dianne Hackborn 1496ecfd7f7d9588728a4579fab8af1722cefeb32d40Dianne Hackborn } catch (RemoteException e) { 1497ecfd7f7d9588728a4579fab8af1722cefeb32d40Dianne Hackborn } finally { 1498ecfd7f7d9588728a4579fab8af1722cefeb32d40Dianne Hackborn Binder.restoreCallingIdentity(ident); 1499105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 1500ecfd7f7d9588728a4579fab8af1722cefeb32d40Dianne Hackborn 1501d4c5f8919b0522bcaab41a5863c313fec52d3a79Eric Shienbrood return hadLock; 15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15035347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt 150458ff0217a617d5b03d18f0ef532f254f8ba6de2bRobert Greenwalt private abstract class DeathRecipient 15055347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt implements IBinder.DeathRecipient { 15065347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt String mTag; 15075347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt int mMode; 15085347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt IBinder mBinder; 15097e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn WorkSource mWorkSource; 15105347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt 15117e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn DeathRecipient(int mode, String tag, IBinder binder, WorkSource ws) { 15125347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt super(); 15135347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt mTag = tag; 15145347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt mMode = mode; 15155347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt mBinder = binder; 15167e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn mWorkSource = ws; 15175347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt try { 15185347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt mBinder.linkToDeath(this, 0); 15195347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt } catch (RemoteException e) { 15205347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt binderDied(); 15215347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt } 15225347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt } 1523fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu 1524fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu void unlinkDeathRecipient() { 1525fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu mBinder.unlinkToDeath(this, 0); 1526fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu } 15275347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt } 15285347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt 152958ff0217a617d5b03d18f0ef532f254f8ba6de2bRobert Greenwalt private class Multicaster extends DeathRecipient { 153058ff0217a617d5b03d18f0ef532f254f8ba6de2bRobert Greenwalt Multicaster(String tag, IBinder binder) { 15317e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn super(Binder.getCallingUid(), tag, binder, null); 15325347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt } 15335347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt 15345347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt public void binderDied() { 15358a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "Multicaster binderDied"); 15365347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt synchronized (mMulticasters) { 15375347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt int i = mMulticasters.indexOf(this); 15385347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt if (i != -1) { 15395347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt removeMulticasterLocked(i, mMode); 15405347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt } 15415347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt } 15425347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt } 15435347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt 15445347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt public String toString() { 154558ff0217a617d5b03d18f0ef532f254f8ba6de2bRobert Greenwalt return "Multicaster{" + mTag + " binder=" + mBinder + "}"; 15465347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt } 15475347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt 15485347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt public int getUid() { 15495347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt return mMode; 15505347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt } 15515347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt } 15525347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt 1553e2d155a51e68694e17fa6e27d05c928215a5dbcfRobert Greenwalt public void initializeMulticastFiltering() { 1554e2d155a51e68694e17fa6e27d05c928215a5dbcfRobert Greenwalt enforceMulticastChangePermission(); 1555a8fbe1fb74d3bd40b73c90c85ac25e5176475ca5Irfan Sheriff 1556e2d155a51e68694e17fa6e27d05c928215a5dbcfRobert Greenwalt synchronized (mMulticasters) { 1557e2d155a51e68694e17fa6e27d05c928215a5dbcfRobert Greenwalt // if anybody had requested filters be off, leave off 1558e2d155a51e68694e17fa6e27d05c928215a5dbcfRobert Greenwalt if (mMulticasters.size() != 0) { 1559e2d155a51e68694e17fa6e27d05c928215a5dbcfRobert Greenwalt return; 1560e2d155a51e68694e17fa6e27d05c928215a5dbcfRobert Greenwalt } else { 1561b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff mWifiStateMachine.startFilteringMulticastV4Packets(); 1562e2d155a51e68694e17fa6e27d05c928215a5dbcfRobert Greenwalt } 1563e2d155a51e68694e17fa6e27d05c928215a5dbcfRobert Greenwalt } 1564e2d155a51e68694e17fa6e27d05c928215a5dbcfRobert Greenwalt } 1565e2d155a51e68694e17fa6e27d05c928215a5dbcfRobert Greenwalt 1566fc1b15cfbfc5f69235ec1f367abd7a909381cd05Robert Greenwalt public void acquireMulticastLock(IBinder binder, String tag) { 1567fc1b15cfbfc5f69235ec1f367abd7a909381cd05Robert Greenwalt enforceMulticastChangePermission(); 15685347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt 15695347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt synchronized (mMulticasters) { 15705347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt mMulticastEnabled++; 157158ff0217a617d5b03d18f0ef532f254f8ba6de2bRobert Greenwalt mMulticasters.add(new Multicaster(tag, binder)); 1572b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff // Note that we could call stopFilteringMulticastV4Packets only when 15735347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt // our new size == 1 (first call), but this function won't 15745347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt // be called often and by making the stopPacket call each 15755347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt // time we're less fragile and self-healing. 1576b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff mWifiStateMachine.stopFilteringMulticastV4Packets(); 15775347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt } 15785347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt 15795347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt int uid = Binder.getCallingUid(); 15805347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt Long ident = Binder.clearCallingIdentity(); 15815347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt try { 15825347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt mBatteryStats.noteWifiMulticastEnabled(uid); 15835347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt } catch (RemoteException e) { 15845347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt } finally { 15855347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt Binder.restoreCallingIdentity(ident); 15865347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt } 15875347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt } 15885347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt 1589fc1b15cfbfc5f69235ec1f367abd7a909381cd05Robert Greenwalt public void releaseMulticastLock() { 1590fc1b15cfbfc5f69235ec1f367abd7a909381cd05Robert Greenwalt enforceMulticastChangePermission(); 15915347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt 15925347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt int uid = Binder.getCallingUid(); 15935347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt synchronized (mMulticasters) { 15945347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt mMulticastDisabled++; 15955347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt int size = mMulticasters.size(); 15965347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt for (int i = size - 1; i >= 0; i--) { 159758ff0217a617d5b03d18f0ef532f254f8ba6de2bRobert Greenwalt Multicaster m = mMulticasters.get(i); 15985347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt if ((m != null) && (m.getUid() == uid)) { 15995347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt removeMulticasterLocked(i, uid); 16005347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt } 16015347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt } 16025347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt } 16035347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt } 16045347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt 16055347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt private void removeMulticasterLocked(int i, int uid) 16065347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt { 1607fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu Multicaster removed = mMulticasters.remove(i); 1608a8fbe1fb74d3bd40b73c90c85ac25e5176475ca5Irfan Sheriff 1609fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu if (removed != null) { 1610fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu removed.unlinkDeathRecipient(); 1611fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu } 16125347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt if (mMulticasters.size() == 0) { 1613b0c1b80f471bd49af60e7b78161d814e355a6972Irfan Sheriff mWifiStateMachine.startFilteringMulticastV4Packets(); 16145347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt } 16155347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt 16165347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt Long ident = Binder.clearCallingIdentity(); 16175347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt try { 16185347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt mBatteryStats.noteWifiMulticastDisabled(uid); 16195347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt } catch (RemoteException e) { 16205347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt } finally { 16215347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt Binder.restoreCallingIdentity(ident); 16225347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt } 16235347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt } 16245347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt 162558ff0217a617d5b03d18f0ef532f254f8ba6de2bRobert Greenwalt public boolean isMulticastEnabled() { 16265347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt enforceAccessPermission(); 16275347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt 16285347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt synchronized (mMulticasters) { 16295347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt return (mMulticasters.size() > 0); 16305347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt } 16315347bd4cda2b6afc18f8acab48e52131f35ed13cRobert Greenwalt } 16320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 1633227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff /** 1634227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff * Evaluate if traffic stats polling is needed based on 1635227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff * connection and screen on status 1636227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff */ 1637227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff private void evaluateTrafficStatsPolling() { 1638227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff Message msg; 1639227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff if (mNetworkInfo.getDetailedState() == DetailedState.CONNECTED && !mScreenOff) { 1640ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff msg = Message.obtain(mAsyncServiceHandler, 1641d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff WifiManager.ENABLE_TRAFFIC_STATS_POLL, 1, 0); 1642227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff } else { 1643ebe606fccd9293674273d5f73246e0e8e6e6ddcfIrfan Sheriff msg = Message.obtain(mAsyncServiceHandler, 1644d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff WifiManager.ENABLE_TRAFFIC_STATS_POLL, 0, 0); 1645227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff } 1646227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff msg.sendToTarget(); 1647227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff } 1648227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff 1649227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff private void notifyOnDataActivity() { 1650227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff long sent, received; 1651227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff long preTxPkts = mTxPkts, preRxPkts = mRxPkts; 1652227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff int dataActivity = WifiManager.DATA_ACTIVITY_NONE; 1653227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff 1654227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff mTxPkts = TrafficStats.getTxPackets(mInterfaceName); 1655227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff mRxPkts = TrafficStats.getRxPackets(mInterfaceName); 1656227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff 1657227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff if (preTxPkts > 0 || preRxPkts > 0) { 1658227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff sent = mTxPkts - preTxPkts; 1659227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff received = mRxPkts - preRxPkts; 1660227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff if (sent > 0) { 1661227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff dataActivity |= WifiManager.DATA_ACTIVITY_OUT; 1662227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff } 1663227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff if (received > 0) { 1664227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff dataActivity |= WifiManager.DATA_ACTIVITY_IN; 1665227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff } 1666227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff 1667227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff if (dataActivity != mDataActivity && !mScreenOff) { 1668227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff mDataActivity = dataActivity; 1669227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff for (AsyncChannel client : mClients) { 1670227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff client.sendMessage(WifiManager.DATA_ACTIVITY_NOTIFICATION, mDataActivity); 1671227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff } 1672227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff } 1673227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff } 1674227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff } 1675227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff 1676227bec49157bc496f7c9e8e8f63c12728a448922Irfan Sheriff 16770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff private void checkAndSetNotification() { 16780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff // If we shouldn't place a notification on available networks, then 16790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff // don't bother doing any of the following 16800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff if (!mNotificationEnabled) return; 16810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 16820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff State state = mNetworkInfo.getState(); 16830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff if ((state == NetworkInfo.State.DISCONNECTED) 16840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff || (state == NetworkInfo.State.UNKNOWN)) { 16850d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff // Look for an open network 1686d8134ff9d8178470116108bb7815fd0ab2a606a1Irfan Sheriff List<ScanResult> scanResults = mWifiStateMachine.syncGetScanResultsList(); 16870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff if (scanResults != null) { 16880d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff int numOpenNetworks = 0; 16890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff for (int i = scanResults.size() - 1; i >= 0; i--) { 16900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff ScanResult scanResult = scanResults.get(i); 16910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 1692fdd5f95a817820c8e3e240718c6ef2f0d0d96613Irfan Sheriff //A capability of [ESS] represents an open access point 1693fdd5f95a817820c8e3e240718c6ef2f0d0d96613Irfan Sheriff //that is available for an STA to connect 1694fdd5f95a817820c8e3e240718c6ef2f0d0d96613Irfan Sheriff if (scanResult.capabilities != null && 1695fdd5f95a817820c8e3e240718c6ef2f0d0d96613Irfan Sheriff scanResult.capabilities.equals("[ESS]")) { 16960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff numOpenNetworks++; 16970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff } 16980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff } 16990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 17000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff if (numOpenNetworks > 0) { 17010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff if (++mNumScansSinceNetworkStateChange >= NUM_SCANS_BEFORE_ACTUALLY_SCANNING) { 17020d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff /* 17030d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * We've scanned continuously at least 17040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * NUM_SCANS_BEFORE_NOTIFICATION times. The user 17050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * probably does not have a remembered network in range, 17060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * since otherwise supplicant would have tried to 17070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * associate and thus resetting this counter. 17080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */ 17090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff setNotificationVisible(true, numOpenNetworks, false, 0); 17100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff } 17110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff return; 17120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff } 17130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff } 17140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff } 17150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 17160d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff // No open networks in range, remove the notification 17170d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff setNotificationVisible(false, 0, false, 0); 17180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff } 17190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 17200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff /** 17210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Clears variables related to tracking whether a notification has been 17220d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * shown recently and clears the current notification. 17230d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */ 17240d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff private void resetNotification() { 17250d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff mNotificationRepeatTime = 0; 17260d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff mNumScansSinceNetworkStateChange = 0; 17270d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff setNotificationVisible(false, 0, false, 0); 17280d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff } 17290d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 17300d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff /** 17310d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * Display or don't display a notification that there are open Wi-Fi networks. 17320d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * @param visible {@code true} if notification should be visible, {@code false} otherwise 17330d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * @param numNetworks the number networks seen 17340d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * @param force {@code true} to force notification to be shown/not-shown, 17350d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * even if it is already shown/not-shown. 17360d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * @param delay time in milliseconds after which the notification should be made 17370d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff * visible or invisible. 17380d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff */ 17390d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff private void setNotificationVisible(boolean visible, int numNetworks, boolean force, 17400d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff int delay) { 17410d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 17420d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff // Since we use auto cancel on the notification, when the 17430d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff // mNetworksAvailableNotificationShown is true, the notification may 17440d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff // have actually been canceled. However, when it is false we know 17450d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff // for sure that it is not being shown (it will not be shown any other 17460d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff // place than here) 17470d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 17480d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff // If it should be hidden and it is already hidden, then noop 17490d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff if (!visible && !mNotificationShown && !force) { 17500d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff return; 17510d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff } 17520d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 17530d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff NotificationManager notificationManager = (NotificationManager) mContext 17540d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff .getSystemService(Context.NOTIFICATION_SERVICE); 17550d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 17560d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff Message message; 17570d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff if (visible) { 17580d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 17590d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff // Not enough time has passed to show the notification again 17600d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff if (System.currentTimeMillis() < mNotificationRepeatTime) { 17610d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff return; 17620d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff } 17630d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 17640d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff if (mNotification == null) { 1765c7a98341b053bd8090accca151e8f3522f2dd126Wink Saville // Cache the Notification object. 17660d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff mNotification = new Notification(); 17670d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff mNotification.when = 0; 17680d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff mNotification.icon = ICON_NETWORKS_AVAILABLE; 17690d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff mNotification.flags = Notification.FLAG_AUTO_CANCEL; 1770d56b4d1db34bd6928f599e7e9a7321c2a81cb995Adam Powell mNotification.contentIntent = TaskStackBuilder.create(mContext) 1771d56b4d1db34bd6928f599e7e9a7321c2a81cb995Adam Powell .addNextIntentWithParentStack( 1772d56b4d1db34bd6928f599e7e9a7321c2a81cb995Adam Powell new Intent(WifiManager.ACTION_PICK_WIFI_NETWORK)) 1773d56b4d1db34bd6928f599e7e9a7321c2a81cb995Adam Powell .getPendingIntent(0, 0, null, UserHandle.CURRENT); 17740d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff } 17750d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 17760d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff CharSequence title = mContext.getResources().getQuantityText( 17770d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff com.android.internal.R.plurals.wifi_available, numNetworks); 17780d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff CharSequence details = mContext.getResources().getQuantityText( 17790d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff com.android.internal.R.plurals.wifi_available_detailed, numNetworks); 17800d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff mNotification.tickerText = title; 17810d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff mNotification.setLatestEventInfo(mContext, title, details, mNotification.contentIntent); 17820d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 17830d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff mNotificationRepeatTime = System.currentTimeMillis() + NOTIFICATION_REPEAT_DELAY_MS; 17840d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 178550cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn notificationManager.notifyAsUser(null, ICON_NETWORKS_AVAILABLE, mNotification, 178650cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn UserHandle.ALL); 17870d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff } else { 178850cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn notificationManager.cancelAsUser(null, ICON_NETWORKS_AVAILABLE, UserHandle.ALL); 17890d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff } 17900d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 17910d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff mNotificationShown = visible; 17920d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff } 17930d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 17940d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff private class NotificationEnabledSettingObserver extends ContentObserver { 17950d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 17960d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff public NotificationEnabledSettingObserver(Handler handler) { 17970d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff super(handler); 17980d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff } 17990d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 18000d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff public void register() { 18010d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff ContentResolver cr = mContext.getContentResolver(); 18026f5a9a96523ecf97a9828a410dd1226df47ec4e6Christopher Tate cr.registerContentObserver(Settings.Global.getUriFor( 18036f5a9a96523ecf97a9828a410dd1226df47ec4e6Christopher Tate Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON), true, this); 18040d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff mNotificationEnabled = getValue(); 18050d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff } 18060d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 18070d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff @Override 18080d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff public void onChange(boolean selfChange) { 18090d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff super.onChange(selfChange); 18100d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 18110d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff mNotificationEnabled = getValue(); 18120d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff resetNotification(); 18130d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff } 18140d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 18150d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff private boolean getValue() { 18166f5a9a96523ecf97a9828a410dd1226df47ec4e6Christopher Tate return Settings.Global.getInt(mContext.getContentResolver(), 18176f5a9a96523ecf97a9828a410dd1226df47ec4e6Christopher Tate Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 1) == 1; 18180d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff } 18190d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff } 18200d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 18210d25534fed91f636def5776ddc4605005bd7471cIrfan Sheriff 18229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1823