diff options
author | 2019-09-24 13:32:11 +0000 | |
---|---|---|
committer | 2019-09-24 13:32:11 +0000 | |
commit | 718a048728f7ca8ad6491c9161cb43864abb68fe (patch) | |
tree | 4e470201b469201178d326959b2d65be3d1d0cc1 | |
parent | e75b4a7d08268e802d21af16ab624710e924030a (diff) | |
parent | f145e1732e2db55007e338b8b64b7dd9497d1988 (diff) |
Merge changes from topics "clientmodeimpl_api_cleanup", "remove_wifi_set_country_code_api", "wifimanager_async_remove"
* changes:
TestLooper: Some changes to test looper behavior
WifiManager: Remove setCountryCode API
WifiManager: Remove async channel usage
-rw-r--r-- | api/system-current.txt | 2 | ||||
-rw-r--r-- | tests/utils/testutils/java/android/os/test/TestLooper.java | 38 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/IActionListener.aidl | 27 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/ITxPacketCountListener.aidl | 27 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/IWifiManager.aidl | 14 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/RssiPacketCountInfo.java | 75 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/WifiManager.java | 404 | ||||
-rw-r--r-- | wifi/java/com/android/server/wifi/BaseWifiService.java | 30 | ||||
-rw-r--r-- | wifi/tests/src/android/net/wifi/WifiManagerTest.java | 114 |
9 files changed, 366 insertions, 365 deletions
diff --git a/api/system-current.txt b/api/system-current.txt index d31bfeb9138d..3d1247f96d48 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -4722,7 +4722,7 @@ package android.net.wifi { method @RequiresPermission("android.permission.WIFI_UPDATE_USABILITY_STATS_SCORE") public void addOnWifiUsabilityStatsListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.OnWifiUsabilityStatsListener); method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void connect(@NonNull android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiManager.ActionListener); method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void connect(int, @Nullable android.net.wifi.WifiManager.ActionListener); - method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void disable(int, @Nullable android.net.wifi.WifiManager.ActionListener); + method @Deprecated @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void disable(int, @Nullable android.net.wifi.WifiManager.ActionListener); method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void forget(int, @Nullable android.net.wifi.WifiManager.ActionListener); method @NonNull @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.List<android.util.Pair<android.net.wifi.WifiConfiguration,java.util.Map<java.lang.Integer,java.util.List<android.net.wifi.ScanResult>>>> getAllMatchingWifiConfigs(@NonNull java.util.List<android.net.wifi.ScanResult>); method @NonNull @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.Map<android.net.wifi.hotspot2.OsuProvider,java.util.List<android.net.wifi.ScanResult>> getMatchingOsuProviders(@Nullable java.util.List<android.net.wifi.ScanResult>); diff --git a/tests/utils/testutils/java/android/os/test/TestLooper.java b/tests/utils/testutils/java/android/os/test/TestLooper.java index a49eda3d86d0..01bd47b9c608 100644 --- a/tests/utils/testutils/java/android/os/test/TestLooper.java +++ b/tests/utils/testutils/java/android/os/test/TestLooper.java @@ -210,33 +210,36 @@ public class TestLooper { /** * Run method for the auto dispatch thread. * The thread loops a maximum of MAX_LOOPS times with a 10ms sleep between loops. - * The thread continues looping and attempting to dispatch all messages until at - * least one message has been dispatched. + * The thread continues looping and attempting to dispatch all messages until + * {@link #stopAutoDispatch()} has been invoked. */ @Override public void run() { int dispatchCount = 0; for (int i = 0; i < MAX_LOOPS; i++) { try { - dispatchCount = dispatchAll(); + dispatchCount += dispatchAll(); } catch (RuntimeException e) { mAutoDispatchException = e; - } - Log.d(TAG, "dispatched " + dispatchCount + " messages"); - if (dispatchCount > 0) { return; } + Log.d(TAG, "dispatched " + dispatchCount + " messages"); try { Thread.sleep(LOOP_SLEEP_TIME_MS); } catch (InterruptedException e) { - mAutoDispatchException = new IllegalStateException( - "stopAutoDispatch called before any messages were dispatched."); + if (dispatchCount == 0) { + Log.e(TAG, "stopAutoDispatch called before any messages were dispatched."); + mAutoDispatchException = new IllegalStateException( + "stopAutoDispatch called before any messages were dispatched."); + } return; } } - Log.e(TAG, "AutoDispatchThread did not dispatch any messages."); - mAutoDispatchException = new IllegalStateException( - "TestLooper did not dispatch any messages before exiting."); + if (dispatchCount == 0) { + Log.e(TAG, "AutoDispatchThread did not dispatch any messages."); + mAutoDispatchException = new IllegalStateException( + "TestLooper did not dispatch any messages before exiting."); + } } /** @@ -287,4 +290,17 @@ public class TestLooper { "stopAutoDispatch called without startAutoDispatch."); } } + + /** + * If an AutoDispatchThread is currently running, stop and clean up. + * This method ignores exceptions raised for indicating that no messages were dispatched. + */ + public void stopAutoDispatchAndIgnoreExceptions() { + try { + stopAutoDispatch(); + } catch (IllegalStateException e) { + Log.e(TAG, "stopAutoDispatch", e); + } + + } } diff --git a/wifi/java/android/net/wifi/IActionListener.aidl b/wifi/java/android/net/wifi/IActionListener.aidl new file mode 100644 index 000000000000..faa0901cb087 --- /dev/null +++ b/wifi/java/android/net/wifi/IActionListener.aidl @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2019 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; + +/** + * Interface for generic wifi callbacks. + * @hide + */ +oneway interface IActionListener +{ + void onSuccess(); + void onFailure(int reason); +} diff --git a/wifi/java/android/net/wifi/ITxPacketCountListener.aidl b/wifi/java/android/net/wifi/ITxPacketCountListener.aidl new file mode 100644 index 000000000000..8606ab5afa9c --- /dev/null +++ b/wifi/java/android/net/wifi/ITxPacketCountListener.aidl @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2019 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; + +/** + * Interface for tx packet counter callback. + * @hide + */ +oneway interface ITxPacketCountListener +{ + void onSuccess(int count); + void onFailure(int reason); +} diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 931e5dd7405f..a97a5a5ec593 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -24,10 +24,12 @@ import android.net.wifi.hotspot2.IProvisioningCallback; import android.net.DhcpInfo; import android.net.Network; +import android.net.wifi.IActionListener; import android.net.wifi.IDppCallback; import android.net.wifi.INetworkRequestMatchCallback; import android.net.wifi.ISoftApCallback; import android.net.wifi.ITrafficStateCallback; +import android.net.wifi.ITxPacketCountListener; import android.net.wifi.IOnWifiUsabilityStatsListener; import android.net.wifi.ScanResult; import android.net.wifi.WifiActivityEnergyInfo; @@ -106,8 +108,6 @@ interface IWifiManager int getWifiEnabledState(); - void setCountryCode(String country); - String getCountryCode(); boolean isDualBandSupported(); @@ -156,8 +156,6 @@ interface IWifiManager void notifyUserOfApBandConversion(String packageName); - Messenger getWifiServiceMessenger(String packageName); - void enableTdls(String remoteIPAddress, boolean enable); void enableTdlsWithMacAddress(String remoteMacAddress, boolean enable); @@ -220,4 +218,12 @@ interface IWifiManager void stopDppSession(); void updateWifiUsabilityScore(int seqNum, int score, int predictionHorizonSec); + + oneway void connect(in WifiConfiguration config, int netId, in IBinder binder, in IActionListener listener, int callbackIdentifier); + + oneway void save(in WifiConfiguration config, in IBinder binder, in IActionListener listener, int callbackIdentifier); + + oneway void forget(int netId, in IBinder binder, in IActionListener listener, int callbackIdentifier); + + oneway void getTxPacketCount(String packageName, in IBinder binder, in ITxPacketCountListener listener, int callbackIdentifier); } diff --git a/wifi/java/android/net/wifi/RssiPacketCountInfo.java b/wifi/java/android/net/wifi/RssiPacketCountInfo.java deleted file mode 100644 index 4301165308d1..000000000000 --- a/wifi/java/android/net/wifi/RssiPacketCountInfo.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2012 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 android.os.Parcel; -import android.os.Parcelable; - -/** - * Bundle of RSSI and packet count information, for WiFi watchdog - * - * @see WifiWatchdogStateMachine - * - * @hide - */ -public class RssiPacketCountInfo implements Parcelable { - - public int rssi; - - public int txgood; - - public int txbad; - - public int rxgood; - - public RssiPacketCountInfo() { - rssi = txgood = txbad = rxgood = 0; - } - - private RssiPacketCountInfo(Parcel in) { - rssi = in.readInt(); - txgood = in.readInt(); - txbad = in.readInt(); - rxgood = in.readInt(); - } - - @Override - public void writeToParcel(Parcel out, int flags) { - out.writeInt(rssi); - out.writeInt(txgood); - out.writeInt(txbad); - out.writeInt(rxgood); - } - - @Override - public int describeContents() { - return 0; - } - - public static final @android.annotation.NonNull Parcelable.Creator<RssiPacketCountInfo> CREATOR = - new Parcelable.Creator<RssiPacketCountInfo>() { - @Override - public RssiPacketCountInfo createFromParcel(Parcel in) { - return new RssiPacketCountInfo(in); - } - - @Override - public RssiPacketCountInfo[] newArray(int size) { - return new RssiPacketCountInfo[size]; - } - }; -} diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 0fa0ec7afd91..00895e846e82 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -55,13 +55,10 @@ import android.os.WorkSource; import android.text.TextUtils; import android.util.Log; import android.util.Pair; -import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; -import com.android.internal.util.AsyncChannel; -import com.android.internal.util.Protocol; import com.android.server.net.NetworkPinner; import dalvik.system.CloseGuard; @@ -75,7 +72,6 @@ import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; /** @@ -1128,13 +1124,6 @@ public class WifiManager { IWifiManager mService; private final int mTargetSdkVersion; - private static final int INVALID_KEY = 0; - private int mListenerKey = 1; - private final SparseArray mListenerMap = new SparseArray(); - private final Object mListenerMapLock = new Object(); - - private AsyncChannel mAsyncChannel; - private CountDownLatch mConnected; private Looper mLooper; private boolean mVerboseLoggingEnabled = false; @@ -2501,25 +2490,6 @@ public class WifiManager { } /** - * Set the country code. - * @param countryCode country code in ISO 3166 format. - * - * @hide - */ - public void setCountryCode(@NonNull String country) { - try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - if (TextUtils.isEmpty(country)) return; - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.setCountryCode(country); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** * get the country code. * @return the country code in ISO 3166 format. * @@ -2644,8 +2614,23 @@ public class WifiManager { * * @hide for CTS test only */ - public void getTxPacketCount(TxPacketCountListener listener) { - getChannel().sendMessage(RSSI_PKTCNT_FETCH, 0, putListener(listener)); + public void getTxPacketCount(@NonNull TxPacketCountListener listener) { + if (listener == null) throw new IllegalArgumentException("listener cannot be null"); + Binder binder = new Binder(); + TxPacketCountListenerProxy listenerProxy = + new TxPacketCountListenerProxy(mLooper, listener); + try { + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.getTxPacketCount(mContext.getOpPackageName(), binder, listenerProxy, + listener.hashCode()); + } catch (RemoteException e) { + listenerProxy.onFailure(ERROR); + } catch (SecurityException e) { + listenerProxy.onFailure(NOT_AUTHORIZED); + } } /** @@ -3080,76 +3065,6 @@ public class WifiManager { } } - /* TODO: deprecate synchronous API and open up the following API */ - - private static final int BASE = Protocol.BASE_WIFI_MANAGER; - - /* Commands to WifiService */ - /** @hide */ - public static final int CONNECT_NETWORK = BASE + 1; - /** @hide */ - public static final int CONNECT_NETWORK_FAILED = BASE + 2; - /** @hide */ - public static final int CONNECT_NETWORK_SUCCEEDED = BASE + 3; - - /** @hide */ - public static final int FORGET_NETWORK = BASE + 4; - /** @hide */ - public static final int FORGET_NETWORK_FAILED = BASE + 5; - /** @hide */ - public static final int FORGET_NETWORK_SUCCEEDED = BASE + 6; - - /** @hide */ - public static final int SAVE_NETWORK = BASE + 7; - /** @hide */ - public static final int SAVE_NETWORK_FAILED = BASE + 8; - /** @hide */ - public static final int SAVE_NETWORK_SUCCEEDED = BASE + 9; - - /** @hide - * @deprecated This is deprecated - */ - public static final int START_WPS = BASE + 10; - /** @hide - * @deprecated This is deprecated - */ - public static final int START_WPS_SUCCEEDED = BASE + 11; - /** @hide - * @deprecated This is deprecated - */ - public static final int WPS_FAILED = BASE + 12; - /** @hide - * @deprecated This is deprecated - */ - public static final int WPS_COMPLETED = BASE + 13; - - /** @hide - * @deprecated This is deprecated - */ - public static final int CANCEL_WPS = BASE + 14; - /** @hide - * @deprecated This is deprecated - */ - public static final int CANCEL_WPS_FAILED = BASE + 15; - /** @hide - * @deprecated This is deprecated - */ - public static final int CANCEL_WPS_SUCCEDED = BASE + 16; - - /** @hide */ - public static final int DISABLE_NETWORK = BASE + 17; - /** @hide */ - public static final int DISABLE_NETWORK_FAILED = BASE + 18; - /** @hide */ - public static final int DISABLE_NETWORK_SUCCEEDED = BASE + 19; - - /** @hide */ - public static final int RSSI_PKTCNT_FETCH = BASE + 20; - /** @hide */ - public static final int RSSI_PKTCNT_FETCH_SUCCEEDED = BASE + 21; - /** @hide */ - public static final int RSSI_PKTCNT_FETCH_FAILED = BASE + 22; - /** * Passed with {@link ActionListener#onFailure}. * Indicates that the operation failed due to an internal error. @@ -3172,6 +3087,11 @@ public class WifiManager { */ public static final int BUSY = 2; + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({ERROR, IN_PROGRESS, BUSY}) + public @interface ActionListenerFailureReason {} + /* WPS specific errors */ /** WPS overlap detected * @deprecated This is deprecated @@ -3216,20 +3136,13 @@ public class WifiManager { public interface ActionListener { /** * The operation succeeded. - * This is called when the scan request has been validated and ready - * to sent to driver. */ - public void onSuccess(); + void onSuccess(); /** * The operation failed. - * This is called when the scan request failed. - * @param reason The reason for failure could be one of the following: - * {@link #REASON_INVALID_REQUEST}} is specified when scan request parameters are invalid. - * {@link #REASON_NOT_AUTHORIZED} is specified when requesting app doesn't have the required - * permission to request a scan. - * {@link #REASON_UNSPECIFIED} is specified when driver reports a scan failure. + * @param reason The reason for failure depends on the operation. */ - public void onFailure(int reason); + void onFailure(@ActionListenerFailureReason int reason); } /** Interface for callback invocation on a start WPS action @@ -3274,6 +3187,41 @@ public class WifiManager { } /** + * Callback proxy for TxPacketCountListener objects. + * + * @hide + */ + private class TxPacketCountListenerProxy extends ITxPacketCountListener.Stub { + private final Handler mHandler; + private final TxPacketCountListener mCallback; + + TxPacketCountListenerProxy(Looper looper, TxPacketCountListener callback) { + mHandler = new Handler(looper); + mCallback = callback; + } + + @Override + public void onSuccess(int count) { + if (mVerboseLoggingEnabled) { + Log.v(TAG, "TxPacketCounterProxy: onSuccess: count=" + count); + } + mHandler.post(() -> { + mCallback.onSuccess(count); + }); + } + + @Override + public void onFailure(int reason) { + if (mVerboseLoggingEnabled) { + Log.v(TAG, "TxPacketCounterProxy: onFailure: reason=" + reason); + } + mHandler.post(() -> { + mCallback.onFailure(reason); + }); + } + } + + /** * Base class for soft AP callback. Should be extended by applications and set when calling * {@link WifiManager#registerSoftApCallback(SoftApCallback, Handler)}. * @@ -3707,125 +3655,61 @@ public class WifiManager { } } - // Ensure that multiple ServiceHandler threads do not interleave message dispatch. - private static final Object sServiceHandlerDispatchLock = new Object(); + /** + * Callback proxy for ActionListener objects. + */ + private class ActionListenerProxy extends IActionListener.Stub { + private final String mActionTag; + private final Handler mHandler; + private final ActionListener mCallback; - private class ServiceHandler extends Handler { - ServiceHandler(Looper looper) { - super(looper); + ActionListenerProxy(String actionTag, Looper looper, ActionListener callback) { + mActionTag = actionTag; + mHandler = new Handler(looper); + mCallback = callback; } @Override - public void handleMessage(Message message) { - synchronized (sServiceHandlerDispatchLock) { - dispatchMessageToListeners(message); + public void onSuccess() { + if (mVerboseLoggingEnabled) { + Log.v(TAG, "ActionListenerProxy:" + mActionTag + ": onSuccess"); } + mHandler.post(() -> { + mCallback.onSuccess(); + }); } - private void dispatchMessageToListeners(Message message) { - Object listener = removeListener(message.arg2); - switch (message.what) { - case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: - if (message.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { - mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); - } else { - Log.e(TAG, "Failed to set up channel connection"); - // This will cause all further async API calls on the WifiManager - // to fail and throw an exception - mAsyncChannel = null; - } - mConnected.countDown(); - break; - case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED: - // Ignore - break; - case AsyncChannel.CMD_CHANNEL_DISCONNECTED: - Log.e(TAG, "Channel connection lost"); - // This will cause all further async API calls on the WifiManager - // to fail and throw an exception - mAsyncChannel = null; - getLooper().quit(); - break; - /* ActionListeners grouped together */ - case WifiManager.CONNECT_NETWORK_FAILED: - case WifiManager.FORGET_NETWORK_FAILED: - case WifiManager.SAVE_NETWORK_FAILED: - case WifiManager.DISABLE_NETWORK_FAILED: - if (listener != null) { - ((ActionListener) listener).onFailure(message.arg1); - } - break; - /* ActionListeners grouped together */ - case WifiManager.CONNECT_NETWORK_SUCCEEDED: - case WifiManager.FORGET_NETWORK_SUCCEEDED: - case WifiManager.SAVE_NETWORK_SUCCEEDED: - case WifiManager.DISABLE_NETWORK_SUCCEEDED: - if (listener != null) { - ((ActionListener) listener).onSuccess(); - } - break; - case WifiManager.RSSI_PKTCNT_FETCH_SUCCEEDED: - if (listener != null) { - RssiPacketCountInfo info = (RssiPacketCountInfo) message.obj; - if (info != null) - ((TxPacketCountListener) listener).onSuccess(info.txgood + info.txbad); - else - ((TxPacketCountListener) listener).onFailure(ERROR); - } - break; - case WifiManager.RSSI_PKTCNT_FETCH_FAILED: - if (listener != null) { - ((TxPacketCountListener) listener).onFailure(message.arg1); - } - break; - default: - //ignore - break; + @Override + public void onFailure(@ActionListenerFailureReason int reason) { + if (mVerboseLoggingEnabled) { + Log.v(TAG, "ActionListenerProxy:" + mActionTag + ": onFailure=" + reason); } + mHandler.post(() -> { + mCallback.onFailure(reason); + }); } } - private int putListener(Object listener) { - if (listener == null) return INVALID_KEY; - int key; - synchronized (mListenerMapLock) { - do { - key = mListenerKey++; - } while (key == INVALID_KEY); - mListenerMap.put(key, listener); - } - return key; - } - - private Object removeListener(int key) { - if (key == INVALID_KEY) return null; - synchronized (mListenerMapLock) { - Object listener = mListenerMap.get(key); - mListenerMap.remove(key); - return listener; + private void connectInternal(@Nullable WifiConfiguration config, int networkId, + @Nullable ActionListener listener) { + ActionListenerProxy listenerProxy = null; + Binder binder = null; + if (listener != null) { + listenerProxy = new ActionListenerProxy("connect", mLooper, listener); + binder = new Binder(); } - } - - private synchronized AsyncChannel getChannel() { - if (mAsyncChannel == null) { - Messenger messenger = getWifiServiceMessenger(); - if (messenger == null) { - throw new IllegalStateException( - "getWifiServiceMessenger() returned null! This is invalid."); - } - - mAsyncChannel = new AsyncChannel(); - mConnected = new CountDownLatch(1); - - Handler handler = new ServiceHandler(mLooper); - mAsyncChannel.connect(mContext, handler, messenger); - try { - mConnected.await(); - } catch (InterruptedException e) { - Log.e(TAG, "interrupted wait at init"); + try { + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); } + iWifiManager.connect(config, networkId, binder, listenerProxy, + listener == null ? 0 : listener.hashCode()); + } catch (RemoteException e) { + if (listenerProxy != null) listenerProxy.onFailure(ERROR); + } catch (SecurityException e) { + if (listenerProxy != null) listenerProxy.onFailure(NOT_AUTHORIZED); } - return mAsyncChannel; } /** @@ -3851,10 +3735,7 @@ public class WifiManager { }) public void connect(@NonNull WifiConfiguration config, @Nullable ActionListener listener) { if (config == null) throw new IllegalArgumentException("config cannot be null"); - // Use INVALID_NETWORK_ID for arg1 when passing a config object - // arg1 is used to pass network id when the network already exists - getChannel().sendMessage(CONNECT_NETWORK, WifiConfiguration.INVALID_NETWORK_ID, - putListener(listener), config); + connectInternal(config, WifiConfiguration.INVALID_NETWORK_ID, listener); } /** @@ -3877,7 +3758,7 @@ public class WifiManager { }) public void connect(int networkId, @Nullable ActionListener listener) { if (networkId < 0) throw new IllegalArgumentException("Network id cannot be negative"); - getChannel().sendMessage(CONNECT_NETWORK, networkId, putListener(listener)); + connectInternal(null, networkId, listener); } /** @@ -3908,7 +3789,24 @@ public class WifiManager { }) public void save(@NonNull WifiConfiguration config, @Nullable ActionListener listener) { if (config == null) throw new IllegalArgumentException("config cannot be null"); - getChannel().sendMessage(SAVE_NETWORK, 0, putListener(listener), config); + ActionListenerProxy listenerProxy = null; + Binder binder = null; + if (listener != null) { + listenerProxy = new ActionListenerProxy("save", mLooper, listener); + binder = new Binder(); + } + try { + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.save(config, binder, listenerProxy, + listener == null ? 0 : listener.hashCode()); + } catch (RemoteException e) { + if (listenerProxy != null) listenerProxy.onFailure(ERROR); + } catch (SecurityException e) { + if (listenerProxy != null) listenerProxy.onFailure(NOT_AUTHORIZED); + } } /** @@ -3932,7 +3830,24 @@ public class WifiManager { }) public void forget(int netId, @Nullable ActionListener listener) { if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative"); - getChannel().sendMessage(FORGET_NETWORK, netId, putListener(listener)); + ActionListenerProxy listenerProxy = null; + Binder binder = null; + if (listener != null) { + listenerProxy = new ActionListenerProxy("forget", mLooper, listener); + binder = new Binder(); + } + try { + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.forget(netId, binder, listenerProxy, + listener == null ? 0 : listener.hashCode()); + } catch (RemoteException e) { + if (listenerProxy != null) listenerProxy.onFailure(ERROR); + } catch (SecurityException e) { + if (listenerProxy != null) listenerProxy.onFailure(NOT_AUTHORIZED); + } } /** @@ -3942,6 +3857,7 @@ public class WifiManager { * @param listener for callbacks on success or failure. Can be null. * @throws IllegalStateException if the WifiManager instance needs to be * initialized again + * @deprecated This API is deprecated. Use {@link #disableNetwork(int)} instead. * @hide */ @SystemApi @@ -3950,9 +3866,19 @@ public class WifiManager { android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK }) + @Deprecated public void disable(int netId, @Nullable ActionListener listener) { if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative"); - getChannel().sendMessage(DISABLE_NETWORK, netId, putListener(listener)); + // Simple wrapper which forwards the call to disableNetwork. This is a temporary + // implementation until we can remove this API completely. + boolean status = disableNetwork(netId); + if (listener != null) { + if (status) { + listener.onSuccess(); + } else { + listener.onFailure(ERROR); + } + } } /** @@ -4008,24 +3934,6 @@ public class WifiManager { } /** - * Get a reference to WifiService handler. This is used by a client to establish - * an AsyncChannel communication with WifiService - * - * @return Messenger pointing to the WifiService handler - */ - @UnsupportedAppUsage - private Messenger getWifiServiceMessenger() { - try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return null; - return iWifiManager.getWifiServiceMessenger(mContext.getOpPackageName()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - - /** * Allows an application to keep the Wi-Fi radio awake. * Normally the Wi-Fi radio may turn off when the user has not used the device in a while. * Acquiring a WifiLock will keep the radio on until the lock is released. Multiple @@ -4485,16 +4393,6 @@ public class WifiManager { } } - protected void finalize() throws Throwable { - try { - if (mAsyncChannel != null) { - mAsyncChannel.disconnect(); - } - } finally { - super.finalize(); - } - } - /** * Set wifi verbose log. Called from developer settings. * @hide diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index bc06e7de8502..2e82f4e8c23b 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -21,11 +21,13 @@ package com.android.server.wifi; import android.content.pm.ParceledListSlice; import android.net.DhcpInfo; import android.net.Network; +import android.net.wifi.IActionListener; import android.net.wifi.IDppCallback; import android.net.wifi.INetworkRequestMatchCallback; import android.net.wifi.IOnWifiUsabilityStatsListener; import android.net.wifi.ISoftApCallback; import android.net.wifi.ITrafficStateCallback; +import android.net.wifi.ITxPacketCountListener; import android.net.wifi.IWifiManager; import android.net.wifi.ScanResult; import android.net.wifi.WifiActivityEnergyInfo; @@ -203,7 +205,7 @@ public class BaseWifiService extends IWifiManager.Stub { throw new UnsupportedOperationException(); } - @Override + /** @removed */ public void setCountryCode(String country) { throw new UnsupportedOperationException(); } @@ -323,7 +325,7 @@ public class BaseWifiService extends IWifiManager.Stub { throw new UnsupportedOperationException(); } - @Override + /** @removed */ public Messenger getWifiServiceMessenger(String packageName) { throw new UnsupportedOperationException(); } @@ -486,4 +488,28 @@ public class BaseWifiService extends IWifiManager.Stub { public void updateWifiUsabilityScore(int seqNum, int score, int predictionHorizonSec) { throw new UnsupportedOperationException(); } + + @Override + public void connect(WifiConfiguration config, int netId, IBinder binder, + IActionListener callback, int callbackIdentifier) { + throw new UnsupportedOperationException(); + } + + @Override + public void save(WifiConfiguration config, IBinder binder, IActionListener callback, + int callbackIdentifier) { + throw new UnsupportedOperationException(); + } + + @Override + public void forget(int netId, IBinder binder, IActionListener callback, + int callbackIdentifier) { + throw new UnsupportedOperationException(); + } + + @Override + public void getTxPacketCount(String packageName, IBinder binder, + ITxPacketCountListener callback, int callbackIdentifier) { + throw new UnsupportedOperationException(); + } } diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index e478f3830c0a..7e7f00281529 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -64,11 +64,13 @@ import android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback; import android.net.wifi.WifiManager.OnWifiUsabilityStatsListener; import android.net.wifi.WifiManager.SoftApCallback; import android.net.wifi.WifiManager.TrafficStateCallback; +import android.os.Binder; import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.os.Messenger; +import android.os.RemoteException; import android.os.test.TestLooper; import androidx.test.filters.SmallTest; @@ -971,25 +973,6 @@ public class WifiManagerTest { } /** - * Verify that calls WifiServiceImpl to set country code when no exception happens. - */ - @Test - public void testSetWifiCountryCode() throws Exception { - mWifiManager.setCountryCode(TEST_COUNTRY_CODE); - verify(mWifiService).setCountryCode(TEST_COUNTRY_CODE); - } - - /** - * Verify that WifiManager.setCountryCode() rethrows exceptions if caller does not - * have necessary permissions. - */ - @Test(expected = SecurityException.class) - public void testSetWifiCountryCodeFailedOnSecurityException() throws Exception { - doThrow(new SecurityException()).when(mWifiService).setCountryCode(anyString()); - mWifiManager.setCountryCode(TEST_COUNTRY_CODE); - } - - /** * Test that calls to get the current WPS config token return null and do not have any * interactions with WifiServiceImpl. */ @@ -1646,4 +1629,97 @@ i * Verify that a call to cancel WPS immediately returns a failure. assertTrue(mWifiManager.setWifiEnabled(false)); verify(mWifiService).setWifiEnabled(mContext.getOpPackageName(), false); } + + /** + * Test behavior of {@link WifiManager#connect(int, WifiManager.ActionListener)} + */ + @Test + public void testConnectWithListener() throws Exception { + WifiManager.ActionListener externalListener = mock(WifiManager.ActionListener.class); + mWifiManager.connect(TEST_NETWORK_ID, externalListener); + + ArgumentCaptor<IActionListener> binderListenerCaptor = + ArgumentCaptor.forClass(IActionListener.class); + verify(mWifiService).connect(eq(null), eq(TEST_NETWORK_ID), any(Binder.class), + binderListenerCaptor.capture(), anyInt()); + assertNotNull(binderListenerCaptor.getValue()); + + // Trigger on success. + binderListenerCaptor.getValue().onSuccess(); + mLooper.dispatchAll(); + verify(externalListener).onSuccess(); + + // Trigger on failure. + binderListenerCaptor.getValue().onFailure(WifiManager.BUSY); + mLooper.dispatchAll(); + verify(externalListener).onFailure(WifiManager.BUSY); + } + + /** + * Test behavior of {@link WifiManager#connect(int, WifiManager.ActionListener)} + */ + @Test + public void testConnectWithListenerHandleSecurityException() throws Exception { + doThrow(new SecurityException()).when(mWifiService) + .connect(eq(null), anyInt(), any(IBinder.class), + any(IActionListener.class), anyInt()); + WifiManager.ActionListener externalListener = mock(WifiManager.ActionListener.class); + mWifiManager.connect(TEST_NETWORK_ID, externalListener); + + mLooper.dispatchAll(); + verify(externalListener).onFailure(WifiManager.NOT_AUTHORIZED); + } + + /** + * Test behavior of {@link WifiManager#connect(int, WifiManager.ActionListener)} + */ + @Test + public void testConnectWithListenerHandleRemoteException() throws Exception { + doThrow(new RemoteException()).when(mWifiService) + .connect(eq(null), anyInt(), any(IBinder.class), + any(IActionListener.class), anyInt()); + WifiManager.ActionListener externalListener = mock(WifiManager.ActionListener.class); + mWifiManager.connect(TEST_NETWORK_ID, externalListener); + + mLooper.dispatchAll(); + verify(externalListener).onFailure(WifiManager.ERROR); + } + + /** + * Test behavior of {@link WifiManager#connect(int, WifiManager.ActionListener)} + */ + @Test + public void testConnectWithoutListener() throws Exception { + WifiConfiguration configuration = new WifiConfiguration(); + mWifiManager.connect(configuration, null); + + verify(mWifiService).connect(configuration, WifiConfiguration.INVALID_NETWORK_ID, null, + null, 0); + } + + /** + * Test behavior of {@link WifiManager#getTxPacketCount(WifiManager.TxPacketCountListener)} + */ + @Test + public void testGetTxPacketCount() throws Exception { + WifiManager.TxPacketCountListener externalListener = + mock(WifiManager.TxPacketCountListener.class); + mWifiManager.getTxPacketCount(externalListener); + + ArgumentCaptor<ITxPacketCountListener> binderListenerCaptor = + ArgumentCaptor.forClass(ITxPacketCountListener.class); + verify(mWifiService).getTxPacketCount(anyString(), any(Binder.class), + binderListenerCaptor.capture(), anyInt()); + assertNotNull(binderListenerCaptor.getValue()); + + // Trigger on success. + binderListenerCaptor.getValue().onSuccess(6); + mLooper.dispatchAll(); + verify(externalListener).onSuccess(6); + + // Trigger on failure. + binderListenerCaptor.getValue().onFailure(WifiManager.BUSY); + mLooper.dispatchAll(); + verify(externalListener).onFailure(WifiManager.BUSY); + } } |