Merge changes I8d149ab0,Ia0a52819,If54a89cb,I20faa733,Ib32dfd23 into oc-dev
* changes: WifiManager: expose Local Only Hotspot APIs WifiManager: implement watch LocalOnlyHotspot WifiManager: implement start/stopLocalOnlyHotspot WifiManager: add LocalOnlyHotspotObserverProxy WifiManager: add LocalOnlyHotspotCallbackProxy
This commit is contained in:
committed by
Android (Google) Code Review
commit
07ea44909f
@@ -26549,6 +26549,7 @@ package android.net.wifi {
|
||||
method public void setTdlsEnabled(java.net.InetAddress, boolean);
|
||||
method public void setTdlsEnabledWithMacAddress(java.lang.String, boolean);
|
||||
method public boolean setWifiEnabled(boolean);
|
||||
method public void startLocalOnlyHotspot(android.net.wifi.WifiManager.LocalOnlyHotspotCallback, android.os.Handler);
|
||||
method public boolean startScan();
|
||||
method public void startWps(android.net.wifi.WpsInfo, android.net.wifi.WifiManager.WpsCallback);
|
||||
method public int updateNetwork(android.net.wifi.WifiConfiguration);
|
||||
@@ -26599,6 +26600,21 @@ package android.net.wifi {
|
||||
field public static final int WPS_WEP_PROHIBITED = 4; // 0x4
|
||||
}
|
||||
|
||||
public static class WifiManager.LocalOnlyHotspotCallback {
|
||||
ctor public WifiManager.LocalOnlyHotspotCallback();
|
||||
method public void onFailed(int);
|
||||
method public void onStarted(android.net.wifi.WifiManager.LocalOnlyHotspotReservation);
|
||||
method public void onStopped();
|
||||
field public static final int ERROR_GENERIC = 2; // 0x2
|
||||
field public static final int ERROR_INCOMPATIBLE_MODE = 3; // 0x3
|
||||
field public static final int ERROR_NO_CHANNEL = 1; // 0x1
|
||||
}
|
||||
|
||||
public class WifiManager.LocalOnlyHotspotReservation implements java.lang.AutoCloseable {
|
||||
method public void close();
|
||||
method public android.net.wifi.WifiConfiguration getConfig();
|
||||
}
|
||||
|
||||
public class WifiManager.MulticastLock {
|
||||
method public void acquire();
|
||||
method public boolean isHeld();
|
||||
|
||||
@@ -29130,6 +29130,7 @@ package android.net.wifi {
|
||||
method public boolean setWifiApConfiguration(android.net.wifi.WifiConfiguration);
|
||||
method public boolean setWifiApEnabled(android.net.wifi.WifiConfiguration, boolean);
|
||||
method public boolean setWifiEnabled(boolean);
|
||||
method public void startLocalOnlyHotspot(android.net.wifi.WifiManager.LocalOnlyHotspotCallback, android.os.Handler);
|
||||
method public deprecated boolean startLocationRestrictedScan(android.os.WorkSource);
|
||||
method public boolean startScan();
|
||||
method public boolean startScan(android.os.WorkSource);
|
||||
@@ -29207,6 +29208,21 @@ package android.net.wifi {
|
||||
method public abstract void onSuccess();
|
||||
}
|
||||
|
||||
public static class WifiManager.LocalOnlyHotspotCallback {
|
||||
ctor public WifiManager.LocalOnlyHotspotCallback();
|
||||
method public void onFailed(int);
|
||||
method public void onStarted(android.net.wifi.WifiManager.LocalOnlyHotspotReservation);
|
||||
method public void onStopped();
|
||||
field public static final int ERROR_GENERIC = 2; // 0x2
|
||||
field public static final int ERROR_INCOMPATIBLE_MODE = 3; // 0x3
|
||||
field public static final int ERROR_NO_CHANNEL = 1; // 0x1
|
||||
}
|
||||
|
||||
public class WifiManager.LocalOnlyHotspotReservation implements java.lang.AutoCloseable {
|
||||
method public void close();
|
||||
method public android.net.wifi.WifiConfiguration getConfig();
|
||||
}
|
||||
|
||||
public class WifiManager.MulticastLock {
|
||||
method public void acquire();
|
||||
method public boolean isHeld();
|
||||
|
||||
@@ -26657,6 +26657,7 @@ package android.net.wifi {
|
||||
method public void setTdlsEnabled(java.net.InetAddress, boolean);
|
||||
method public void setTdlsEnabledWithMacAddress(java.lang.String, boolean);
|
||||
method public boolean setWifiEnabled(boolean);
|
||||
method public void startLocalOnlyHotspot(android.net.wifi.WifiManager.LocalOnlyHotspotCallback, android.os.Handler);
|
||||
method public boolean startScan();
|
||||
method public void startWps(android.net.wifi.WpsInfo, android.net.wifi.WifiManager.WpsCallback);
|
||||
method public int updateNetwork(android.net.wifi.WifiConfiguration);
|
||||
@@ -26707,6 +26708,21 @@ package android.net.wifi {
|
||||
field public static final int WPS_WEP_PROHIBITED = 4; // 0x4
|
||||
}
|
||||
|
||||
public static class WifiManager.LocalOnlyHotspotCallback {
|
||||
ctor public WifiManager.LocalOnlyHotspotCallback();
|
||||
method public void onFailed(int);
|
||||
method public void onStarted(android.net.wifi.WifiManager.LocalOnlyHotspotReservation);
|
||||
method public void onStopped();
|
||||
field public static final int ERROR_GENERIC = 2; // 0x2
|
||||
field public static final int ERROR_INCOMPATIBLE_MODE = 3; // 0x3
|
||||
field public static final int ERROR_NO_CHANNEL = 1; // 0x1
|
||||
}
|
||||
|
||||
public class WifiManager.LocalOnlyHotspotReservation implements java.lang.AutoCloseable {
|
||||
method public void close();
|
||||
method public android.net.wifi.WifiConfiguration getConfig();
|
||||
}
|
||||
|
||||
public class WifiManager.MulticastLock {
|
||||
method public void acquire();
|
||||
method public boolean isHeld();
|
||||
|
||||
@@ -40,6 +40,7 @@ import android.os.WorkSource;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.util.AsyncChannel;
|
||||
import com.android.internal.util.Protocol;
|
||||
@@ -47,6 +48,7 @@ import com.android.server.net.NetworkPinner;
|
||||
|
||||
import dalvik.system.CloseGuard;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.net.InetAddress;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -851,6 +853,22 @@ public class WifiManager {
|
||||
private CountDownLatch mConnected;
|
||||
private Looper mLooper;
|
||||
|
||||
/* LocalOnlyHotspot callback message types */
|
||||
/** @hide */
|
||||
public static final int HOTSPOT_STARTED = 0;
|
||||
/** @hide */
|
||||
public static final int HOTSPOT_STOPPED = 1;
|
||||
/** @hide */
|
||||
public static final int HOTSPOT_FAILED = 2;
|
||||
/** @hide */
|
||||
public static final int HOTSPOT_OBSERVER_REGISTERED = 3;
|
||||
|
||||
private final Object mLock = new Object(); // lock guarding access to the following vars
|
||||
@GuardedBy("mLock")
|
||||
private LocalOnlyHotspotCallbackProxy mLOHSCallbackProxy;
|
||||
@GuardedBy("mLock")
|
||||
private LocalOnlyHotspotObserverProxy mLOHSObserverProxy;
|
||||
|
||||
/**
|
||||
* Create a new WifiManager instance.
|
||||
* Applications will almost always want to use
|
||||
@@ -1864,12 +1882,27 @@ public class WifiManager {
|
||||
* operating status.
|
||||
* @param handler Handler to be used for callbacks. If the caller passes a null Handler, the
|
||||
* main thread will be used.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void startLocalOnlyHotspot(LocalOnlyHotspotCallback callback,
|
||||
@Nullable Handler handler) {
|
||||
throw new UnsupportedOperationException("LocalOnlyHotspot is still in development");
|
||||
synchronized (mLock) {
|
||||
Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper();
|
||||
LocalOnlyHotspotCallbackProxy proxy =
|
||||
new LocalOnlyHotspotCallbackProxy(this, looper, callback);
|
||||
try {
|
||||
WifiConfiguration config = mService.startLocalOnlyHotspot(
|
||||
proxy.getMessenger(), new Binder());
|
||||
if (config == null) {
|
||||
// Send message to the proxy to make sure we call back on the correct thread
|
||||
proxy.notifyFailed(
|
||||
LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE);
|
||||
return;
|
||||
}
|
||||
mLOHSCallbackProxy = proxy;
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1886,7 +1919,9 @@ public class WifiManager {
|
||||
* @hide
|
||||
*/
|
||||
public void cancelLocalOnlyHotspotRequest() {
|
||||
throw new UnsupportedOperationException("LocalOnlyHotspot is still in development");
|
||||
synchronized (mLock) {
|
||||
stopLocalOnlyHotspot();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1900,7 +1935,18 @@ public class WifiManager {
|
||||
* method on their LocalOnlyHotspotReservation.
|
||||
*/
|
||||
private void stopLocalOnlyHotspot() {
|
||||
throw new UnsupportedOperationException("LocalOnlyHotspot is still in development");
|
||||
synchronized (mLock) {
|
||||
if (mLOHSCallbackProxy == null) {
|
||||
// nothing to do, the callback was already cleaned up.
|
||||
return;
|
||||
}
|
||||
mLOHSCallbackProxy = null;
|
||||
try {
|
||||
mService.stopLocalOnlyHotspot();
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1922,7 +1968,18 @@ public class WifiManager {
|
||||
*/
|
||||
public void watchLocalOnlyHotspot(LocalOnlyHotspotObserver observer,
|
||||
@Nullable Handler handler) {
|
||||
throw new UnsupportedOperationException("LocalOnlyHotspot is still in development");
|
||||
synchronized (mLock) {
|
||||
Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper();
|
||||
mLOHSObserverProxy = new LocalOnlyHotspotObserverProxy(this, looper, observer);
|
||||
try {
|
||||
mService.startWatchLocalOnlyHotspot(
|
||||
mLOHSObserverProxy.getMessenger(), new Binder());
|
||||
mLOHSObserverProxy.registered();
|
||||
} catch (RemoteException e) {
|
||||
mLOHSObserverProxy = null;
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1932,10 +1989,20 @@ public class WifiManager {
|
||||
* @hide
|
||||
*/
|
||||
public void unregisterLocalOnlyHotspotObserver() {
|
||||
throw new UnsupportedOperationException("LocalOnlyHotspot is still in development");
|
||||
synchronized (mLock) {
|
||||
if (mLOHSObserverProxy == null) {
|
||||
// nothing to do, the callback was already cleaned up
|
||||
return;
|
||||
}
|
||||
mLOHSObserverProxy = null;
|
||||
try {
|
||||
mService.stopWatchLocalOnlyHotspot();
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the Wi-Fi enabled state.
|
||||
* @return One of {@link #WIFI_AP_STATE_DISABLED},
|
||||
@@ -2205,8 +2272,6 @@ public class WifiManager {
|
||||
* any further callbacks. If the LocalOnlyHotspot is stopped due to a
|
||||
* user triggered mode change, applications will be notified via the {@link
|
||||
* LocalOnlyHotspotCallback#onStopped()} callback.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class LocalOnlyHotspotReservation implements AutoCloseable {
|
||||
|
||||
@@ -2249,8 +2314,6 @@ public class WifiManager {
|
||||
|
||||
/**
|
||||
* Callback class for applications to receive updates about the LocalOnlyHotspot status.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static class LocalOnlyHotspotCallback {
|
||||
public static final int ERROR_NO_CHANNEL = 1;
|
||||
@@ -2282,6 +2345,88 @@ public class WifiManager {
|
||||
public void onFailed(int reason) { };
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback proxy for LocalOnlyHotspotCallback objects.
|
||||
*/
|
||||
private static class LocalOnlyHotspotCallbackProxy {
|
||||
private final Handler mHandler;
|
||||
private final WeakReference<WifiManager> mWifiManager;
|
||||
private final Looper mLooper;
|
||||
private final Messenger mMessenger;
|
||||
|
||||
/**
|
||||
* Constructs a {@link LocalOnlyHotspotCallback} using the specified looper. All callbacks
|
||||
* will be delivered on the thread of the specified looper.
|
||||
*
|
||||
* @param manager WifiManager
|
||||
* @param looper Looper for delivering callbacks
|
||||
* @param callback LocalOnlyHotspotCallback to notify the calling application.
|
||||
*/
|
||||
LocalOnlyHotspotCallbackProxy(WifiManager manager, Looper looper,
|
||||
final LocalOnlyHotspotCallback callback) {
|
||||
mWifiManager = new WeakReference<>(manager);
|
||||
mLooper = looper;
|
||||
|
||||
mHandler = new Handler(looper) {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
Log.d(TAG, "LocalOnlyHotspotCallbackProxy: handle message what: "
|
||||
+ msg.what + " msg: " + msg);
|
||||
|
||||
WifiManager manager = mWifiManager.get();
|
||||
if (manager == null) {
|
||||
Log.w(TAG, "LocalOnlyHotspotCallbackProxy: handle message post GC");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (msg.what) {
|
||||
case HOTSPOT_STARTED:
|
||||
WifiConfiguration config = (WifiConfiguration) msg.obj;
|
||||
if (config == null) {
|
||||
Log.e(TAG, "LocalOnlyHotspotCallbackProxy: config cannot be null.");
|
||||
callback.onFailed(LocalOnlyHotspotCallback.ERROR_GENERIC);
|
||||
return;
|
||||
}
|
||||
callback.onStarted(manager.new LocalOnlyHotspotReservation(config));
|
||||
break;
|
||||
case HOTSPOT_STOPPED:
|
||||
Log.w(TAG, "LocalOnlyHotspotCallbackProxy: hotspot stopped");
|
||||
callback.onStopped();
|
||||
break;
|
||||
case HOTSPOT_FAILED:
|
||||
int reasonCode = msg.arg1;
|
||||
Log.w(TAG, "LocalOnlyHotspotCallbackProxy: failed to start. reason: "
|
||||
+ reasonCode);
|
||||
callback.onFailed(reasonCode);
|
||||
Log.w(TAG, "done with the callback...");
|
||||
break;
|
||||
default:
|
||||
Log.e(TAG, "LocalOnlyHotspotCallbackProxy unhandled message. type: "
|
||||
+ msg.what);
|
||||
}
|
||||
}
|
||||
};
|
||||
mMessenger = new Messenger(mHandler);
|
||||
}
|
||||
|
||||
public Messenger getMessenger() {
|
||||
return mMessenger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method allowing the the incoming application call to move the onFailed callback
|
||||
* over to the desired callback thread.
|
||||
*
|
||||
* @param reason int representing the error type
|
||||
*/
|
||||
public void notifyFailed(int reason) throws RemoteException {
|
||||
Message msg = Message.obtain();
|
||||
msg.what = HOTSPOT_FAILED;
|
||||
msg.arg1 = reason;
|
||||
mMessenger.send(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* LocalOnlyHotspotSubscription that is an AutoCloseable object for tracking applications
|
||||
* watching for LocalOnlyHotspot changes.
|
||||
@@ -2291,7 +2436,6 @@ public class WifiManager {
|
||||
public class LocalOnlyHotspotSubscription implements AutoCloseable {
|
||||
private final CloseGuard mCloseGuard = CloseGuard.get();
|
||||
|
||||
/** @hide */
|
||||
@VisibleForTesting
|
||||
public LocalOnlyHotspotSubscription() {
|
||||
mCloseGuard.open("close");
|
||||
@@ -2343,6 +2487,75 @@ public class WifiManager {
|
||||
public void onStopped() {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback proxy for LocalOnlyHotspotObserver objects.
|
||||
*/
|
||||
private static class LocalOnlyHotspotObserverProxy {
|
||||
private final Handler mHandler;
|
||||
private final WeakReference<WifiManager> mWifiManager;
|
||||
private final Looper mLooper;
|
||||
private final Messenger mMessenger;
|
||||
|
||||
/**
|
||||
* Constructs a {@link LocalOnlyHotspotObserverProxy} using the specified looper.
|
||||
* All callbacks will be delivered on the thread of the specified looper.
|
||||
*
|
||||
* @param manager WifiManager
|
||||
* @param looper Looper for delivering callbacks
|
||||
* @param observer LocalOnlyHotspotObserver to notify the calling application.
|
||||
*/
|
||||
LocalOnlyHotspotObserverProxy(WifiManager manager, Looper looper,
|
||||
final LocalOnlyHotspotObserver observer) {
|
||||
mWifiManager = new WeakReference<>(manager);
|
||||
mLooper = looper;
|
||||
|
||||
mHandler = new Handler(looper) {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
Log.d(TAG, "LocalOnlyHotspotObserverProxy: handle message what: "
|
||||
+ msg.what + " msg: " + msg);
|
||||
|
||||
WifiManager manager = mWifiManager.get();
|
||||
if (manager == null) {
|
||||
Log.w(TAG, "LocalOnlyHotspotObserverProxy: handle message post GC");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (msg.what) {
|
||||
case HOTSPOT_OBSERVER_REGISTERED:
|
||||
observer.onRegistered(manager.new LocalOnlyHotspotSubscription());
|
||||
break;
|
||||
case HOTSPOT_STARTED:
|
||||
WifiConfiguration config = (WifiConfiguration) msg.obj;
|
||||
if (config == null) {
|
||||
Log.e(TAG, "LocalOnlyHotspotObserverProxy: config cannot be null.");
|
||||
return;
|
||||
}
|
||||
observer.onStarted(config);
|
||||
break;
|
||||
case HOTSPOT_STOPPED:
|
||||
observer.onStopped();
|
||||
break;
|
||||
default:
|
||||
Log.e(TAG, "LocalOnlyHotspotObserverProxy unhandled message. type: "
|
||||
+ msg.what);
|
||||
}
|
||||
}
|
||||
};
|
||||
mMessenger = new Messenger(mHandler);
|
||||
}
|
||||
|
||||
public Messenger getMessenger() {
|
||||
return mMessenger;
|
||||
}
|
||||
|
||||
public void registered() throws RemoteException {
|
||||
Message msg = Message.obtain();
|
||||
msg.what = HOTSPOT_OBSERVER_REGISTERED;
|
||||
mMessenger.send(msg);
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that multiple ServiceHandler threads do not interleave message dispatch.
|
||||
private static final Object sServiceHandlerDispatchLock = new Object();
|
||||
|
||||
|
||||
761
wifi/tests/src/android/net/wifi/WifiManagerTest.java
Normal file
761
wifi/tests/src/android/net/wifi/WifiManagerTest.java
Normal file
@@ -0,0 +1,761 @@
|
||||
/*
|
||||
* 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 android.net.wifi;
|
||||
|
||||
import static android.net.wifi.WifiManager.HOTSPOT_FAILED;
|
||||
import static android.net.wifi.WifiManager.HOTSPOT_STARTED;
|
||||
import static android.net.wifi.WifiManager.HOTSPOT_STOPPED;
|
||||
import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_GENERIC;
|
||||
import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE;
|
||||
import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_NO_CHANNEL;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.net.wifi.WifiManager.LocalOnlyHotspotCallback;
|
||||
import android.net.wifi.WifiManager.LocalOnlyHotspotObserver;
|
||||
import android.net.wifi.WifiManager.LocalOnlyHotspotReservation;
|
||||
import android.net.wifi.WifiManager.LocalOnlyHotspotSubscription;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
import android.os.test.TestLooper;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link android.net.wifi.WifiManager}.
|
||||
*/
|
||||
@SmallTest
|
||||
public class WifiManagerTest {
|
||||
|
||||
private static final int ERROR_NOT_SET = -1;
|
||||
private static final int ERROR_TEST_REASON = 5;
|
||||
|
||||
@Mock Context mContext;
|
||||
@Mock IWifiManager mWifiService;
|
||||
@Mock ApplicationInfo mApplicationInfo;
|
||||
@Mock WifiConfiguration mApConfig;
|
||||
@Mock IBinder mAppBinder;
|
||||
|
||||
private Handler mHandler;
|
||||
private TestLooper mLooper;
|
||||
private WifiManager mWifiManager;
|
||||
private Messenger mWifiServiceMessenger;
|
||||
final ArgumentCaptor<Messenger> mMessengerCaptor = ArgumentCaptor.forClass(Messenger.class);
|
||||
|
||||
@Before public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mLooper = new TestLooper();
|
||||
mHandler = spy(new Handler(mLooper.getLooper()));
|
||||
when(mContext.getApplicationInfo()).thenReturn(mApplicationInfo);
|
||||
|
||||
mWifiServiceMessenger = new Messenger(mHandler);
|
||||
mWifiManager = new WifiManager(mContext, mWifiService, mLooper.getLooper());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the call to startSoftAp calls WifiService to startSoftAp with the provided
|
||||
* WifiConfiguration. Verify that the return value is propagated to the caller.
|
||||
*/
|
||||
@Test
|
||||
public void testStartSoftApCallsServiceWithWifiConfig() throws Exception {
|
||||
when(mWifiService.startSoftAp(eq(mApConfig))).thenReturn(true);
|
||||
assertTrue(mWifiManager.startSoftAp(mApConfig));
|
||||
|
||||
when(mWifiService.startSoftAp(eq(mApConfig))).thenReturn(false);
|
||||
assertFalse(mWifiManager.startSoftAp(mApConfig));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the call to startSoftAp calls WifiService to startSoftAp with a null config. Verify
|
||||
* that the return value is propagated to the caller.
|
||||
*/
|
||||
@Test
|
||||
public void testStartSoftApCallsServiceWithNullConfig() throws Exception {
|
||||
when(mWifiService.startSoftAp(eq(null))).thenReturn(true);
|
||||
assertTrue(mWifiManager.startSoftAp(null));
|
||||
|
||||
when(mWifiService.startSoftAp(eq(null))).thenReturn(false);
|
||||
assertFalse(mWifiManager.startSoftAp(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the call to stopSoftAp calls WifiService to stopSoftAp.
|
||||
*/
|
||||
@Test
|
||||
public void testStopSoftApCallsService() throws Exception {
|
||||
when(mWifiService.stopSoftAp()).thenReturn(true);
|
||||
assertTrue(mWifiManager.stopSoftAp());
|
||||
|
||||
when(mWifiService.stopSoftAp()).thenReturn(false);
|
||||
assertFalse(mWifiManager.stopSoftAp());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test creation of a LocalOnlyHotspotReservation and verify that close properly calls
|
||||
* WifiService.stopLocalOnlyHotspot.
|
||||
*/
|
||||
@Test
|
||||
public void testCreationAndCloseOfLocalOnlyHotspotReservation() throws Exception {
|
||||
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
|
||||
when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
|
||||
.thenReturn(mApConfig);
|
||||
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
|
||||
|
||||
callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(mApConfig));
|
||||
|
||||
assertEquals(mApConfig, callback.mRes.getConfig());
|
||||
callback.mRes.close();
|
||||
verify(mWifiService).stopLocalOnlyHotspot();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify stopLOHS is called when try-with-resources is used properly.
|
||||
*/
|
||||
@Test
|
||||
public void testLocalOnlyHotspotReservationCallsStopProperlyInTryWithResources()
|
||||
throws Exception {
|
||||
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
|
||||
when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
|
||||
.thenReturn(mApConfig);
|
||||
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
|
||||
|
||||
callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(mApConfig));
|
||||
|
||||
try (WifiManager.LocalOnlyHotspotReservation res = callback.mRes) {
|
||||
assertEquals(mApConfig, res.getConfig());
|
||||
}
|
||||
|
||||
verify(mWifiService).stopLocalOnlyHotspot();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test creation of a LocalOnlyHotspotSubscription.
|
||||
* TODO: when registrations are tracked, verify removal on close.
|
||||
*/
|
||||
@Test
|
||||
public void testCreationOfLocalOnlyHotspotSubscription() throws Exception {
|
||||
try (WifiManager.LocalOnlyHotspotSubscription sub =
|
||||
mWifiManager.new LocalOnlyHotspotSubscription()) {
|
||||
sub.close();
|
||||
}
|
||||
}
|
||||
|
||||
public class TestLocalOnlyHotspotCallback extends LocalOnlyHotspotCallback {
|
||||
public boolean mOnStartedCalled = false;
|
||||
public boolean mOnStoppedCalled = false;
|
||||
public int mFailureReason = -1;
|
||||
public LocalOnlyHotspotReservation mRes = null;
|
||||
public long mCallingThreadId = -1;
|
||||
|
||||
@Override
|
||||
public void onStarted(LocalOnlyHotspotReservation r) {
|
||||
mRes = r;
|
||||
mOnStartedCalled = true;
|
||||
mCallingThreadId = Thread.currentThread().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopped() {
|
||||
mOnStoppedCalled = true;
|
||||
mCallingThreadId = Thread.currentThread().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(int reason) {
|
||||
mFailureReason = reason;
|
||||
mCallingThreadId = Thread.currentThread().getId();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify callback is properly plumbed when called.
|
||||
*/
|
||||
@Test
|
||||
public void testLocalOnlyHotspotCallback() {
|
||||
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
|
||||
assertFalse(callback.mOnStartedCalled);
|
||||
assertFalse(callback.mOnStoppedCalled);
|
||||
assertEquals(ERROR_NOT_SET, callback.mFailureReason);
|
||||
assertEquals(null, callback.mRes);
|
||||
|
||||
// test onStarted
|
||||
WifiManager.LocalOnlyHotspotReservation res =
|
||||
mWifiManager.new LocalOnlyHotspotReservation(mApConfig);
|
||||
callback.onStarted(res);
|
||||
assertEquals(res, callback.mRes);
|
||||
assertTrue(callback.mOnStartedCalled);
|
||||
assertFalse(callback.mOnStoppedCalled);
|
||||
assertEquals(ERROR_NOT_SET, callback.mFailureReason);
|
||||
|
||||
// test onStopped
|
||||
callback.onStopped();
|
||||
assertEquals(res, callback.mRes);
|
||||
assertTrue(callback.mOnStartedCalled);
|
||||
assertTrue(callback.mOnStoppedCalled);
|
||||
assertEquals(ERROR_NOT_SET, callback.mFailureReason);
|
||||
|
||||
// test onFailed
|
||||
callback.onFailed(ERROR_TEST_REASON);
|
||||
assertEquals(res, callback.mRes);
|
||||
assertTrue(callback.mOnStartedCalled);
|
||||
assertTrue(callback.mOnStoppedCalled);
|
||||
assertEquals(ERROR_TEST_REASON, callback.mFailureReason);
|
||||
}
|
||||
|
||||
public class TestLocalOnlyHotspotObserver extends LocalOnlyHotspotObserver {
|
||||
public boolean mOnRegistered = false;
|
||||
public boolean mOnStartedCalled = false;
|
||||
public boolean mOnStoppedCalled = false;
|
||||
public WifiConfiguration mConfig = null;
|
||||
public LocalOnlyHotspotSubscription mSub = null;
|
||||
public long mCallingThreadId = -1;
|
||||
|
||||
@Override
|
||||
public void onRegistered(LocalOnlyHotspotSubscription sub) {
|
||||
mOnRegistered = true;
|
||||
mSub = sub;
|
||||
mCallingThreadId = Thread.currentThread().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStarted(WifiConfiguration config) {
|
||||
mOnStartedCalled = true;
|
||||
mConfig = config;
|
||||
mCallingThreadId = Thread.currentThread().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopped() {
|
||||
mOnStoppedCalled = true;
|
||||
mCallingThreadId = Thread.currentThread().getId();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify observer is properly plumbed when called.
|
||||
*/
|
||||
@Test
|
||||
public void testLocalOnlyHotspotObserver() {
|
||||
TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
|
||||
assertFalse(observer.mOnRegistered);
|
||||
assertFalse(observer.mOnStartedCalled);
|
||||
assertFalse(observer.mOnStoppedCalled);
|
||||
assertEquals(null, observer.mConfig);
|
||||
assertEquals(null, observer.mSub);
|
||||
|
||||
WifiManager.LocalOnlyHotspotSubscription sub =
|
||||
mWifiManager.new LocalOnlyHotspotSubscription();
|
||||
observer.onRegistered(sub);
|
||||
assertTrue(observer.mOnRegistered);
|
||||
assertFalse(observer.mOnStartedCalled);
|
||||
assertFalse(observer.mOnStoppedCalled);
|
||||
assertEquals(null, observer.mConfig);
|
||||
assertEquals(sub, observer.mSub);
|
||||
|
||||
observer.onStarted(mApConfig);
|
||||
assertTrue(observer.mOnRegistered);
|
||||
assertTrue(observer.mOnStartedCalled);
|
||||
assertFalse(observer.mOnStoppedCalled);
|
||||
assertEquals(mApConfig, observer.mConfig);
|
||||
assertEquals(sub, observer.mSub);
|
||||
|
||||
observer.onStopped();
|
||||
assertTrue(observer.mOnRegistered);
|
||||
assertTrue(observer.mOnStartedCalled);
|
||||
assertTrue(observer.mOnStoppedCalled);
|
||||
assertEquals(mApConfig, observer.mConfig);
|
||||
assertEquals(sub, observer.mSub);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify call to startLocalOnlyHotspot goes to WifiServiceImpl.
|
||||
*/
|
||||
@Test
|
||||
public void testStartLocalOnlyHotspot() throws Exception {
|
||||
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
|
||||
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
|
||||
|
||||
verify(mWifiService).startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify a SecurityException is thrown for callers without proper permissions for
|
||||
* startLocalOnlyHotspot.
|
||||
*/
|
||||
@Test(expected = SecurityException.class)
|
||||
public void testStartLocalOnlyHotspotThrowsSecurityException() throws Exception {
|
||||
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
|
||||
doThrow(new SecurityException()).when(mWifiService)
|
||||
.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class));
|
||||
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify an IllegalStateException is thrown for callers that already have a pending request for
|
||||
* startLocalOnlyHotspot.
|
||||
*/
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void testStartLocalOnlyHotspotThrowsIllegalStateException() throws Exception {
|
||||
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
|
||||
doThrow(new IllegalStateException()).when(mWifiService)
|
||||
.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class));
|
||||
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that the handler provided by the caller is used for the callbacks.
|
||||
*/
|
||||
@Test
|
||||
public void testCorrectLooperIsUsedForHandler() throws Exception {
|
||||
// record thread from looper.getThread and check ids.
|
||||
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
|
||||
when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
|
||||
.thenReturn(null);
|
||||
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
|
||||
mLooper.dispatchAll();
|
||||
assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
|
||||
assertEquals(mLooper.getLooper().getThread().getId(), callback.mCallingThreadId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that the main looper's thread is used if a handler is not provided by the reqiestomg
|
||||
* application.
|
||||
*/
|
||||
@Test
|
||||
public void testMainLooperIsUsedWhenHandlerNotProvided() throws Exception {
|
||||
// record thread from looper.getThread and check ids.
|
||||
TestLooper altLooper = new TestLooper();
|
||||
when(mContext.getMainLooper()).thenReturn(altLooper.getLooper());
|
||||
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
|
||||
when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
|
||||
.thenReturn(null);
|
||||
mWifiManager.startLocalOnlyHotspot(callback, null);
|
||||
altLooper.dispatchAll();
|
||||
assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
|
||||
assertEquals(altLooper.getLooper().getThread().getId(), callback.mCallingThreadId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the LOHS onStarted callback is triggered when WifiManager receives a HOTSPOT_STARTED
|
||||
* message from WifiServiceImpl.
|
||||
*/
|
||||
@Test
|
||||
public void testOnStartedIsCalledWithReservation() throws Exception {
|
||||
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
|
||||
TestLooper callbackLooper = new TestLooper();
|
||||
Handler callbackHandler = new Handler(callbackLooper.getLooper());
|
||||
when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(),
|
||||
any(IBinder.class))).thenReturn(mApConfig);
|
||||
mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
|
||||
callbackLooper.dispatchAll();
|
||||
mLooper.dispatchAll();
|
||||
assertFalse(callback.mOnStartedCalled);
|
||||
assertEquals(null, callback.mRes);
|
||||
// now trigger the callback
|
||||
Message msg = new Message();
|
||||
msg.what = HOTSPOT_STARTED;
|
||||
msg.obj = mApConfig;
|
||||
mMessengerCaptor.getValue().send(msg);
|
||||
mLooper.dispatchAll();
|
||||
callbackLooper.dispatchAll();
|
||||
assertTrue(callback.mOnStartedCalled);
|
||||
assertEquals(mApConfig, callback.mRes.getConfig());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify onFailed is called if WifiServiceImpl sends a HOTSPOT_STARTED message with a null
|
||||
* config.
|
||||
*/
|
||||
@Test
|
||||
public void testOnStartedIsCalledWithNullConfig() throws Exception {
|
||||
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
|
||||
TestLooper callbackLooper = new TestLooper();
|
||||
Handler callbackHandler = new Handler(callbackLooper.getLooper());
|
||||
when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(),
|
||||
any(IBinder.class))).thenReturn(mApConfig);
|
||||
mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
|
||||
callbackLooper.dispatchAll();
|
||||
mLooper.dispatchAll();
|
||||
assertFalse(callback.mOnStartedCalled);
|
||||
assertEquals(null, callback.mRes);
|
||||
// now trigger the callback
|
||||
Message msg = new Message();
|
||||
msg.what = HOTSPOT_STARTED;
|
||||
mMessengerCaptor.getValue().send(msg);
|
||||
mLooper.dispatchAll();
|
||||
callbackLooper.dispatchAll();
|
||||
assertFalse(callback.mOnStartedCalled);
|
||||
assertEquals(ERROR_GENERIC, callback.mFailureReason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify onStopped is called if WifiServiceImpl sends a HOTSPOT_STOPPED message.
|
||||
*/
|
||||
@Test
|
||||
public void testOnStoppedIsCalled() throws Exception {
|
||||
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
|
||||
TestLooper callbackLooper = new TestLooper();
|
||||
Handler callbackHandler = new Handler(callbackLooper.getLooper());
|
||||
when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(),
|
||||
any(IBinder.class))).thenReturn(mApConfig);
|
||||
mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
|
||||
callbackLooper.dispatchAll();
|
||||
mLooper.dispatchAll();
|
||||
assertFalse(callback.mOnStoppedCalled);
|
||||
// now trigger the callback
|
||||
Message msg = new Message();
|
||||
msg.what = HOTSPOT_STOPPED;
|
||||
mMessengerCaptor.getValue().send(msg);
|
||||
mLooper.dispatchAll();
|
||||
callbackLooper.dispatchAll();
|
||||
assertTrue(callback.mOnStoppedCalled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify onFailed is called if WifiServiceImpl sends a HOTSPOT_FAILED message.
|
||||
*/
|
||||
@Test
|
||||
public void testOnFailedIsCalled() throws Exception {
|
||||
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
|
||||
TestLooper callbackLooper = new TestLooper();
|
||||
Handler callbackHandler = new Handler(callbackLooper.getLooper());
|
||||
when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(),
|
||||
any(IBinder.class))).thenReturn(mApConfig);
|
||||
mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
|
||||
callbackLooper.dispatchAll();
|
||||
mLooper.dispatchAll();
|
||||
assertEquals(ERROR_NOT_SET, callback.mFailureReason);
|
||||
// now trigger the callback
|
||||
Message msg = new Message();
|
||||
msg.what = HOTSPOT_FAILED;
|
||||
msg.arg1 = ERROR_NO_CHANNEL;
|
||||
mMessengerCaptor.getValue().send(msg);
|
||||
mLooper.dispatchAll();
|
||||
callbackLooper.dispatchAll();
|
||||
assertEquals(ERROR_NO_CHANNEL, callback.mFailureReason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the handler passed in to startLocalOnlyHotspot is correctly used for callbacks when a
|
||||
* null WifiConfig is returned.
|
||||
*/
|
||||
@Test
|
||||
public void testLocalOnlyHotspotCallbackFullOnNullConfig() throws Exception {
|
||||
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
|
||||
when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
|
||||
.thenReturn(null);
|
||||
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
|
||||
mLooper.dispatchAll();
|
||||
assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
|
||||
assertFalse(callback.mOnStartedCalled);
|
||||
assertFalse(callback.mOnStoppedCalled);
|
||||
assertEquals(null, callback.mRes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify a SecurityException resulting from an application without necessary permissions will
|
||||
* bubble up through the call to start LocalOnlyHotspot and will not trigger other callbacks.
|
||||
*/
|
||||
@Test(expected = SecurityException.class)
|
||||
public void testLocalOnlyHotspotCallbackFullOnSecurityException() throws Exception {
|
||||
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
|
||||
doThrow(new SecurityException()).when(mWifiService)
|
||||
.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class));
|
||||
try {
|
||||
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
|
||||
} catch (SecurityException e) {
|
||||
assertEquals(ERROR_NOT_SET, callback.mFailureReason);
|
||||
assertFalse(callback.mOnStartedCalled);
|
||||
assertFalse(callback.mOnStoppedCalled);
|
||||
assertEquals(null, callback.mRes);
|
||||
throw e;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the handler passed to startLocalOnlyHotspot is correctly used for callbacks when
|
||||
* SoftApMode fails due to a underlying error.
|
||||
*/
|
||||
@Test
|
||||
public void testLocalOnlyHotspotCallbackFullOnNoChannelError() throws Exception {
|
||||
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
|
||||
when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
|
||||
.thenReturn(mApConfig);
|
||||
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
|
||||
mLooper.dispatchAll();
|
||||
//assertEquals(ERROR_NO_CHANNEL, callback.mFailureReason);
|
||||
assertFalse(callback.mOnStartedCalled);
|
||||
assertFalse(callback.mOnStoppedCalled);
|
||||
assertEquals(null, callback.mRes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that the call to cancel a LOHS request does call stopLOHS.
|
||||
*/
|
||||
@Test
|
||||
public void testCancelLocalOnlyHotspotRequestCallsStopOnWifiService() throws Exception {
|
||||
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
|
||||
when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
|
||||
.thenReturn(mApConfig);
|
||||
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
|
||||
mWifiManager.cancelLocalOnlyHotspotRequest();
|
||||
verify(mWifiService).stopLocalOnlyHotspot();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that we do not crash if cancelLocalOnlyHotspotRequest is called without an existing
|
||||
* callback stored.
|
||||
*/
|
||||
@Test
|
||||
public void testCancelLocalOnlyHotspotReturnsWithoutExistingRequest() {
|
||||
mWifiManager.cancelLocalOnlyHotspotRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that the callback is not triggered if the LOHS request was already cancelled.
|
||||
*/
|
||||
@Test
|
||||
public void testCallbackAfterLocalOnlyHotspotWasCancelled() throws Exception {
|
||||
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
|
||||
when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
|
||||
.thenReturn(mApConfig);
|
||||
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
|
||||
mWifiManager.cancelLocalOnlyHotspotRequest();
|
||||
verify(mWifiService).stopLocalOnlyHotspot();
|
||||
mLooper.dispatchAll();
|
||||
assertEquals(ERROR_NOT_SET, callback.mFailureReason);
|
||||
assertFalse(callback.mOnStartedCalled);
|
||||
assertFalse(callback.mOnStoppedCalled);
|
||||
assertEquals(null, callback.mRes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that calling cancel LOHS request does not crash if an error callback was already
|
||||
* handled.
|
||||
*/
|
||||
@Test
|
||||
public void testCancelAfterLocalOnlyHotspotCallbackTriggered() throws Exception {
|
||||
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
|
||||
when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
|
||||
.thenReturn(null);
|
||||
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
|
||||
mLooper.dispatchAll();
|
||||
assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
|
||||
assertFalse(callback.mOnStartedCalled);
|
||||
assertFalse(callback.mOnStoppedCalled);
|
||||
assertEquals(null, callback.mRes);
|
||||
mWifiManager.cancelLocalOnlyHotspotRequest();
|
||||
verify(mWifiService, never()).stopLocalOnlyHotspot();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the watchLocalOnlyHotspot call goes to WifiServiceImpl.
|
||||
*/
|
||||
public void testWatchLocalOnlyHotspot() throws Exception {
|
||||
TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
|
||||
|
||||
mWifiManager.watchLocalOnlyHotspot(observer, mHandler);
|
||||
verify(mWifiService).startWatchLocalOnlyHotspot(any(Messenger.class), any(IBinder.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify a SecurityException is thrown for callers without proper permissions for
|
||||
* startWatchLocalOnlyHotspot.
|
||||
*/
|
||||
@Test(expected = SecurityException.class)
|
||||
public void testStartWatchLocalOnlyHotspotThrowsSecurityException() throws Exception {
|
||||
TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
|
||||
doThrow(new SecurityException()).when(mWifiService)
|
||||
.startWatchLocalOnlyHotspot(any(Messenger.class), any(IBinder.class));
|
||||
mWifiManager.watchLocalOnlyHotspot(observer, mHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify an IllegalStateException is thrown for callers that already have a pending request for
|
||||
* watchLocalOnlyHotspot.
|
||||
*/
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void testStartWatchLocalOnlyHotspotThrowsIllegalStateException() throws Exception {
|
||||
TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
|
||||
doThrow(new IllegalStateException()).when(mWifiService)
|
||||
.startWatchLocalOnlyHotspot(any(Messenger.class), any(IBinder.class));
|
||||
mWifiManager.watchLocalOnlyHotspot(observer, mHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that the handler provided by the caller is used for the observer.
|
||||
*/
|
||||
@Test
|
||||
public void testCorrectLooperIsUsedForObserverHandler() throws Exception {
|
||||
// record thread from looper.getThread and check ids.
|
||||
TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
|
||||
mWifiManager.watchLocalOnlyHotspot(observer, mHandler);
|
||||
mLooper.dispatchAll();
|
||||
assertTrue(observer.mOnRegistered);
|
||||
assertEquals(mLooper.getLooper().getThread().getId(), observer.mCallingThreadId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that the main looper's thread is used if a handler is not provided by the requesting
|
||||
* application.
|
||||
*/
|
||||
@Test
|
||||
public void testMainLooperIsUsedWhenHandlerNotProvidedForObserver() throws Exception {
|
||||
// record thread from looper.getThread and check ids.
|
||||
TestLooper altLooper = new TestLooper();
|
||||
when(mContext.getMainLooper()).thenReturn(altLooper.getLooper());
|
||||
TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
|
||||
mWifiManager.watchLocalOnlyHotspot(observer, null);
|
||||
altLooper.dispatchAll();
|
||||
assertTrue(observer.mOnRegistered);
|
||||
assertEquals(altLooper.getLooper().getThread().getId(), observer.mCallingThreadId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the LOHS onRegistered observer callback is triggered when WifiManager receives a
|
||||
* HOTSPOT_OBSERVER_REGISTERED message from WifiServiceImpl.
|
||||
*/
|
||||
@Test
|
||||
public void testOnRegisteredIsCalledWithSubscription() throws Exception {
|
||||
TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
|
||||
TestLooper observerLooper = new TestLooper();
|
||||
Handler observerHandler = new Handler(observerLooper.getLooper());
|
||||
assertFalse(observer.mOnRegistered);
|
||||
assertEquals(null, observer.mSub);
|
||||
mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
|
||||
verify(mWifiService).startWatchLocalOnlyHotspot(mMessengerCaptor.capture(),
|
||||
any(IBinder.class));
|
||||
// now trigger the callback
|
||||
observerLooper.dispatchAll();
|
||||
mLooper.dispatchAll();
|
||||
assertTrue(observer.mOnRegistered);
|
||||
assertNotNull(observer.mSub);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the LOHS onStarted observer callback is triggered when WifiManager receives a
|
||||
* HOTSPOT_STARTED message from WifiServiceImpl.
|
||||
*/
|
||||
@Test
|
||||
public void testObserverOnStartedIsCalledWithWifiConfig() throws Exception {
|
||||
TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
|
||||
TestLooper observerLooper = new TestLooper();
|
||||
Handler observerHandler = new Handler(observerLooper.getLooper());
|
||||
mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
|
||||
verify(mWifiService).startWatchLocalOnlyHotspot(mMessengerCaptor.capture(),
|
||||
any(IBinder.class));
|
||||
observerLooper.dispatchAll();
|
||||
mLooper.dispatchAll();
|
||||
assertFalse(observer.mOnStartedCalled);
|
||||
// now trigger the callback
|
||||
Message msg = new Message();
|
||||
msg.what = HOTSPOT_STARTED;
|
||||
msg.obj = mApConfig;
|
||||
mMessengerCaptor.getValue().send(msg);
|
||||
mLooper.dispatchAll();
|
||||
observerLooper.dispatchAll();
|
||||
assertTrue(observer.mOnStartedCalled);
|
||||
assertEquals(mApConfig, observer.mConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the LOHS onStarted observer callback is triggered not when WifiManager receives a
|
||||
* HOTSPOT_STARTED message from WifiServiceImpl with a null config.
|
||||
*/
|
||||
@Test
|
||||
public void testObserverOnStartedNotCalledWithNullConfig() throws Exception {
|
||||
TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
|
||||
TestLooper observerLooper = new TestLooper();
|
||||
Handler observerHandler = new Handler(observerLooper.getLooper());
|
||||
mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
|
||||
verify(mWifiService).startWatchLocalOnlyHotspot(mMessengerCaptor.capture(),
|
||||
any(IBinder.class));
|
||||
observerLooper.dispatchAll();
|
||||
mLooper.dispatchAll();
|
||||
assertFalse(observer.mOnStartedCalled);
|
||||
// now trigger the callback
|
||||
Message msg = new Message();
|
||||
msg.what = HOTSPOT_STARTED;
|
||||
mMessengerCaptor.getValue().send(msg);
|
||||
mLooper.dispatchAll();
|
||||
observerLooper.dispatchAll();
|
||||
assertFalse(observer.mOnStartedCalled);
|
||||
assertEquals(null, observer.mConfig);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verify the LOHS onStopped observer callback is triggered when WifiManager receives a
|
||||
* HOTSPOT_STOPPED message from WifiServiceImpl.
|
||||
*/
|
||||
@Test
|
||||
public void testObserverOnStoppedIsCalled() throws Exception {
|
||||
TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
|
||||
TestLooper observerLooper = new TestLooper();
|
||||
Handler observerHandler = new Handler(observerLooper.getLooper());
|
||||
mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
|
||||
verify(mWifiService).startWatchLocalOnlyHotspot(mMessengerCaptor.capture(),
|
||||
any(IBinder.class));
|
||||
observerLooper.dispatchAll();
|
||||
mLooper.dispatchAll();
|
||||
assertFalse(observer.mOnStoppedCalled);
|
||||
// now trigger the callback
|
||||
Message msg = new Message();
|
||||
msg.what = HOTSPOT_STOPPED;
|
||||
mMessengerCaptor.getValue().send(msg);
|
||||
mLooper.dispatchAll();
|
||||
observerLooper.dispatchAll();
|
||||
assertTrue(observer.mOnStoppedCalled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify WifiServiceImpl is not called if there is not a registered LOHS observer callback.
|
||||
*/
|
||||
@Test
|
||||
public void testUnregisterWifiServiceImplNotCalledWithoutRegisteredObserver() throws Exception {
|
||||
mWifiManager.unregisterLocalOnlyHotspotObserver();
|
||||
verifyZeroInteractions(mWifiService);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify WifiServiceImpl is called when there is a registered LOHS observer callback.
|
||||
*/
|
||||
@Test
|
||||
public void testUnregisterWifiServiceImplCalledWithRegisteredObserver() throws Exception {
|
||||
TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
|
||||
TestLooper observerLooper = new TestLooper();
|
||||
Handler observerHandler = new Handler(observerLooper.getLooper());
|
||||
mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
|
||||
mWifiManager.unregisterLocalOnlyHotspotObserver();
|
||||
verify(mWifiService).stopWatchLocalOnlyHotspot();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user