summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEtan Cohen <etancohen@google.com>2017-05-11 23:38:14 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2017-05-11 23:38:16 +0000
commit2b8d172f337298ac1da2f9a69662474529e11bc1 (patch)
tree1fd29a888d4f751350a70ca263ecbb69bb0caddc
parent813bba29bf7d48c1d829841457cf27365e0aaa68 (diff)
parentc760a66378bbd844eb421658799b4d55c76b98fa (diff)
Merge "[AWARE] Initial power optimization framework - hooks & config"
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareNativeApi.java110
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareNativeManager.java13
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareService.java5
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareServiceImpl.java8
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareShellCommand.java60
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareStateManager.java158
-rw-r--r--tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java21
-rw-r--r--tests/wifitests/src/com/android/server/wifi/aware/WifiAwareNativeApiTest.java218
-rw-r--r--tests/wifitests/src/com/android/server/wifi/aware/WifiAwareServiceImplTest.java4
-rw-r--r--tests/wifitests/src/com/android/server/wifi/aware/WifiAwareStateManagerTest.java268
10 files changed, 797 insertions, 68 deletions
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareNativeApi.java b/service/java/com/android/server/wifi/aware/WifiAwareNativeApi.java
index 9395e6a5d..14ce22fb2 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareNativeApi.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareNativeApi.java
@@ -36,6 +36,7 @@ import android.net.wifi.aware.ConfigRequest;
import android.net.wifi.aware.PublishConfig;
import android.net.wifi.aware.SubscribeConfig;
import android.os.RemoteException;
+import android.os.ShellCommand;
import android.util.Log;
import libcore.util.HexEncoding;
@@ -44,13 +45,15 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
/**
* Translates Wi-Fi Aware requests from the framework to the HAL (HIDL).
*
* Delegates the management of the NAN interface to WifiAwareNativeManager.
*/
-public class WifiAwareNativeApi {
+public class WifiAwareNativeApi implements WifiAwareShellCommand.DelegatedShellCommand {
private static final String TAG = "WifiAwareNativeApi";
private static final boolean DBG = false;
private static final boolean VDBG = false; // STOPSHIP if true
@@ -63,6 +66,70 @@ public class WifiAwareNativeApi {
mHal = wifiAwareNativeManager;
}
+ /*
+ * Parameters settable through the shell command.
+ */
+ public static final String PARAM_DW_ON_INACTIVE_24GHZ = "dw_on_inactive_24ghz";
+ public static final String PARAM_DW_ON_INACTIVE_5GHZ = "dw_on_inactive_5ghz";
+ public static final String PARAM_DW_ON_IDLE_24GHZ = "dw_on_idle_24ghz";
+ public static final String PARAM_DW_ON_IDLE_5GHZ = "dw_on_idle_5ghz";
+
+ private Map<String, Integer> mSettableParameters = new HashMap<>();
+ {
+ mSettableParameters.put(PARAM_DW_ON_INACTIVE_24GHZ, -1); // -1 mean no-op, don't override
+ mSettableParameters.put(PARAM_DW_ON_INACTIVE_5GHZ, -1); // -1 mean no-op, don't override
+ mSettableParameters.put(PARAM_DW_ON_IDLE_24GHZ, -1); // -1 mean no-op, don't override
+ mSettableParameters.put(PARAM_DW_ON_IDLE_5GHZ, -1); // -1 mean no-op, don't override
+ }
+
+ /**
+ * Interpreter of adb shell command 'adb shell wifiaware native_api ...'.
+ *
+ * @return -1 if parameter not recognized or invalid value, 0 otherwise.
+ */
+ @Override
+ public int onCommand(ShellCommand parentShell) {
+ final PrintWriter pw = parentShell.getErrPrintWriter();
+
+ String subCmd = parentShell.getNextArgRequired();
+ if (VDBG) Log.v(TAG, "onCommand: subCmd='" + subCmd + "'");
+ switch (subCmd) {
+ case "set": {
+ String name = parentShell.getNextArgRequired();
+ if (VDBG) Log.v(TAG, "onCommand: name='" + name + "'");
+ if (!mSettableParameters.containsKey(name)) {
+ pw.println("Unknown parameter name -- '" + name + "'");
+ return -1;
+ }
+
+ String valueStr = parentShell.getNextArgRequired();
+ if (VDBG) Log.v(TAG, "onCommand: valueStr='" + valueStr + "'");
+ int value;
+ try {
+ value = Integer.valueOf(valueStr);
+ } catch (NumberFormatException e) {
+ pw.println("Can't convert value to integer -- '" + valueStr + "'");
+ return -1;
+ }
+ mSettableParameters.put(name, value);
+ return 0;
+ }
+ default:
+ pw.println("Unknown 'wifiaware native_api <cmd>'");
+ }
+
+ return -1;
+ }
+
+ @Override
+ public void onHelp(String command, ShellCommand parentShell) {
+ final PrintWriter pw = parentShell.getOutPrintWriter();
+
+ pw.println(" " + command);
+ pw.println(" set <name> <value>: sets named parameter to value. Names: "
+ + mSettableParameters.keySet());
+ }
+
/**
* Query the firmware's capabilities.
*
@@ -101,13 +168,17 @@ public class WifiAwareNativeApi {
* @param notifyIdentityChange Indicates whether or not to get address change callbacks.
* @param initialConfiguration Specifies whether initial configuration
* (true) or an update (false) to the configuration.
+ * @param isInteractive PowerManager.isInteractive
+ * @param isIdle PowerManager.isIdle
*/
public boolean enableAndConfigure(short transactionId, ConfigRequest configRequest,
- boolean notifyIdentityChange, boolean initialConfiguration) {
+ boolean notifyIdentityChange, boolean initialConfiguration, boolean isInteractive,
+ boolean isIdle) {
if (VDBG) {
Log.v(TAG, "enableAndConfigure: transactionId=" + transactionId + ", configRequest="
+ configRequest + ", notifyIdentityChange=" + notifyIdentityChange
- + ", initialConfiguration=" + initialConfiguration);
+ + ", initialConfiguration=" + initialConfiguration
+ + ", isInteractive=" + isInteractive + ", isIdle=" + isIdle);
}
IWifiNanIface iface = mHal.getWifiNanIface();
@@ -190,6 +261,8 @@ public class WifiAwareNativeApi {
req.debugConfigs.useSdfInBandVal[NanBandIndex.NAN_BAND_24GHZ] = true;
req.debugConfigs.useSdfInBandVal[NanBandIndex.NAN_BAND_5GHZ] = true;
+ updateConfigForPowerSettings(req.configParams, isInteractive, isIdle);
+
status = iface.enableRequest(transactionId, req);
} else {
NanConfigRequest req = new NanConfigRequest();
@@ -238,6 +311,8 @@ public class WifiAwareNativeApi {
}
req.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ] = config5;
+ updateConfigForPowerSettings(req, isInteractive, isIdle);
+
status = iface.configRequest(transactionId, req);
}
if (status.code == WifiStatusCode.SUCCESS) {
@@ -767,6 +842,33 @@ public class WifiAwareNativeApi {
// utilities
/**
+ * Update the NAN configuration to reflect the current power settings.
+ */
+ private void updateConfigForPowerSettings(NanConfigRequest req, boolean isInteractive,
+ boolean isIdle) {
+ if (isIdle) { // lowest power state: doze
+ updateSingleConigForPowerSettings(req.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ],
+ mSettableParameters.get(PARAM_DW_ON_IDLE_5GHZ));
+ updateSingleConigForPowerSettings(req.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ],
+ mSettableParameters.get(PARAM_DW_ON_IDLE_24GHZ));
+ } else if (!isInteractive) { // intermediate power state: inactive
+ updateSingleConigForPowerSettings(req.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ],
+ mSettableParameters.get(PARAM_DW_ON_INACTIVE_5GHZ));
+ updateSingleConigForPowerSettings(req.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ],
+ mSettableParameters.get(PARAM_DW_ON_INACTIVE_24GHZ));
+ }
+
+ // else do nothing - normal power state
+ }
+
+ private void updateSingleConigForPowerSettings(NanBandSpecificConfig cfg, int override) {
+ if (override != -1) {
+ cfg.validDiscoveryWindowIntervalVal = true;
+ cfg.discoveryWindowIntervalVal = (byte) override;
+ }
+ }
+
+ /**
* Returns the strongest supported cipher suite.
*
* Baseline is very simple: 256 > 128 > 0.
@@ -829,6 +931,8 @@ public class WifiAwareNativeApi {
* Dump the internal state of the class.
*/
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.println("WifiAwareNativeApi:");
+ pw.println(" mSettableParameters: " + mSettableParameters);
mHal.dump(fd, pw, args);
}
}
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareNativeManager.java b/service/java/com/android/server/wifi/aware/WifiAwareNativeManager.java
index f1945808f..9d2f3d062 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareNativeManager.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareNativeManager.java
@@ -23,6 +23,7 @@ import android.hardware.wifi.V1_0.WifiStatusCode;
import android.os.RemoteException;
import android.util.Log;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.server.wifi.HalDeviceManager;
import java.io.FileDescriptor;
@@ -31,7 +32,7 @@ import java.io.PrintWriter;
/**
* Manages the interface to Wi-Fi Aware HIDL (HAL).
*/
-class WifiAwareNativeManager {
+public class WifiAwareNativeManager {
private static final String TAG = "WifiAwareNativeManager";
private static final boolean DBG = false;
@@ -78,12 +79,20 @@ class WifiAwareNativeManager {
}
}
- /* package */ IWifiNanIface getWifiNanIface() {
+ /**
+ * Returns the native HAL WifiNanIface through which commands to the NAN HAL are dispatched.
+ * Return may be null if not initialized/available.
+ */
+ @VisibleForTesting
+ public IWifiNanIface getWifiNanIface() {
synchronized (mLock) {
return mWifiNanIface;
}
}
+ /**
+ * Attempt to obtain the HAL NAN interface. If available then enables Aware usage.
+ */
private void tryToGetAware() {
synchronized (mLock) {
if (DBG) Log.d(TAG, "tryToGetAware: mWifiNanIface=" + mWifiNanIface);
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareService.java b/service/java/com/android/server/wifi/aware/WifiAwareService.java
index bd8156e17..6aceb6adc 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareService.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareService.java
@@ -62,9 +62,12 @@ public final class WifiAwareService extends SystemService {
wifiAwareStateManager, halDeviceManager, wifiAwareNativeCallback);
WifiAwareNativeApi wifiAwareNativeApi = new WifiAwareNativeApi(wifiAwareNativeManager);
wifiAwareStateManager.setNative(wifiAwareNativeApi);
+ WifiAwareShellCommand wifiAwareShellCommand = new WifiAwareShellCommand();
+ wifiAwareShellCommand.register("native_api", wifiAwareNativeApi);
+ wifiAwareShellCommand.register("state_mgr", wifiAwareStateManager);
HandlerThread awareHandlerThread = wifiInjector.getWifiAwareHandlerThread();
- mImpl.start(awareHandlerThread, wifiAwareStateManager);
+ mImpl.start(awareHandlerThread, wifiAwareStateManager, wifiAwareShellCommand);
wifiAwareNativeManager.start();
} else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
mImpl.startLate();
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareServiceImpl.java b/service/java/com/android/server/wifi/aware/WifiAwareServiceImpl.java
index 49e3bb9a7..74898bf69 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareServiceImpl.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareServiceImpl.java
@@ -55,6 +55,7 @@ public class WifiAwareServiceImpl extends IWifiAwareManager.Stub {
private Context mContext;
private WifiAwareStateManager mStateManager;
+ private WifiAwareShellCommand mShellCommand;
private final Object mLock = new Object();
private final SparseArray<IBinder.DeathRecipient> mDeathRecipientsByClientId =
@@ -79,10 +80,12 @@ public class WifiAwareServiceImpl extends IWifiAwareManager.Stub {
* Start the service: allocate a new thread (for now), start the handlers of
* the components of the service.
*/
- public void start(HandlerThread handlerThread, WifiAwareStateManager awareStateManager) {
+ public void start(HandlerThread handlerThread, WifiAwareStateManager awareStateManager,
+ WifiAwareShellCommand awareShellCommand) {
Log.i(TAG, "Starting Wi-Fi Aware service");
mStateManager = awareStateManager;
+ mShellCommand = awareShellCommand;
mStateManager.start(mContext, handlerThread.getLooper());
}
@@ -375,8 +378,7 @@ public class WifiAwareServiceImpl extends IWifiAwareManager.Stub {
@Override
public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
- (new WifiAwareShellCommand(mStateManager)).exec(this, in, out, err, args, callback,
- resultReceiver);
+ mShellCommand.exec(this, in, out, err, args, callback, resultReceiver);
}
@Override
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareShellCommand.java b/service/java/com/android/server/wifi/aware/WifiAwareShellCommand.java
index de8bfa73b..46b08634b 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareShellCommand.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareShellCommand.java
@@ -16,34 +16,50 @@
package com.android.server.wifi.aware;
-import android.app.AppGlobals;
-import android.content.pm.IPackageManager;
import android.os.Binder;
import android.os.ShellCommand;
+import android.text.TextUtils;
+import android.util.Log;
import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.Map;
/**
* Interprets and executes 'adb shell cmd wifiaware [args]'.
*/
public class WifiAwareShellCommand extends ShellCommand {
- private final WifiAwareStateManager mStateManager;
- private final IPackageManager mPM;
+ private static final String TAG = "WifiAwareShellCommand";
- WifiAwareShellCommand(WifiAwareStateManager stateManager) {
- mStateManager = stateManager;
- mPM = AppGlobals.getPackageManager();
+ private Map<String, DelegatedShellCommand> mDelegatedCommands = new HashMap<>();
+
+ /**
+ * Register an delegated command interpreter for the specified 'command'. Each class can
+ * interpret and execute their own commands.
+ */
+ public void register(String command, DelegatedShellCommand shellCommand) {
+ if (mDelegatedCommands.containsKey(command)) {
+ Log.e(TAG, "register: overwriting existing command -- '" + command + "'");
+ }
+
+ mDelegatedCommands.put(command, shellCommand);
}
@Override
public int onCommand(String cmd) {
checkRootPermission();
- final PrintWriter pw = getOutPrintWriter();
+ final PrintWriter pw = getErrPrintWriter();
try {
- switch (cmd != null ? cmd : "") {
- default:
- return handleDefaultCommands(cmd);
+ DelegatedShellCommand delegatedCmd = null;
+ if (!TextUtils.isEmpty(cmd)) {
+ delegatedCmd = mDelegatedCommands.get(cmd);
+ }
+
+ if (delegatedCmd != null) {
+ return delegatedCmd.onCommand(this);
+ } else {
+ return handleDefaultCommands(cmd);
}
} catch (Exception e) {
pw.println("Exception: " + e);
@@ -67,6 +83,28 @@ public class WifiAwareShellCommand extends ShellCommand {
pw.println("Wi-Fi Aware (wifiaware) commands:");
pw.println(" help");
pw.println(" Print this help text.");
+ for (Map.Entry<String, DelegatedShellCommand> sce: mDelegatedCommands.entrySet()) {
+ sce.getValue().onHelp(sce.getKey(), this);
+ }
pw.println();
}
+
+ /**
+ * Interface that delegated command targets must implement. They are passed the parent shell
+ * command (the real command interpreter) from which they can obtain arguments.
+ */
+ public interface DelegatedShellCommand {
+ /**
+ * Execute the specified command. Use the parent shell to obtain arguments. Note that the
+ * first argument (which specified the delegated shell) has already been extracted.
+ */
+ int onCommand(ShellCommand parentShell);
+
+ /**
+ * Print out help for the delegated command. The name of the delegated command is passed
+ * as a first argument as an assist (prevents hard-coding of that string in multiple
+ * places).
+ */
+ void onHelp(String command, ShellCommand parentShell);
+ }
}
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java b/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
index f3b7be4b1..c2f6a79ed 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
@@ -16,8 +16,10 @@
package com.android.server.wifi.aware;
+import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.hardware.wifi.V1_0.NanStatusType;
import android.net.wifi.RttManager;
import android.net.wifi.aware.Characteristics;
@@ -31,7 +33,9 @@ import android.net.wifi.aware.WifiAwareNetworkSpecifier;
import android.os.Bundle;
import android.os.Looper;
import android.os.Message;
+import android.os.PowerManager;
import android.os.RemoteException;
+import android.os.ShellCommand;
import android.os.SystemClock;
import android.os.UserHandle;
import android.util.ArrayMap;
@@ -50,6 +54,7 @@ import libcore.util.HexEncoding;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -57,7 +62,7 @@ import java.util.Map;
/**
* Manages the state of the Wi-Fi Aware system service.
*/
-public class WifiAwareStateManager {
+public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShellCommand {
private static final String TAG = "WifiAwareStateManager";
private static final boolean DBG = false;
private static final boolean VDBG = false; // STOPSHIP if true
@@ -108,6 +113,7 @@ public class WifiAwareStateManager {
private static final int COMMAND_TYPE_RESPOND_TO_DATA_PATH_SETUP_REQUEST = 117;
private static final int COMMAND_TYPE_END_DATA_PATH = 118;
private static final int COMMAND_TYPE_TRANSMIT_NEXT_MESSAGE = 119;
+ private static final int COMMAND_TYPE_RECONFIGURE = 120;
private static final int RESPONSE_TYPE_ON_CONFIG_SUCCESS = 200;
private static final int RESPONSE_TYPE_ON_CONFIG_FAIL = 201;
@@ -190,6 +196,7 @@ public class WifiAwareStateManager {
private WifiAwareStateMachine mSm;
private WifiAwareRttStateManager mRtt;
private WifiAwareDataPathStateManager mDataPathMgr;
+ private PowerManager mPowerManager;
private final SparseArray<WifiAwareClientState> mClients = new SparseArray<>();
private ConfigRequest mCurrentAwareConfiguration = null;
@@ -202,10 +209,72 @@ public class WifiAwareStateManager {
// empty
}
+ /**
+ * Inject references to other manager objects. Needed to resolve
+ * circular dependencies and to allow mocking.
+ */
public void setNative(WifiAwareNativeApi wifiAwareNativeApi) {
mWifiAwareNativeApi = wifiAwareNativeApi;
}
+ /*
+ * parameters settable through shell command
+ */
+ public static final String PARAM_ON_IDLE_DISABLE_AWARE = "on_idle_disable_aware";
+
+ private Map<String, Integer> mSettableParameters = new HashMap<>();
+ {
+ mSettableParameters.put(PARAM_ON_IDLE_DISABLE_AWARE, 0); // 0 = false
+ }
+
+ /**
+ * Interpreter of adb shell command 'adb shell wifiaware native_api ...'.
+ *
+ * @return -1 if parameter not recognized or invalid value, 0 otherwise.
+ */
+ @Override
+ public int onCommand(ShellCommand parentShell) {
+ final PrintWriter pw = parentShell.getErrPrintWriter();
+
+ String subCmd = parentShell.getNextArgRequired();
+ if (VDBG) Log.v(TAG, "onCommand: subCmd='" + subCmd + "'");
+ switch (subCmd) {
+ case "set": {
+ String name = parentShell.getNextArgRequired();
+ if (VDBG) Log.v(TAG, "onCommand: name='" + name + "'");
+ if (!mSettableParameters.containsKey(name)) {
+ pw.println("Unknown parameter name -- '" + name + "'");
+ return -1;
+ }
+
+ String valueStr = parentShell.getNextArgRequired();
+ if (VDBG) Log.v(TAG, "onCommand: valueStr='" + valueStr + "'");
+ int value;
+ try {
+ value = Integer.valueOf(valueStr);
+ } catch (NumberFormatException e) {
+ pw.println("Can't convert value to integer -- '" + valueStr + "'");
+ return -1;
+ }
+ mSettableParameters.put(name, value);
+ return 0;
+ }
+ default:
+ pw.println("Unknown 'wifiaware state_mgr <cmd>'");
+ }
+
+ return -1;
+ }
+
+ @Override
+ public void onHelp(String command, ShellCommand parentShell) {
+ final PrintWriter pw = parentShell.getOutPrintWriter();
+
+ pw.println(" " + command);
+ pw.println(" set <name> <value>: sets named parameter to value. Names: "
+ + mSettableParameters.keySet());
+ }
+
/**
* Initialize the handler of the state manager with the specified thread
* looper.
@@ -223,6 +292,36 @@ public class WifiAwareStateManager {
mRtt = new WifiAwareRttStateManager();
mDataPathMgr = new WifiAwareDataPathStateManager(this);
mDataPathMgr.start(mContext, mSm.getHandler().getLooper());
+
+ mPowerManager = mContext.getSystemService(PowerManager.class);
+
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(Intent.ACTION_SCREEN_ON);
+ intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
+ intentFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
+ mContext.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (VDBG) Log.v(TAG, "BroadcastReceiver: action=" + action);
+ if (action.equals(Intent.ACTION_SCREEN_ON)
+ || action.equals(Intent.ACTION_SCREEN_OFF)) {
+ reconfigure();
+ }
+
+ if (action.equals(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED)) {
+ if (mSettableParameters.get(PARAM_ON_IDLE_DISABLE_AWARE) != 0) {
+ if (mPowerManager.isDeviceIdleMode()) {
+ disableUsage();
+ } else {
+ enableUsage();
+ }
+ } else {
+ reconfigure();
+ }
+ }
+ }
+ }, intentFilter);
}
/**
@@ -292,6 +391,17 @@ public class WifiAwareStateManager {
}
/**
+ * Place a request to reconfigure Aware. No additional input - intended to use current
+ * power settings when executed. Thus possibly entering or exiting power saving mode if
+ * needed (or do nothing if Aware is not active).
+ */
+ public void reconfigure() {
+ Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
+ msg.arg1 = COMMAND_TYPE_RECONFIGURE;
+ mSm.sendMessage(msg);
+ }
+
+ /**
* Place a request to stop a discovery session on the state machine queue.
*/
public void terminateSession(int clientId, int sessionId) {
@@ -392,6 +502,11 @@ public class WifiAwareStateManager {
* only happens when a connection is created.
*/
public void enableUsage() {
+ if (mSettableParameters.get(PARAM_ON_IDLE_DISABLE_AWARE) != 0
+ && mPowerManager.isDeviceIdleMode()) {
+ Log.d(TAG, "enableUsage(): while device is in IDLE mode - ignoring");
+ return;
+ }
Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
msg.arg1 = COMMAND_TYPE_ENABLE_USAGE;
mSm.sendMessage(msg);
@@ -1220,6 +1335,9 @@ public class WifiAwareStateManager {
waitForResponse = disconnectLocal(mCurrentTransactionId, clientId);
break;
}
+ case COMMAND_TYPE_RECONFIGURE:
+ waitForResponse = reconfigureLocal(mCurrentTransactionId);
+ break;
case COMMAND_TYPE_TERMINATE_SESSION: {
int clientId = msg.arg2;
int sessionId = (Integer) msg.obj;
@@ -1576,6 +1694,13 @@ public class WifiAwareStateManager {
onConfigFailedLocal(mCurrentCommand, NanStatusType.INTERNAL_FAILURE);
break;
}
+ case COMMAND_TYPE_RECONFIGURE:
+ /*
+ * Reconfigure timed-out. There is nothing to do but log the issue - which
+ * will be done in the callback.
+ */
+ onConfigFailedLocal(mCurrentCommand, NanStatusType.INTERNAL_FAILURE);
+ break;
case COMMAND_TYPE_TERMINATE_SESSION: {
Log.wtf(TAG, "processTimeout: TERMINATE_SESSION - shouldn't be waiting!");
break;
@@ -1826,7 +1951,8 @@ public class WifiAwareStateManager {
doesAnyClientNeedIdentityChangeNotifications() || notifyIdentityChange;
boolean success = mWifiAwareNativeApi.enableAndConfigure(transactionId, merged,
- notificationRequired, mCurrentAwareConfiguration == null);
+ notificationRequired, mCurrentAwareConfiguration == null,
+ mPowerManager.isInteractive(), mPowerManager.isDeviceIdleMode());
if (!success) {
try {
callback.onConnectFail(NanStatusType.INTERNAL_FAILURE);
@@ -1870,7 +1996,22 @@ public class WifiAwareStateManager {
}
return mWifiAwareNativeApi.enableAndConfigure(transactionId, merged, notificationReqs,
- false);
+ false, mPowerManager.isInteractive(), mPowerManager.isDeviceIdleMode());
+ }
+
+ private boolean reconfigureLocal(short transactionId) {
+ if (VDBG) Log.v(TAG, "reconfigureLocal(): transactionId=" + transactionId);
+
+ if (mClients.size() == 0) {
+ // no clients - Aware is not enabled, nothing to reconfigure
+ return false;
+ }
+
+ boolean notificationReqs = doesAnyClientNeedIdentityChangeNotifications();
+
+ return mWifiAwareNativeApi.enableAndConfigure(transactionId, mCurrentAwareConfiguration,
+ notificationReqs, false, mPowerManager.isInteractive(),
+ mPowerManager.isDeviceIdleMode());
}
private void terminateSessionLocal(int clientId, int sessionId) {
@@ -2166,6 +2307,10 @@ public class WifiAwareStateManager {
/*
* NOP (i.e. updated configuration after disconnecting a client)
*/
+ } else if (completedCommand.arg1 == COMMAND_TYPE_RECONFIGURE) {
+ /*
+ * NOP (i.e. updated configuration at power saving event)
+ */
} else {
Log.wtf(TAG, "onConfigCompletedLocal: unexpected completedCommand=" + completedCommand);
return;
@@ -2198,11 +2343,15 @@ public class WifiAwareStateManager {
* shouldn't fail but there's nothing to do - the old configuration
* is still up-and-running).
*/
+ } else if (failedCommand.arg1 == COMMAND_TYPE_RECONFIGURE) {
+ /*
+ * NOP (configuration change as part of possibly power saving event - should not
+ * fail but there's nothing to do).
+ */
} else {
Log.wtf(TAG, "onConfigFailedLocal: unexpected failedCommand=" + failedCommand);
return;
}
-
}
private void onSessionConfigSuccessLocal(Message completedCommand, int pubSubId,
@@ -2709,6 +2858,7 @@ public class WifiAwareStateManager {
for (int i = 0; i < mClients.size(); ++i) {
mClients.valueAt(i).dump(fd, pw, args);
}
+ pw.println(" mSettableParameters: " + mSettableParameters);
mSm.dump(fd, pw, args);
mRtt.dump(fd, pw, args);
mDataPathMgr.dump(fd, pw, args);
diff --git a/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java b/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java
index 8835d75b8..f0758934a 100644
--- a/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java
@@ -55,8 +55,10 @@ import android.net.wifi.aware.WifiAwareNetworkSpecifier;
import android.net.wifi.aware.WifiAwareSession;
import android.os.Handler;
import android.os.INetworkManagementService;
+import android.os.IPowerManager;
import android.os.Message;
import android.os.Messenger;
+import android.os.PowerManager;
import android.os.Process;
import android.os.test.TestLooper;
import android.test.suitebuilder.annotation.SmallTest;
@@ -97,6 +99,7 @@ public class WifiAwareDataPathStateManagerTest {
@Mock private IWifiAwareEventCallback mMockCallback;
@Mock IWifiAwareDiscoverySessionCallback mMockSessionCallback;
TestAlarmManager mAlarmManager;
+ private PowerManager mMockPowerManager;
@Rule
public ErrorCollector collector = new ErrorCollector();
@@ -112,11 +115,18 @@ public class WifiAwareDataPathStateManagerTest {
when(mMockContext.getSystemService(Context.ALARM_SERVICE))
.thenReturn(mAlarmManager.getAlarmManager());
- when(mMockContext.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn(mMockCm);
-
mMockLooper = new TestLooper();
mMockLooperHandler = new Handler(mMockLooper.getLooper());
+ IPowerManager powerManagerService = mock(IPowerManager.class);
+ mMockPowerManager = new PowerManager(mMockContext, powerManagerService,
+ new Handler(mMockLooper.getLooper()));
+
+ when(mMockContext.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn(mMockCm);
+ when(mMockContext.getSystemServiceName(PowerManager.class)).thenReturn(
+ Context.POWER_SERVICE);
+ when(mMockContext.getSystemService(PowerManager.class)).thenReturn(mMockPowerManager);
+
mDut = new WifiAwareStateManager();
mDut.setNative(mMockNative);
mDut.start(mMockContext, mMockLooper.getLooper());
@@ -124,7 +134,7 @@ public class WifiAwareDataPathStateManagerTest {
when(mMockNative.getCapabilities(anyShort())).thenReturn(true);
when(mMockNative.enableAndConfigure(anyShort(), any(), anyBoolean(),
- anyBoolean())).thenReturn(true);
+ anyBoolean(), anyBoolean(), anyBoolean())).thenReturn(true);
when(mMockNative.disable(anyShort())).thenReturn(true);
when(mMockNative.publish(anyShort(), anyInt(), any())).thenReturn(true);
when(mMockNative.subscribe(anyShort(), anyInt(), any()))
@@ -145,6 +155,9 @@ public class WifiAwareDataPathStateManagerTest {
when(mMockNetworkInterface.configureAgentProperties(any(), any(), anyInt(), any(), any(),
any())).thenReturn(true);
+ when(mMockPowerManager.isDeviceIdleMode()).thenReturn(false);
+ when(mMockPowerManager.isInteractive()).thenReturn(true);
+
installDataPathStateManagerMocks();
}
@@ -884,7 +897,7 @@ public class WifiAwareDataPathStateManagerTest {
false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
- eq(configRequest), eq(false), eq(true));
+ eq(configRequest), eq(false), eq(true), eq(true), eq(false));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
inOrder.verify(mMockCallback).onConnectSuccess(clientId);
diff --git a/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareNativeApiTest.java b/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareNativeApiTest.java
new file mode 100644
index 000000000..956418997
--- /dev/null
+++ b/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareNativeApiTest.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2017 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.aware;
+
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyShort;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.hardware.wifi.V1_0.IWifiNanIface;
+import android.hardware.wifi.V1_0.NanBandIndex;
+import android.hardware.wifi.V1_0.NanConfigRequest;
+import android.hardware.wifi.V1_0.NanEnableRequest;
+import android.hardware.wifi.V1_0.WifiStatus;
+import android.hardware.wifi.V1_0.WifiStatusCode;
+import android.net.wifi.aware.ConfigRequest;
+import android.os.RemoteException;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ErrorCollector;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.PrintWriter;
+
+/**
+ * Unit test harness for WifiAwareNativeApi
+ */
+public class WifiAwareNativeApiTest {
+ @Mock WifiAwareNativeManager mWifiAwareNativeManagerMock;
+ @Mock IWifiNanIface mIWifiNanIfaceMock;
+
+ @Rule public ErrorCollector collector = new ErrorCollector();
+
+ private WifiAwareNativeApi mDut;
+
+ /**
+ * Initializes mocks.
+ */
+ @Before
+ public void setup() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ when(mWifiAwareNativeManagerMock.getWifiNanIface()).thenReturn(mIWifiNanIfaceMock);
+
+ WifiStatus status = new WifiStatus();
+ status.code = WifiStatusCode.SUCCESS;
+ when(mIWifiNanIfaceMock.enableRequest(anyShort(), any())).thenReturn(status);
+ when(mIWifiNanIfaceMock.configRequest(anyShort(), any())).thenReturn(status);
+
+ mDut = new WifiAwareNativeApi(mWifiAwareNativeManagerMock);
+ }
+
+ /**
+ * Test that the set parameter shell command executor works when parameters are valid.
+ */
+ @Test
+ public void testSetParameterShellCommandSuccess() {
+ setSettableParam(WifiAwareNativeApi.PARAM_DW_ON_IDLE_5GHZ, Integer.toString(1), true);
+ }
+
+ /**
+ * Test that the set parameter shell command executor fails on incorrect name.
+ */
+ @Test
+ public void testSetParameterShellCommandInvalidParameterName() {
+ setSettableParam("XXX", Integer.toString(1), false);
+ }
+
+ /**
+ * Test that the set parameter shell command executor fails on invalid value (not convertible
+ * to an int).
+ */
+ @Test
+ public void testSetParameterShellCommandInvalidValue() {
+ setSettableParam(WifiAwareNativeApi.PARAM_DW_ON_IDLE_5GHZ, "garbage", false);
+ }
+
+ /**
+ * Validate that the configuration parameters used to manage power state behavior is
+ * using default values at the default power state.
+ */
+ @Test
+ public void testEnableAndConfigPowerSettingsDefaults() throws RemoteException {
+ NanConfigRequest config = validateEnableAndConfigure((short) 10,
+ new ConfigRequest.Builder().build(), true, true, true, false);
+
+ collector.checkThat("validDiscoveryWindowIntervalVal-5", false,
+ equalTo(config.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ]
+ .validDiscoveryWindowIntervalVal));
+ collector.checkThat("validDiscoveryWindowIntervalVal-24", false,
+ equalTo(config.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ]
+ .validDiscoveryWindowIntervalVal));
+ }
+
+ /**
+ * Validate that the configuration parameters used to manage power state behavior is
+ * using the specified non-interactive values when in that power state.
+ */
+ @Test
+ public void testEnableAndConfigPowerSettingsNoneInteractive() throws RemoteException {
+ byte interactive5 = 2;
+ byte interactive24 = 3;
+
+ setPowerConfigurationParams(interactive5, interactive24, (byte) -1, (byte) -1);
+ NanConfigRequest config = validateEnableAndConfigure((short) 10,
+ new ConfigRequest.Builder().build(), false, false, false, false);
+
+ collector.checkThat("validDiscoveryWindowIntervalVal-5", true,
+ equalTo(config.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ]
+ .validDiscoveryWindowIntervalVal));
+ collector.checkThat("discoveryWindowIntervalVal-5", interactive5,
+ equalTo(config.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ]
+ .discoveryWindowIntervalVal));
+ collector.checkThat("validDiscoveryWindowIntervalVal-24", true,
+ equalTo(config.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ]
+ .validDiscoveryWindowIntervalVal));
+ collector.checkThat("discoveryWindowIntervalVal-24", interactive24,
+ equalTo(config.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ]
+ .discoveryWindowIntervalVal));
+ }
+
+ /**
+ * Validate that the configuration parameters used to manage power state behavior is
+ * using the specified idle (doze) values when in that power state.
+ */
+ @Test
+ public void testEnableAndConfigPowerSettingsIdle() throws RemoteException {
+ byte idle5 = 2;
+ byte idle24 = -1;
+
+ setPowerConfigurationParams((byte) -1, (byte) -1, idle5, idle24);
+ NanConfigRequest config = validateEnableAndConfigure((short) 10,
+ new ConfigRequest.Builder().build(), false, true, false, true);
+
+ collector.checkThat("validDiscoveryWindowIntervalVal-5", true,
+ equalTo(config.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ]
+ .validDiscoveryWindowIntervalVal));
+ collector.checkThat("discoveryWindowIntervalVal-5", idle5,
+ equalTo(config.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ]
+ .discoveryWindowIntervalVal));
+ collector.checkThat("validDiscoveryWindowIntervalVal-24", false,
+ equalTo(config.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ]
+ .validDiscoveryWindowIntervalVal));
+ }
+
+ // utilities
+
+ private void setPowerConfigurationParams(byte interactive5, byte interactive24, byte idle5,
+ byte idle24) {
+ setSettableParam(WifiAwareNativeApi.PARAM_DW_ON_INACTIVE_5GHZ,
+ Integer.toString(interactive5), true);
+ setSettableParam(WifiAwareNativeApi.PARAM_DW_ON_INACTIVE_24GHZ,
+ Integer.toString(interactive24), true);
+ setSettableParam(WifiAwareNativeApi.PARAM_DW_ON_IDLE_5GHZ, Integer.toString(idle5), true);
+ setSettableParam(WifiAwareNativeApi.PARAM_DW_ON_IDLE_24GHZ, Integer.toString(idle24), true);
+ }
+
+ private void setSettableParam(String name, String value, boolean expectSuccess) {
+ PrintWriter pwMock = mock(PrintWriter.class);
+ WifiAwareShellCommand parentShellMock = mock(WifiAwareShellCommand.class);
+ when(parentShellMock.getNextArgRequired()).thenReturn("set").thenReturn(name).thenReturn(
+ value);
+ when(parentShellMock.getErrPrintWriter()).thenReturn(pwMock);
+
+ collector.checkThat(mDut.onCommand(parentShellMock), equalTo(expectSuccess ? 0 : -1));
+ }
+
+ private NanConfigRequest validateEnableAndConfigure(short transactionId,
+ ConfigRequest configRequest, boolean notifyIdentityChange, boolean initialConfiguration,
+ boolean isInteractive, boolean isIdle) throws RemoteException {
+ mDut.enableAndConfigure(transactionId, configRequest, notifyIdentityChange,
+ initialConfiguration, isInteractive, isIdle);
+
+ ArgumentCaptor<NanEnableRequest> enableReqCaptor = ArgumentCaptor.forClass(
+ NanEnableRequest.class);
+ ArgumentCaptor<NanConfigRequest> configReqCaptor = ArgumentCaptor.forClass(
+ NanConfigRequest.class);
+ NanConfigRequest config;
+
+ if (initialConfiguration) {
+ verify(mIWifiNanIfaceMock).enableRequest(eq(transactionId), enableReqCaptor.capture());
+ config = enableReqCaptor.getValue().configParams;
+ } else {
+ verify(mIWifiNanIfaceMock).configRequest(eq(transactionId), configReqCaptor.capture());
+ config = configReqCaptor.getValue();
+ }
+
+ collector.checkThat("disableDiscoveryAddressChangeIndication", !notifyIdentityChange,
+ equalTo(config.disableDiscoveryAddressChangeIndication));
+ collector.checkThat("disableStartedClusterIndication", !notifyIdentityChange,
+ equalTo(config.disableStartedClusterIndication));
+ collector.checkThat("disableJoinedClusterIndication", !notifyIdentityChange,
+ equalTo(config.disableJoinedClusterIndication));
+
+ return config;
+ }
+}
diff --git a/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareServiceImplTest.java b/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareServiceImplTest.java
index b5e12d29c..1ab6898f5 100644
--- a/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareServiceImplTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareServiceImplTest.java
@@ -70,6 +70,8 @@ public class WifiAwareServiceImplTest {
@Mock
private WifiAwareStateManager mAwareStateManagerMock;
@Mock
+ private WifiAwareShellCommand mWifiAwareShellCommandMock;
+ @Mock
private IBinder mBinderMock;
@Mock
private IWifiAwareEventCallback mCallbackMock;
@@ -114,7 +116,7 @@ public class WifiAwareServiceImplTest {
mDut = new WifiAwareServiceImplSpy(mContextMock);
mDut.fakeUid = mDefaultUid;
- mDut.start(mHandlerThreadMock, mAwareStateManagerMock);
+ mDut.start(mHandlerThreadMock, mAwareStateManagerMock, mWifiAwareShellCommandMock);
verify(mAwareStateManagerMock).start(eq(mContextMock), any());
}
diff --git a/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareStateManagerTest.java b/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareStateManagerTest.java
index fd4d5c794..a8d310a4b 100644
--- a/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareStateManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareStateManagerTest.java
@@ -38,8 +38,10 @@ import android.Manifest;
import android.app.AppOpsManager;
import android.app.test.MockAnswerUtil;
import android.app.test.TestAlarmManager;
+import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.hardware.wifi.V1_0.NanStatusType;
import android.net.ConnectivityManager;
@@ -50,7 +52,10 @@ import android.net.wifi.aware.IWifiAwareEventCallback;
import android.net.wifi.aware.PublishConfig;
import android.net.wifi.aware.SubscribeConfig;
import android.net.wifi.aware.WifiAwareManager;
+import android.os.Handler;
+import android.os.IPowerManager;
import android.os.Message;
+import android.os.PowerManager;
import android.os.UserHandle;
import android.os.test.TestLooper;
import android.test.suitebuilder.annotation.SmallTest;
@@ -86,11 +91,14 @@ public class WifiAwareStateManagerTest {
private TestLooper mMockLooper;
private Random mRandomNg = new Random(15687);
private WifiAwareStateManager mDut;
+ @Mock private WifiAwareNativeManager mMockNativeManager;
@Mock private WifiAwareNativeApi mMockNative;
@Mock private Context mMockContext;
@Mock private AppOpsManager mMockAppOpsManager;
@Mock private WifiAwareRttStateManager mMockAwareRttStateManager;
TestAlarmManager mAlarmManager;
+ private PowerManager mMockPowerManager;
+ private BroadcastReceiver mPowerBcastReceiver;
@Mock private WifiAwareDataPathStateManager mMockAwareDataPathStatemanager;
@Rule
@@ -109,9 +117,18 @@ public class WifiAwareStateManagerTest {
when(mMockContext.getSystemService(Context.ALARM_SERVICE))
.thenReturn(mAlarmManager.getAlarmManager());
+ mMockLooper = new TestLooper();
+
+ IPowerManager powerManagerService = mock(IPowerManager.class);
+ mMockPowerManager = new PowerManager(mMockContext, powerManagerService,
+ new Handler(mMockLooper.getLooper()));
+
when(mMockContext.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn(
mock(ConnectivityManager.class));
when(mMockContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mMockAppOpsManager);
+ when(mMockContext.getSystemServiceName(PowerManager.class)).thenReturn(
+ Context.POWER_SERVICE);
+ when(mMockContext.getSystemService(PowerManager.class)).thenReturn(mMockPowerManager);
when(mMockContext.checkPermission(eq(android.Manifest.permission.ACCESS_FINE_LOCATION),
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
when(mMockContext.checkPermission(eq(Manifest.permission.ACCESS_COARSE_LOCATION),
@@ -120,16 +137,20 @@ public class WifiAwareStateManagerTest {
any())).thenReturn(AppOpsManager.MODE_ERRORED);
when(mMockAppOpsManager.noteOp(eq(AppOpsManager.OP_COARSE_LOCATION), anyInt(),
any())).thenReturn(AppOpsManager.MODE_ERRORED);
+ when(mMockPowerManager.isDeviceIdleMode()).thenReturn(false);
+ when(mMockPowerManager.isInteractive()).thenReturn(true);
- mMockLooper = new TestLooper();
-
+ ArgumentCaptor<BroadcastReceiver> bcastRxCaptor = ArgumentCaptor.forClass(
+ BroadcastReceiver.class);
mDut = new WifiAwareStateManager();
mDut.setNative(mMockNative);
mDut.start(mMockContext, mMockLooper.getLooper());
+ verify(mMockContext).registerReceiver(bcastRxCaptor.capture(), any(IntentFilter.class));
+ mPowerBcastReceiver = bcastRxCaptor.getValue();
installMocksInStateManager(mDut, mMockAwareRttStateManager, mMockAwareDataPathStatemanager);
when(mMockNative.enableAndConfigure(anyShort(), any(), anyBoolean(),
- anyBoolean())).thenReturn(true);
+ anyBoolean(), anyBoolean(), anyBoolean())).thenReturn(true);
when(mMockNative.disable(anyShort())).thenReturn(true);
when(mMockNative.publish(anyShort(), anyInt(), any())).thenReturn(true);
when(mMockNative.subscribe(anyShort(), anyInt(), any()))
@@ -142,6 +163,32 @@ public class WifiAwareStateManagerTest {
}
/**
+ * Test that the set parameter shell command executor works when parameters are valid.
+ */
+ @Test
+ public void testSetParameterShellCommandSuccess() {
+ setSettableParam(WifiAwareStateManager.PARAM_ON_IDLE_DISABLE_AWARE, Integer.toString(1),
+ true);
+ }
+
+ /**
+ * Test that the set parameter shell command executor fails on incorrect name.
+ */
+ @Test
+ public void testSetParameterShellCommandInvalidParameterName() {
+ setSettableParam("XXX", Integer.toString(1), false);
+ }
+
+ /**
+ * Test that the set parameter shell command executor fails on invalid value (not convertible
+ * to an int).
+ */
+ @Test
+ public void testSetParameterShellCommandInvalidValue() {
+ setSettableParam(WifiAwareStateManager.PARAM_ON_IDLE_DISABLE_AWARE, "garbage", false);
+ }
+
+ /**
* Validate that Aware data-path interfaces are brought up and down correctly.
*/
@Test
@@ -243,7 +290,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
- eq(false), eq(true));
+ eq(false), eq(true), eq(true), eq(false));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onConnectSuccess(clientId);
@@ -276,7 +323,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
- eq(false), eq(true));
+ eq(false), eq(true), eq(true), eq(false));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onConnectSuccess(clientId);
@@ -300,7 +347,7 @@ public class WifiAwareStateManagerTest {
InOrder inOrder = inOrder(mMockContext, mMockNative, mockCallback);
when(mMockNative.enableAndConfigure(anyShort(), any(), anyBoolean(),
- anyBoolean())).thenReturn(false);
+ anyBoolean(), eq(true), eq(false))).thenReturn(false);
// (1) check initial state
mDut.enableUsage();
@@ -314,7 +361,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
- eq(false), eq(true));
+ eq(false), eq(true), eq(true), eq(false));
inOrder.verify(mockCallback).onConnectFail(NanStatusType.INTERNAL_FAILURE);
validateInternalClientInfoCleanedUp(clientId);
@@ -358,7 +405,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId1, uid, pid, callingPackage, mockCallback1, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionIdCapture.capture(),
- eq(configRequest), eq(false), eq(true));
+ eq(configRequest), eq(false), eq(true), eq(true), eq(false));
short transactionId = transactionIdCapture.getValue();
mDut.onConfigSuccessResponse(transactionId);
mMockLooper.dispatchAll();
@@ -367,7 +414,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId2, uid, pid, callingPackage, mockCallback2, configRequest, true);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionIdCapture.capture(),
- eq(configRequest), eq(true), eq(false));
+ eq(configRequest), eq(true), eq(false), eq(true), eq(false));
transactionId = transactionIdCapture.getValue();
mDut.onConfigSuccessResponse(transactionId);
mMockLooper.dispatchAll();
@@ -443,7 +490,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
- eq(false), eq(true));
+ eq(false), eq(true), eq(true), eq(false));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onConnectSuccess(clientId);
@@ -499,7 +546,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
- eq(configRequest), eq(false), eq(true));
+ eq(configRequest), eq(false), eq(true), eq(true), eq(false));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onConnectSuccess(clientId);
@@ -563,7 +610,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
- eq(configRequest), eq(false), eq(true));
+ eq(configRequest), eq(false), eq(true), eq(true), eq(false));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onConnectSuccess(clientId);
@@ -637,7 +684,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
- eq(false), eq(true));
+ eq(false), eq(true), eq(true), eq(false));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onConnectSuccess(clientId);
@@ -719,7 +766,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
- eq(false), eq(true));
+ eq(false), eq(true), eq(true), eq(false));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onConnectSuccess(clientId);
@@ -777,7 +824,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
- eq(false), eq(true));
+ eq(false), eq(true), eq(true), eq(false));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onConnectSuccess(clientId);
@@ -842,7 +889,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
- eq(false), eq(true));
+ eq(false), eq(true), eq(true), eq(false));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onConnectSuccess(clientId);
@@ -915,7 +962,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
- eq(false), eq(true));
+ eq(false), eq(true), eq(true), eq(false));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onConnectSuccess(clientId);
@@ -998,7 +1045,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
- eq(false), eq(true));
+ eq(false), eq(true), eq(true), eq(false));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onConnectSuccess(clientId);
@@ -1070,7 +1117,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
- eq(configRequest), eq(false), eq(true));
+ eq(configRequest), eq(false), eq(true), eq(true), eq(false));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onConnectSuccess(clientId);
@@ -1176,7 +1223,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
- eq(false), eq(true));
+ eq(false), eq(true), eq(true), eq(false));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onConnectSuccess(clientId);
@@ -1270,7 +1317,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
- eq(false), eq(true));
+ eq(false), eq(true), eq(true), eq(false));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onConnectSuccess(clientId);
@@ -1353,7 +1400,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
- eq(false), eq(true));
+ eq(false), eq(true), eq(true), eq(false));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onConnectSuccess(clientId);
@@ -1420,7 +1467,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
- eq(false), eq(true));
+ eq(false), eq(true), eq(true), eq(false));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onConnectSuccess(clientId);
@@ -1544,7 +1591,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
- eq(false), eq(true));
+ eq(false), eq(true), eq(true), eq(false));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onConnectSuccess(clientId);
@@ -1629,7 +1676,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
- eq(false), eq(true));
+ eq(false), eq(true), eq(true), eq(false));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onConnectSuccess(clientId);
@@ -1715,7 +1762,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
- eq(configRequest), eq(false), eq(true));
+ eq(configRequest), eq(false), eq(true), eq(true), eq(false));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onConnectSuccess(clientId);
@@ -1811,7 +1858,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
- eq(configRequest), eq(false), eq(true));
+ eq(configRequest), eq(false), eq(true), eq(true), eq(false));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onConnectSuccess(clientId);
@@ -1941,7 +1988,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
- eq(configRequest), eq(false), eq(true));
+ eq(configRequest), eq(false), eq(true), eq(true), eq(false));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onConnectSuccess(clientId);
@@ -2154,7 +2201,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
- eq(false), eq(true));
+ eq(false), eq(true), eq(true), eq(false));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onConnectSuccess(clientId);
@@ -2245,7 +2292,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId1, uid, pid, callingPackage, mockCallback1, configRequest1, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
- crCapture.capture(), eq(false), eq(true));
+ crCapture.capture(), eq(false), eq(true), eq(true), eq(false));
collector.checkThat("merge: stage 1", crCapture.getValue(), equalTo(configRequest1));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
@@ -2261,7 +2308,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId3, uid, pid, callingPackage, mockCallback3, configRequest3, true);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
- crCapture.capture(), eq(true), eq(false));
+ crCapture.capture(), eq(true), eq(false), eq(true), eq(false));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
inOrder.verify(mockCallback3).onConnectSuccess(clientId3);
@@ -2282,7 +2329,7 @@ public class WifiAwareStateManagerTest {
mMockLooper.dispatchAll();
validateInternalClientInfoCleanedUp(clientId3);
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
- crCapture.capture(), eq(false), eq(false));
+ crCapture.capture(), eq(false), eq(false), eq(true), eq(false));
collector.checkThat("configRequest1", configRequest1, equalTo(crCapture.getValue()));
@@ -2337,7 +2384,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
- eq(false), eq(true));
+ eq(false), eq(true), eq(true), eq(false));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onConnectSuccess(clientId);
@@ -2411,7 +2458,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
- eq(false), eq(true));
+ eq(false), eq(true), eq(true), eq(false));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onConnectSuccess(clientId);
@@ -2454,7 +2501,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
- eq(false), eq(true));
+ eq(false), eq(true), eq(true), eq(false));
verifyNoMoreInteractions(mMockNative, mockCallback, mockSessionCallback);
}
@@ -2488,7 +2535,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
- eq(false), eq(true));
+ eq(false), eq(true), eq(true), eq(false));
short transactionIdConfig = transactionId.getValue();
mDut.onConfigSuccessResponse(transactionIdConfig);
mMockLooper.dispatchAll();
@@ -2544,7 +2591,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
- eq(false), eq(true));
+ eq(false), eq(true), eq(true), eq(false));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onConnectSuccess(clientId);
@@ -2598,7 +2645,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
- eq(configRequest), eq(false), eq(true));
+ eq(configRequest), eq(false), eq(true), eq(true), eq(false));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onConnectSuccess(clientId);
@@ -2650,7 +2697,7 @@ public class WifiAwareStateManagerTest {
mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
- eq(configRequest), eq(false), eq(true));
+ eq(configRequest), eq(false), eq(true), eq(true), eq(false));
mDut.onConfigSuccessResponse(transactionId.getValue());
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onConnectSuccess(clientId);
@@ -2674,6 +2721,116 @@ public class WifiAwareStateManagerTest {
}
}
+ /**
+ * Validate configuration changes on power state changes when Aware is not disabled on doze.
+ */
+ @Test
+ public void testConfigOnPowerStateChanges() throws Exception {
+ final int clientId = 188;
+ final int uid = 1000;
+ final int pid = 2000;
+ final String callingPackage = "com.google.somePackage";
+
+ ConfigRequest configRequest = new ConfigRequest.Builder().build();
+
+ ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
+ IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
+ InOrder inOrder = inOrder(mMockNative, mockCallback);
+
+ mDut.enableUsage();
+ mMockLooper.dispatchAll();
+ inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+ mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
+ mMockLooper.dispatchAll();
+
+ // (1) connect
+ mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
+ mMockLooper.dispatchAll();
+ inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
+ eq(configRequest), eq(false), eq(true), eq(true), eq(false));
+ mDut.onConfigSuccessResponse(transactionId.getValue());
+ mMockLooper.dispatchAll();
+ inOrder.verify(mockCallback).onConnectSuccess(clientId);
+
+ // (2) power state change: SCREEN OFF
+ simulatePowerStateChangeInteractive(false);
+ mMockLooper.dispatchAll();
+ inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
+ eq(configRequest), eq(false), eq(false), eq(false), eq(false));
+ mDut.onConfigSuccessResponse(transactionId.getValue());
+ mMockLooper.dispatchAll();
+
+ // (3) power state change: DOZE
+ simulatePowerStateChangeDoze(true);
+ mMockLooper.dispatchAll();
+ inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
+ eq(configRequest), eq(false), eq(false), eq(false), eq(true));
+ mDut.onConfigSuccessResponse(transactionId.getValue());
+ mMockLooper.dispatchAll();
+
+ // (4) restore power state to default
+ simulatePowerStateChangeInteractive(true); // effectively treated as no-doze
+ mMockLooper.dispatchAll();
+ inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
+ eq(configRequest), eq(false), eq(false), eq(true), eq(true));
+ mDut.onConfigSuccessResponse(transactionId.getValue());
+ mMockLooper.dispatchAll();
+
+ verifyNoMoreInteractions(mMockNative, mockCallback);
+ }
+
+ /**
+ * Validate aware enable/disable during doze transitions.
+ */
+ @Test
+ public void testEnableDisableOnDoze() throws Exception {
+ final int clientId = 188;
+ final int uid = 1000;
+ final int pid = 2000;
+ final String callingPackage = "com.google.somePackage";
+
+ setSettableParam(WifiAwareStateManager.PARAM_ON_IDLE_DISABLE_AWARE, Integer.toString(1),
+ true);
+
+ ConfigRequest configRequest = new ConfigRequest.Builder().build();
+
+ ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
+ IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
+ InOrder inOrder = inOrder(mMockContext, mMockNativeManager, mMockNative, mockCallback);
+
+ mDut.enableUsage();
+ mMockLooper.dispatchAll();
+ inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+ mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
+ mMockLooper.dispatchAll();
+
+ // (1) connect
+ mDut.connect(clientId, uid, pid, callingPackage, mockCallback, configRequest, false);
+ mMockLooper.dispatchAll();
+ inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
+ eq(configRequest), eq(false), eq(true), eq(true), eq(false));
+ mDut.onConfigSuccessResponse(transactionId.getValue());
+ mMockLooper.dispatchAll();
+ inOrder.verify(mockCallback).onConnectSuccess(clientId);
+
+ // (3) power state change: DOZE
+ simulatePowerStateChangeDoze(true);
+ mMockLooper.dispatchAll();
+ inOrder.verify(mMockNative).disable((short) 0);
+ validateCorrectAwareStatusChangeBroadcast(inOrder, false);
+
+ // (4) power state change: SCREEN ON (but DOZE still on - fakish but expect no changes)
+ simulatePowerStateChangeInteractive(false);
+ mMockLooper.dispatchAll();
+
+ // (5) power state change: DOZE OFF
+ simulatePowerStateChangeDoze(false);
+ mMockLooper.dispatchAll();
+ validateCorrectAwareStatusChangeBroadcast(inOrder, true);
+
+ verifyNoMoreInteractions(mMockNativeManager, mMockNative, mockCallback);
+ }
+
/*
* Tests of internal state of WifiAwareStateManager: very limited (not usually
* a good idea). However, these test that the internal state is cleaned-up
@@ -2751,6 +2908,16 @@ public class WifiAwareStateManagerTest {
/*
* Utilities
*/
+ private void setSettableParam(String name, String value, boolean expectSuccess) {
+ PrintWriter pwMock = mock(PrintWriter.class);
+ WifiAwareShellCommand parentShellMock = mock(WifiAwareShellCommand.class);
+ when(parentShellMock.getNextArgRequired()).thenReturn("set").thenReturn(name).thenReturn(
+ value);
+ when(parentShellMock.getErrPrintWriter()).thenReturn(pwMock);
+
+ collector.checkThat(mDut.onCommand(parentShellMock), equalTo(expectSuccess ? 0 : -1));
+ }
+
private void dumpDut(String prefix) {
StringWriter sw = new StringWriter();
mDut.dump(null, new PrintWriter(sw), null);
@@ -2825,6 +2992,29 @@ public class WifiAwareStateManagerTest {
}
}
+ /**
+ * Simulate power state change due to doze. Changes the power manager return values and
+ * dispatches a broadcast.
+ */
+ private void simulatePowerStateChangeDoze(boolean isDozeOn) {
+ when(mMockPowerManager.isDeviceIdleMode()).thenReturn(isDozeOn);
+
+ Intent intent = new Intent(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
+ mPowerBcastReceiver.onReceive(mMockContext, intent);
+ }
+
+ /**
+ * Simulate power state change due to interactive mode change (screen on/off). Changes the power
+ * manager return values and dispatches a broadcast.
+ */
+ private void simulatePowerStateChangeInteractive(boolean isInteractive) {
+ when(mMockPowerManager.isInteractive()).thenReturn(isInteractive);
+
+ Intent intent = new Intent(
+ isInteractive ? Intent.ACTION_SCREEN_ON : Intent.ACTION_SCREEN_OFF);
+ mPowerBcastReceiver.onReceive(mMockContext, intent);
+ }
+
private static Capabilities getCapabilities() {
Capabilities cap = new Capabilities();
cap.maxConcurrentAwareClusters = 1;