diff options
5 files changed, 185 insertions, 4 deletions
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java index 55670e2f1..82a0be697 100644 --- a/service/java/com/android/server/wifi/WifiInjector.java +++ b/service/java/com/android/server/wifi/WifiInjector.java @@ -25,6 +25,7 @@ import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiNetworkScoreCache; import android.net.wifi.WifiScanner; +import android.os.BatteryStats; import android.os.HandlerThread; import android.os.IBinder; import android.os.INetworkManagementService; @@ -38,6 +39,7 @@ import android.telephony.TelephonyManager; import android.util.LocalLog; import com.android.internal.R; +import com.android.internal.app.IBatteryStats; import com.android.server.am.BatteryStatsService; import com.android.server.net.DelayedDiskWrite; import com.android.server.net.IpConfigStore; @@ -108,6 +110,8 @@ public class WifiInjector { private final SIMAccessor mSimAccessor; private HandlerThread mWifiAwareHandlerThread; private HalDeviceManager mHalDeviceManager; + private final IBatteryStats mBatteryStats; + private final WifiStateTracker mWifiStateTracker; private final boolean mUseRealLogger; @@ -132,7 +136,9 @@ public class WifiInjector { mNetworkScoreManager = mContext.getSystemService(NetworkScoreManager.class); mWifiPermissionsUtil = new WifiPermissionsUtil(mWifiPermissionsWrapper, mContext, mSettingsStore, UserManager.get(mContext), mNetworkScoreManager, this); - + mBatteryStats = IBatteryStats.Stub.asInterface(mFrameworkFacade.getService( + BatteryStats.SERVICE_NAME)); + mWifiStateTracker = new WifiStateTracker(mBatteryStats); // Now create and start handler threads mWifiServiceHandlerThread = new HandlerThread("WifiService"); mWifiServiceHandlerThread.start(); @@ -326,6 +332,10 @@ public class WifiInjector { return (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); } + public WifiStateTracker getWifiStateTracker() { + return mWifiStateTracker; + } + public IWificond makeWificond() { // We depend on being able to refresh our binder in WifiStateMachine, so don't cache it. IBinder binder = ServiceManager.getService(WIFICOND_SERVICE_NAME); diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index 8fa52b38c..fa4fc80b7 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -848,7 +848,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss private static int sScanAlarmIntentCount = 0; private FrameworkFacade mFacade; - + private WifiStateTracker mWifiStateTracker; private final BackupManagerProxy mBackupManagerProxy; public WifiStateMachine(Context context, FrameworkFacade facade, Looper looper, @@ -872,7 +872,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, NETWORKTYPE, ""); mBatteryStats = IBatteryStats.Stub.asInterface(mFacade.getService( BatteryStats.SERVICE_NAME)); - + mWifiStateTracker = wifiInjector.getWifiStateTracker(); IBinder b = mFacade.getService(Context.NETWORKMANAGEMENT_SERVICE); mNwService = INetworkManagementService.Stub.asInterface(b); @@ -3930,6 +3930,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss @Override public void enter() { + mWifiStateTracker.updateState(WifiStateTracker.INVALID); cleanup(); } @@ -4149,7 +4150,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss setWifiState(WIFI_STATE_DISABLED); } transitionTo(mScanModeState); - } else if (mOperationalMode == CONNECT_MODE){ + } else if (mOperationalMode == CONNECT_MODE) { // Status pulls in the current supplicant state and network connection state // events over the monitor connection. This helps framework sync up with @@ -4450,6 +4451,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss @Override public void enter() { mLastOperationMode = mOperationalMode; + mWifiStateTracker.updateState(WifiStateTracker.SCAN_MODE); } @Override public boolean processMessage(Message message) { @@ -6048,6 +6050,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss mLastDriverRoamAttempt = 0; mTargetNetworkId = WifiConfiguration.INVALID_NETWORK_ID; mWifiInjector.getWifiLastResortWatchdog().connectedStateTransition(true); + mWifiStateTracker.updateState(WifiStateTracker.CONNECTED); } @Override public boolean processMessage(Message message) { @@ -6341,6 +6344,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss } mDisconnectedTimeStamp = mClock.getWallClockMillis(); + mWifiStateTracker.updateState(WifiStateTracker.DISCONNECTED); } @Override public boolean processMessage(Message message) { @@ -6607,6 +6611,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss apInterface, config); mSoftApManager.start(); + mWifiStateTracker.updateState(WifiStateTracker.SOFT_AP); } @Override diff --git a/service/java/com/android/server/wifi/WifiStateTracker.java b/service/java/com/android/server/wifi/WifiStateTracker.java new file mode 100644 index 000000000..317aa262a --- /dev/null +++ b/service/java/com/android/server/wifi/WifiStateTracker.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.wifi; + +import android.os.BatteryStats; +import android.os.RemoteException; +import android.util.Log; + +import com.android.internal.app.IBatteryStats; + +/** + * This class is used to track WifiState to update BatteryStats + */ +public class WifiStateTracker { + private static final String TAG = "WifiStateTracker"; + + public static final int INVALID = 0; + public static final int SCAN_MODE = 1; + public static final int DISCONNECTED = 2; + public static final int CONNECTED = 3; + public static final int SOFT_AP = 4; + private int mWifiState; + private IBatteryStats mBatteryStats; + + public WifiStateTracker(IBatteryStats stats) { + mWifiState = INVALID; + mBatteryStats = stats; + } + + private void informWifiStateBatteryStats(int state) { + try { + mBatteryStats.noteWifiState(state, null); + } catch (RemoteException e) { + Log.e(TAG, "Battery stats unreachable " + e.getMessage()); + } + } + + /** + * Inform the WifiState to this tracker to translate into the + * WifiState corresponding to BatteryStats. + * @param state state corresponding to the WifiStateMachine state + */ + public void updateState(int state) { + int reportState = BatteryStats.WIFI_STATE_OFF; + if (state != mWifiState) { + switch(state) { + case SCAN_MODE: + reportState = BatteryStats.WIFI_STATE_OFF_SCANNING; + break; + case DISCONNECTED: + reportState = BatteryStats.WIFI_STATE_ON_DISCONNECTED; + break; + case CONNECTED: + reportState = BatteryStats.WIFI_STATE_ON_CONNECTED_STA; + break; + case SOFT_AP: + reportState = BatteryStats.WIFI_STATE_SOFT_AP; + break; + case INVALID: + mWifiState = INVALID; + /* Fall through */ + default: + return; + } + mWifiState = state; + informWifiStateBatteryStats(reportState); + } + return; + } +} diff --git a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java index 91862296e..06fa43094 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java @@ -323,6 +323,7 @@ public class WifiStateMachineTest { @Mock WifiNative mWifiNative; @Mock WifiConnectivityManager mWifiConnectivityManager; @Mock SoftApManager mSoftApManager; + @Mock WifiStateTracker mWifiStateTracker; public WifiStateMachineTest() throws Exception { } @@ -362,6 +363,7 @@ public class WifiStateMachineTest { when(mWifiNative.setupDriverForClientMode()).thenReturn(mClientInterface); when(mWifiNative.setupDriverForSoftApMode()).thenReturn(mApInterface); + when(mWifiInjector.getWifiStateTracker()).thenReturn(mWifiStateTracker); when(mWifiNative.getInterfaceName()).thenReturn("mockWlan"); when(mWifiNative.enableSupplicant()).thenReturn(true); when(mWifiNative.disableSupplicant()).thenReturn(true); diff --git a/tests/wifitests/src/com/android/server/wifi/WifiStateTrackerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiStateTrackerTest.java new file mode 100644 index 000000000..428364dbe --- /dev/null +++ b/tests/wifitests/src/com/android/server/wifi/WifiStateTrackerTest.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.wifi; + +import com.android.internal.app.IBatteryStats; + +import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.anyString; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import android.test.suitebuilder.annotation.SmallTest; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/* + * Unit tests for {@link com.android.server.wifi.WifiStateTracker}. + */ +@SmallTest +public class WifiStateTrackerTest { + + private static final String TAG = "WifiStateTrackerTest"; + @Mock IBatteryStats mBatteryStats; + private WifiStateTracker mWifiStateTracker; + + /** + * Setup test. + */ + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mWifiStateTracker = new WifiStateTracker(mBatteryStats); + } + + /** + * Ensure BatteryStats's noteWifiState() is called when the method + * updateState() is invoked on WifiStateTracker for relevant states. + */ + @Test + public void testBatteryStatsUpdated() throws Exception { + int[] relevantStates = new int[] { WifiStateTracker.SCAN_MODE, + WifiStateTracker.CONNECTED, WifiStateTracker.DISCONNECTED, + WifiStateTracker.SOFT_AP}; + for (int i = 0; i < relevantStates.length; i++) { + mWifiStateTracker.updateState(relevantStates[i]); + } + verify(mBatteryStats, times(relevantStates.length)).noteWifiState(anyInt(), anyString()); + } + + /** + * Ensure BatteryStats's noteWifiState() is not called when the method + * updateState() is invoked on WifiStateTracker for irrelevant states. + */ + @Test + public void testBatteryStatsNotUpdated() throws Exception { + int[] irrelevantStates = new int[] { WifiStateTracker.SCAN_MODE - 1, + WifiStateTracker.SOFT_AP + 1}; + for (int i = 0; i < irrelevantStates.length; i++) { + mWifiStateTracker.updateState(irrelevantStates[i]); + } + verify(mBatteryStats, times(0)).noteWifiState(anyInt(), anyString()); + } +} |