diff options
Diffstat (limited to 'wifi/java')
16 files changed, 784 insertions, 572 deletions
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/ILocalOnlyHotspotCallback.aidl b/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl new file mode 100644 index 000000000000..b83b594c8cb9 --- /dev/null +++ b/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl @@ -0,0 +1,30 @@ +/** + * 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; + +import android.net.wifi.WifiConfiguration; + +/** + * Communicates LOHS status back to the application process. + * + * @hide + */ +oneway interface ILocalOnlyHotspotCallback { + void onHotspotStarted(in WifiConfiguration config); + void onHotspotStopped(); + void onHotspotFailed(int reason); +} diff --git a/wifi/java/android/net/wifi/IScanResultsListener.aidl b/wifi/java/android/net/wifi/IScanResultsListener.aidl new file mode 100644 index 000000000000..bec74a620380 --- /dev/null +++ b/wifi/java/android/net/wifi/IScanResultsListener.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 Wi-Fi scan result available callback. + * + * @hide + */ +oneway interface IScanResultsListener +{ + void onScanResultsAvailable(); +} 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 df9a1d55af20..5ab6678afe78 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -24,10 +24,14 @@ 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.ILocalOnlyHotspotCallback; import android.net.wifi.INetworkRequestMatchCallback; +import android.net.wifi.IScanResultsListener; 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; @@ -107,8 +111,6 @@ interface IWifiManager int getWifiEnabledState(); - void setCountryCode(String country); - String getCountryCode(); boolean isDualBandSupported(); @@ -139,11 +141,11 @@ interface IWifiManager boolean stopSoftAp(); - int startLocalOnlyHotspot(in Messenger messenger, in IBinder binder, String packageName); + int startLocalOnlyHotspot(in ILocalOnlyHotspotCallback callback, String packageName); void stopLocalOnlyHotspot(); - void startWatchLocalOnlyHotspot(in Messenger messenger, in IBinder binder); + void startWatchLocalOnlyHotspot(in ILocalOnlyHotspotCallback callback); void stopWatchLocalOnlyHotspot(); @@ -157,8 +159,6 @@ interface IWifiManager void notifyUserOfApBandConversion(String packageName); - Messenger getWifiServiceMessenger(String packageName); - void enableTdls(String remoteIPAddress, boolean enable); void enableTdlsWithMacAddress(String remoteMacAddress, boolean enable); @@ -250,5 +250,17 @@ interface IWifiManager 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); + + void registerScanResultsListener(in IBinder binder, in IScanResultsListener Listener, int listenerIdentifier); + + void unregisterScanResultsListener(int listenerIdentifier); + int getSoftApWifiGeneration(); } 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/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 258c5813f960..b51622c065fb 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -1113,26 +1113,6 @@ public class WifiConfiguration implements Parcelable { } /** - * @hide - * Returns Randomized MAC address to use with the network. - * If it is not set/valid, creates a new randomized address. - * If it can't generate a valid mac, returns the default MAC. - */ - public @NonNull MacAddress getOrCreateRandomizedMacAddress() { - int randomMacGenerationCount = 0; - while (!isValidMacAddressForRandomization(mRandomizedMacAddress) - && randomMacGenerationCount < MAXIMUM_RANDOM_MAC_GENERATION_RETRY) { - mRandomizedMacAddress = MacAddress.createRandomUnicastAddress(); - randomMacGenerationCount++; - } - - if (!isValidMacAddressForRandomization(mRandomizedMacAddress)) { - mRandomizedMacAddress = MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS); - } - return mRandomizedMacAddress; - } - - /** * Returns MAC address set to be the local randomized MAC address. * Depending on user preference, the device may or may not use the returned MAC address for * connections to this network. diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java index 0127c630baa9..7eadd3b3d9e9 100644 --- a/wifi/java/android/net/wifi/WifiInfo.java +++ b/wifi/java/android/net/wifi/WifiInfo.java @@ -16,6 +16,7 @@ package android.net.wifi; +import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.Nullable; import android.annotation.SystemApi; @@ -27,6 +28,8 @@ import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.net.Inet4Address; import java.net.InetAddress; import java.net.UnknownHostException; @@ -34,7 +37,7 @@ import java.util.EnumMap; import java.util.Locale; /** - * Describes the state of any Wifi connection that is active or + * Describes the state of any Wi-Fi connection that is active or * is in the process of being set up. */ public class WifiInfo implements Parcelable { @@ -96,6 +99,47 @@ public class WifiInfo implements Parcelable { private int mRssi; /** + * Wi-Fi unknown technology + */ + public static final int WIFI_TECHNOLOGY_UNKNOWN = 0; + + /** + * Wi-Fi 802.11a/b/g + */ + public static final int WIFI_TECHNOLOGY_LEGACY = 1; + + /** + * Wi-Fi 802.11n + */ + public static final int WIFI_TECHNOLOGY_11N = 4; + + /** + * Wi-Fi 802.11ac + */ + public static final int WIFI_TECHNOLOGY_11AC = 5; + + /** + * Wi-Fi 802.11ax + */ + public static final int WIFI_TECHNOLOGY_11AX = 6; + + /** @hide */ + @IntDef(prefix = { "WIFI_TECHNOLOGY_" }, value = { + WIFI_TECHNOLOGY_UNKNOWN, + WIFI_TECHNOLOGY_LEGACY, + WIFI_TECHNOLOGY_11N, + WIFI_TECHNOLOGY_11AC, + WIFI_TECHNOLOGY_11AX + }) + @Retention(RetentionPolicy.SOURCE) + public @interface WifiTechnology{} + + /** + * Wi-Fi technology for the connection + */ + private @WifiTechnology int mWifiTechnology; + + /** * The unit in which links speeds are expressed. */ public static final String LINK_SPEED_UNITS = "Mbps"; @@ -301,6 +345,7 @@ public class WifiInfo implements Parcelable { txSuccessRate = source.txSuccessRate; rxSuccessRate = source.rxSuccessRate; score = source.score; + mWifiTechnology = source.mWifiTechnology; } } @@ -389,6 +434,22 @@ public class WifiInfo implements Parcelable { } /** + * Sets the Wi-Fi technology + * @hide + */ + public void setWifiTechnology(@WifiTechnology int wifiTechnology) { + mWifiTechnology = wifiTechnology; + } + + /** + * Get connection Wi-Fi technology + * @return the connection Wi-Fi technology + */ + public @WifiTechnology int getWifiTechnology() { + return mWifiTechnology; + } + + /** * Returns the current link speed in {@link #LINK_SPEED_UNITS}. * @return the link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is unknown. * @see #LINK_SPEED_UNITS @@ -727,6 +788,7 @@ public class WifiInfo implements Parcelable { .append(", Wifi Generation: ").append(mWifiGeneration) .append(", TWT support: ").append(mTwtSupport) .append(", Eight Max VHT Spatial streams support: ").append(mVhtMax8SpatialStreamsSupport) + .append(", Wi-Fi technology: ").append(mWifiTechnology) .append(", RSSI: ").append(mRssi) .append(", Link speed: ").append(mLinkSpeed).append(LINK_SPEED_UNITS) .append(", Tx Link speed: ").append(mTxLinkSpeed).append(LINK_SPEED_UNITS) @@ -785,6 +847,7 @@ public class WifiInfo implements Parcelable { dest.writeInt(mWifiGeneration); dest.writeInt(mVhtMax8SpatialStreamsSupport ? 1 : 0); dest.writeInt(mTwtSupport ? 1 : 0); + dest.writeInt(mWifiTechnology); } /** Implement the Parcelable interface {@hide} */ @@ -829,6 +892,7 @@ public class WifiInfo implements Parcelable { info.mWifiGeneration = in.readInt(); info.mVhtMax8SpatialStreamsSupport = in.readInt() != 0; info.mTwtSupport = in.readInt() != 0; + info.mWifiTechnology = in.readInt(); return info; } diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 026c6a8ec7d6..6d382eef6808 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -38,6 +38,7 @@ import android.net.DhcpInfo; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkRequest; +import android.net.NetworkStack; import android.net.wifi.hotspot2.IProvisioningCallback; import android.net.wifi.hotspot2.OsuProvider; import android.net.wifi.hotspot2.PasspointConfiguration; @@ -45,23 +46,19 @@ import android.net.wifi.hotspot2.ProvisioningCallback; import android.os.Binder; import android.os.Build; import android.os.Handler; +import android.os.HandlerExecutor; import android.os.IBinder; import android.os.Looper; -import android.os.Message; -import android.os.Messenger; import android.os.RemoteException; import android.os.ServiceManager; 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; /** @@ -566,7 +562,9 @@ public class WifiManager { * * @hide */ - public static final String EXTRA_WIFI_AP_INTERFACE_NAME = "wifi_ap_interface_name"; + @SystemApi + public static final String EXTRA_WIFI_AP_INTERFACE_NAME = + "android.net.wifi.extra.WIFI_AP_INTERFACE_NAME"; /** * The intended ip mode for this softap. * @see #IFACE_IP_MODE_TETHERED @@ -574,7 +572,8 @@ public class WifiManager { * * @hide */ - public static final String EXTRA_WIFI_AP_MODE = "wifi_ap_mode"; + @SystemApi + public static final String EXTRA_WIFI_AP_MODE = "android.net.wifi.extra.WIFI_AP_MODE"; /** @hide */ @IntDef(flag = false, prefix = { "WIFI_AP_STATE_" }, value = { @@ -680,6 +679,7 @@ public class WifiManager { * * @hide */ + @SystemApi public static final int IFACE_IP_MODE_UNSPECIFIED = -1; /** @@ -689,6 +689,7 @@ public class WifiManager { * * @hide */ + @SystemApi public static final int IFACE_IP_MODE_CONFIGURATION_ERROR = 0; /** @@ -698,6 +699,7 @@ public class WifiManager { * * @hide */ + @SystemApi public static final int IFACE_IP_MODE_TETHERED = 1; /** @@ -707,6 +709,7 @@ public class WifiManager { * * @hide */ + @SystemApi public static final int IFACE_IP_MODE_LOCAL_ONLY = 2; /** @@ -1204,26 +1207,9 @@ 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; - /* 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; @@ -1991,12 +1977,13 @@ public class WifiManager { } /** - * Remove the Passpoint configuration identified by its FQDN (Fully Qualified Domain Name). + * Remove the Passpoint configuration identified by its FQDN (Fully Qualified Domain Name) added + * by the caller. * - * @param fqdn The FQDN of the Passpoint configuration to be removed + * @param fqdn The FQDN of the Passpoint configuration added by the caller to be removed * @throws IllegalArgumentException if no configuration is associated with the given FQDN or * Passpoint is not enabled on the device. - * @deprecated This is no longer supported. + * @deprecated This will be non-functional in a future release. */ @Deprecated @RequiresPermission(anyOf = { @@ -2020,12 +2007,12 @@ public class WifiManager { } /** - * Return the list of installed Passpoint configurations. + * Return the list of installed Passpoint configurations added by the caller. * * An empty list will be returned when no configurations are installed. * - * @return A list of {@link PasspointConfiguration} - * @deprecated This is no longer supported. + * @return A list of {@link PasspointConfiguration} added by the caller + * @deprecated This will be non-functional in a future release. */ @Deprecated @RequiresPermission(anyOf = { @@ -2658,25 +2645,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. * @@ -2801,8 +2769,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); + } } /** @@ -2843,16 +2826,21 @@ public class WifiManager { /** * Call allowing ConnectivityService to update WifiService with interface mode changes. * - * The possible modes include: {@link #IFACE_IP_MODE_TETHERED}, - * {@link #IFACE_IP_MODE_LOCAL_ONLY}, - * {@link #IFACE_IP_MODE_CONFIGURATION_ERROR} - * - * @param ifaceName String name of the updated interface - * @param mode int representing the new mode + * @param ifaceName String name of the updated interface, or null to represent all interfaces + * @param mode int representing the new mode, one of: + * {@link #IFACE_IP_MODE_TETHERED}, + * {@link #IFACE_IP_MODE_LOCAL_ONLY}, + * {@link #IFACE_IP_MODE_CONFIGURATION_ERROR}, + * {@link #IFACE_IP_MODE_UNSPECIFIED} * * @hide */ - public void updateInterfaceIpState(String ifaceName, int mode) { + @SystemApi + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_STACK, + NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK + }) + public void updateInterfaceIpState(@Nullable String ifaceName, @IfaceIpMode int mode) { try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) { @@ -2875,6 +2863,11 @@ public class WifiManager { * * @hide */ + @SystemApi + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_STACK, + NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK + }) public boolean startSoftAp(@Nullable WifiConfiguration wifiConfig) { try { IWifiManager iWifiManager = getIWifiManager(); @@ -2892,6 +2885,11 @@ public class WifiManager { * * @hide */ + @SystemApi + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_STACK, + NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK + }) public boolean stopSoftAp() { try { IWifiManager iWifiManager = getIWifiManager(); @@ -2902,6 +2900,13 @@ public class WifiManager { } } + private Executor executorForHandler(@Nullable Handler handler) { + if (handler == null) { + return mContext.getMainExecutor(); + } + return new HandlerExecutor(handler); + } + /** * Request a local only hotspot that an application can use to communicate between co-located * devices connected to the created WiFi hotspot. The network created by this method will not @@ -2959,21 +2964,20 @@ public class WifiManager { */ public void startLocalOnlyHotspot(LocalOnlyHotspotCallback callback, @Nullable Handler handler) { + Executor executor = executorForHandler(handler); synchronized (mLock) { - Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper(); LocalOnlyHotspotCallbackProxy proxy = - new LocalOnlyHotspotCallbackProxy(this, looper, callback); + new LocalOnlyHotspotCallbackProxy(this, executor, callback); try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) { throw new RemoteException("Wifi service is not running"); } String packageName = mContext.getOpPackageName(); - int returnCode = iWifiManager.startLocalOnlyHotspot( - proxy.getMessenger(), new Binder(), packageName); + int returnCode = iWifiManager.startLocalOnlyHotspot(proxy, packageName); if (returnCode != LocalOnlyHotspotCallback.REQUEST_REGISTERED) { // Send message to the proxy to make sure we call back on the correct thread - proxy.notifyFailed(returnCode); + proxy.onHotspotFailed(returnCode); return; } mLOHSCallbackProxy = proxy; @@ -3051,16 +3055,16 @@ public class WifiManager { */ public void watchLocalOnlyHotspot(LocalOnlyHotspotObserver observer, @Nullable Handler handler) { + Executor executor = executorForHandler(handler); synchronized (mLock) { - Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper(); - mLOHSObserverProxy = new LocalOnlyHotspotObserverProxy(this, looper, observer); + mLOHSObserverProxy = + new LocalOnlyHotspotObserverProxy(this, executor, observer); try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) { throw new RemoteException("Wifi service is not running"); } - iWifiManager.startWatchLocalOnlyHotspot( - mLOHSObserverProxy.getMessenger(), new Binder()); + iWifiManager.startWatchLocalOnlyHotspot(mLOHSObserverProxy); mLOHSObserverProxy.registered(); } catch (RemoteException e) { mLOHSObserverProxy = null; @@ -3237,76 +3241,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. @@ -3329,6 +3263,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 @@ -3373,20 +3312,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 @@ -3431,6 +3363,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)}. * @@ -3687,82 +3654,58 @@ public class WifiManager { /** * Callback proxy for LocalOnlyHotspotCallback objects. */ - private static class LocalOnlyHotspotCallbackProxy { - private final Handler mHandler; + private static class LocalOnlyHotspotCallbackProxy extends ILocalOnlyHotspotCallback.Stub { private final WeakReference<WifiManager> mWifiManager; - private final Looper mLooper; - private final Messenger mMessenger; + private final Executor mExecutor; + private final LocalOnlyHotspotCallback mCallback; /** - * Constructs a {@link LocalOnlyHotspotCallback} using the specified looper. All callbacks - * will be delivered on the thread of the specified looper. + * Constructs a {@link LocalOnlyHotspotCallbackProxy} using the specified executor. All + * callbacks will run using the given executor. * * @param manager WifiManager - * @param looper Looper for delivering callbacks + * @param executor Executor for delivering callbacks. * @param callback LocalOnlyHotspotCallback to notify the calling application. */ - LocalOnlyHotspotCallbackProxy(WifiManager manager, Looper looper, - final LocalOnlyHotspotCallback callback) { + LocalOnlyHotspotCallbackProxy(WifiManager manager, Executor executor, + 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; - } + mExecutor = executor; + mCallback = callback; + } - 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); + @Override + public void onHotspotStarted(WifiConfiguration config) { + WifiManager manager = mWifiManager.get(); + if (manager == null) return; + + if (config == null) { + Log.e(TAG, "LocalOnlyHotspotCallbackProxy: config cannot be null."); + onHotspotFailed(LocalOnlyHotspotCallback.ERROR_GENERIC); + return; + } + final LocalOnlyHotspotReservation reservation = + manager.new LocalOnlyHotspotReservation(config); + mExecutor.execute(() -> mCallback.onStarted(reservation)); } - public Messenger getMessenger() { - return mMessenger; + @Override + public void onHotspotStopped() { + WifiManager manager = mWifiManager.get(); + if (manager == null) return; + + Log.w(TAG, "LocalOnlyHotspotCallbackProxy: hotspot stopped"); + mExecutor.execute(() -> mCallback.onStopped()); } - /** - * 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); + @Override + public void onHotspotFailed(int reason) { + WifiManager manager = mWifiManager.get(); + if (manager == null) return; + + Log.w(TAG, "LocalOnlyHotspotCallbackProxy: failed to start. reason: " + + reason); + mExecutor.execute(() -> mCallback.onFailed(reason)); } } @@ -3830,191 +3773,115 @@ public class WifiManager { /** * Callback proxy for LocalOnlyHotspotObserver objects. */ - private static class LocalOnlyHotspotObserverProxy { - private final Handler mHandler; + private static class LocalOnlyHotspotObserverProxy extends ILocalOnlyHotspotCallback.Stub { private final WeakReference<WifiManager> mWifiManager; - private final Looper mLooper; - private final Messenger mMessenger; + private final Executor mExecutor; + private final LocalOnlyHotspotObserver mObserver; /** * 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 executor Executor for delivering callbacks * @param observer LocalOnlyHotspotObserver to notify the calling application. */ - LocalOnlyHotspotObserverProxy(WifiManager manager, Looper looper, + LocalOnlyHotspotObserverProxy(WifiManager manager, Executor executor, 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; + mExecutor = executor; + mObserver = observer; } public void registered() throws RemoteException { - Message msg = Message.obtain(); - msg.what = HOTSPOT_OBSERVER_REGISTERED; - mMessenger.send(msg); - } - } + WifiManager manager = mWifiManager.get(); + if (manager == null) return; - // Ensure that multiple ServiceHandler threads do not interleave message dispatch. - private static final Object sServiceHandlerDispatchLock = new Object(); - - private class ServiceHandler extends Handler { - ServiceHandler(Looper looper) { - super(looper); + mExecutor.execute(() -> + mObserver.onRegistered(manager.new LocalOnlyHotspotSubscription())); } @Override - public void handleMessage(Message message) { - synchronized (sServiceHandlerDispatchLock) { - dispatchMessageToListeners(message); + public void onHotspotStarted(WifiConfiguration config) { + WifiManager manager = mWifiManager.get(); + if (manager == null) return; + + if (config == null) { + Log.e(TAG, "LocalOnlyHotspotObserverProxy: config cannot be null."); + return; } + mExecutor.execute(() -> mObserver.onStarted(config)); } - 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 onHotspotStopped() { + WifiManager manager = mWifiManager.get(); + if (manager == null) return; + + mExecutor.execute(() -> mObserver.onStopped()); } - } - 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); + @Override + public void onHotspotFailed(int reason) { + // do nothing } - 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; + /** + * Callback proxy for ActionListener objects. + */ + private class ActionListenerProxy extends IActionListener.Stub { + private final String mActionTag; + private final Handler mHandler; + private final ActionListener mCallback; + + ActionListenerProxy(String actionTag, Looper looper, ActionListener callback) { + mActionTag = actionTag; + mHandler = new Handler(looper); + mCallback = callback; } - } - private synchronized AsyncChannel getChannel() { - if (mAsyncChannel == null) { - Messenger messenger = getWifiServiceMessenger(); - if (messenger == null) { - throw new IllegalStateException( - "getWifiServiceMessenger() returned null! This is invalid."); + @Override + public void onSuccess() { + if (mVerboseLoggingEnabled) { + Log.v(TAG, "ActionListenerProxy:" + mActionTag + ": onSuccess"); } + mHandler.post(() -> { + mCallback.onSuccess(); + }); + } - mAsyncChannel = new AsyncChannel(); - mConnected = new CountDownLatch(1); + @Override + public void onFailure(@ActionListenerFailureReason int reason) { + if (mVerboseLoggingEnabled) { + Log.v(TAG, "ActionListenerProxy:" + mActionTag + ": onFailure=" + reason); + } + mHandler.post(() -> { + mCallback.onFailure(reason); + }); + } + } - Handler handler = new ServiceHandler(mLooper); - mAsyncChannel.connect(mContext, handler, messenger); - try { - mConnected.await(); - } catch (InterruptedException e) { - Log.e(TAG, "interrupted wait at init"); + 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(); + } + 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; } /** @@ -4040,10 +3907,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); } /** @@ -4066,7 +3930,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); } /** @@ -4097,7 +3961,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); + } } /** @@ -4121,7 +4002,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); + } } /** @@ -4131,6 +4029,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 @@ -4139,9 +4038,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); + } + } } /** @@ -4197,24 +4106,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 @@ -4674,16 +4565,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 @@ -5643,4 +5524,90 @@ public class WifiManager { throw e.rethrowFromSystemServer(); } } + + /** + * Base class for scan results listener. Should be implemented by applications and set when + * calling {@link WifiManager#addScanResultsListener(Executor, ScanResultsListener)}. + */ + public interface ScanResultsListener { + + /** + * Called when new scan results available. + * Caller should use {@link WifiManager#getScanResults()} to get the scan results. + */ + void onScanResultsAvailable(); + } + + private class ScanResultsListenerProxy extends IScanResultsListener.Stub { + private final Executor mExecutor; + private final ScanResultsListener mListener; + + ScanResultsListenerProxy(Executor executor, ScanResultsListener listener) { + mExecutor = executor; + mListener = listener; + } + + @Override + public void onScanResultsAvailable() { + mExecutor.execute(mListener::onScanResultsAvailable); + } + } + + /** + * Add a listener for Scan Results. See {@link ScanResultsListener}. + * Caller will receive the event when scan results are available. + * Caller should use {@link WifiManager#getScanResults()} to get the scan results. + * Caller can remove a previously registered listener using + * {@link WifiManager#removeScanResultsListener(ScanResultsListener)} + * <p> + * Applications should have the + * {@link android.Manifest.permission#ACCESS_WIFI_STATE} permission. Callers + * without the permission will trigger a {@link java.lang.SecurityException}. + * <p> + * + * @param executor The executor to execute the listener of the {@code listener} object. + * @param listener listener for Scan Results events + */ + + @RequiresPermission(ACCESS_WIFI_STATE) + public void addScanResultsListener(@NonNull @CallbackExecutor Executor executor, + @NonNull ScanResultsListener listener) { + if (listener == null) throw new IllegalArgumentException("listener cannot be null"); + if (executor == null) throw new IllegalArgumentException("executor cannot be null"); + Log.v(TAG, "addScanResultsListener: listener=" + listener + ", executor=" + executor); + try { + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.registerScanResultsListener( + new Binder(), + new ScanResultsListenerProxy(executor, listener), + mContext.getOpPackageName().hashCode()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Allow callers to remove a previously added listener. After calling this method, + * applications will no longer receive Scan Results events. + * + * @param listener listener to remove for Scan Results events + */ + @RequiresPermission(ACCESS_WIFI_STATE) + public void removeScanResultsListener(@NonNull ScanResultsListener listener) { + if (listener == null) throw new IllegalArgumentException("listener cannot be null"); + Log.v(TAG, "removeScanResultsListener: listener=" + listener); + + try { + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.unregisterScanResultsListener(mContext.getOpPackageName().hashCode()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } } diff --git a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java index 6c2d7ff882d3..ba9dd37398a1 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java +++ b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java @@ -157,7 +157,8 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc */ public @NonNull Builder setBssidPattern( @NonNull MacAddress baseAddress, @NonNull MacAddress mask) { - checkNotNull(baseAddress, mask); + checkNotNull(baseAddress); + checkNotNull(mask); mBssidPatternMatcher = Pair.create(baseAddress, mask); return this; } diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java index 426201732359..9b529cee58b3 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java +++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java @@ -23,6 +23,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityThread; import android.net.MacAddress; +import android.net.wifi.hotspot2.PasspointConfiguration; import android.os.Parcel; import android.os.Parcelable; import android.os.Process; @@ -80,6 +81,10 @@ public final class WifiNetworkSuggestion implements Parcelable { */ private @Nullable WifiEnterpriseConfig mWpa3EnterpriseConfig; /** + * The passpoint config for use with Hotspot 2.0 network + */ + private @Nullable PasspointConfiguration mPasspointConfiguration; + /** * This is a network that does not broadcast its SSID, so an * SSID-specific probe request must be used for scans. */ @@ -110,6 +115,7 @@ public final class WifiNetworkSuggestion implements Parcelable { mWpa3SaePassphrase = null; mWpa2EnterpriseConfig = null; mWpa3EnterpriseConfig = null; + mPasspointConfiguration = null; mIsHiddenSSID = false; mIsAppInteractionRequired = false; mIsUserInteractionRequired = false; @@ -234,6 +240,24 @@ public final class WifiNetworkSuggestion implements Parcelable { } /** + * Set the associated Passpoint configuration for this network. Needed for authenticating + * to Hotspot 2.0 networks. See {@link PasspointConfiguration} for description. + * + * @param passpointConfig Instance of {@link PasspointConfiguration}. + * @return Instance of {@link Builder} to enable chaining of the builder method. + * @throws IllegalArgumentException if passpoint configuration is invalid. + */ + public @NonNull Builder setPasspointConfig( + @NonNull PasspointConfiguration passpointConfig) { + checkNotNull(passpointConfig); + if (!passpointConfig.validate()) { + throw new IllegalArgumentException("Passpoint configuration is invalid"); + } + mPasspointConfiguration = passpointConfig; + return this; + } + + /** * Specifies whether this represents a hidden network. * <p> * <li>If not set, defaults to false (i.e not a hidden network).</li> @@ -366,13 +390,24 @@ public final class WifiNetworkSuggestion implements Parcelable { numSecurityTypes += !TextUtils.isEmpty(mWpa3SaePassphrase) ? 1 : 0; numSecurityTypes += mWpa2EnterpriseConfig != null ? 1 : 0; numSecurityTypes += mWpa3EnterpriseConfig != null ? 1 : 0; + numSecurityTypes += mPasspointConfiguration != null ? 1 : 0; if (numSecurityTypes > 1) { throw new IllegalStateException("only one of setIsEnhancedOpen, setWpa2Passphrase," - + "setWpa3Passphrase, setWpa2EnterpriseConfig or setWpa3EnterpriseConfig" - + " can be invoked for network specifier"); + + "setWpa3Passphrase, setWpa2EnterpriseConfig, setWpa3EnterpriseConfig" + + "or setPasspointConfig can be invoked for network suggestion"); } } + private WifiConfiguration buildWifiConfigurationForPasspoint() { + WifiConfiguration wifiConfiguration = new WifiConfiguration(); + wifiConfiguration.FQDN = mPasspointConfiguration.getHomeSp().getFqdn(); + wifiConfiguration.priority = mPriority; + wifiConfiguration.meteredOverride = + mIsMetered ? WifiConfiguration.METERED_OVERRIDE_METERED + : WifiConfiguration.METERED_OVERRIDE_NONE; + return wifiConfiguration; + } + /** * Create a network suggestion object for use in * {@link WifiManager#addNetworkSuggestions(List)}. @@ -384,29 +419,36 @@ public final class WifiNetworkSuggestion implements Parcelable { * </p> * * For example: - * To provide credentials for one open, one WPA2 and one WPA3 network with their - * corresponding SSID's: + * To provide credentials for one open, one WPA2, one WPA3 network with their + * corresponding SSID's and one with Passpoint config: * * <pre>{@code * final WifiNetworkSuggestion suggestion1 = * new Builder() * .setSsid("test111111") - * .build() + * .build(); * final WifiNetworkSuggestion suggestion2 = * new Builder() * .setSsid("test222222") * .setWpa2Passphrase("test123456") - * .build() + * .build(); * final WifiNetworkSuggestion suggestion3 = * new Builder() * .setSsid("test333333") * .setWpa3Passphrase("test6789") - * .build() + * .build(); + * final PasspointConfiguration passpointConfig= new PasspointConfiguration(); + * // configure passpointConfig to include a valid Passpoint configuration + * final WifiNetworkSuggestion suggestion4 = + * new Builder() + * .setPasspointConfig(passpointConfig) + * .build(); * final List<WifiNetworkSuggestion> suggestionsList = * new ArrayList<WifiNetworkSuggestion> { { * add(suggestion1); * add(suggestion2); * add(suggestion3); + * add(suggestion4); * } }; * final WifiManager wifiManager = * context.getSystemService(Context.WIFI_SERVICE); @@ -419,21 +461,37 @@ public final class WifiNetworkSuggestion implements Parcelable { * @see WifiNetworkSuggestion */ public @NonNull WifiNetworkSuggestion build() { - if (mSsid == null) { - throw new IllegalStateException("setSsid should be invoked for suggestion"); - } - if (TextUtils.isEmpty(mSsid)) { - throw new IllegalStateException("invalid ssid for suggestion"); - } - if (mBssid != null - && (mBssid.equals(MacAddress.BROADCAST_ADDRESS) - || mBssid.equals(MacAddress.ALL_ZEROS_ADDRESS))) { - throw new IllegalStateException("invalid bssid for suggestion"); - } validateSecurityParams(); + WifiConfiguration wifiConfiguration; + if (mPasspointConfiguration != null) { + if (mSsid != null) { + throw new IllegalStateException("setSsid should not be invoked for suggestion " + + "with Passpoint configuration"); + } + if (mIsHiddenSSID) { + throw new IllegalStateException("setIsHiddenSsid should not be invoked for " + + "suggestion with Passpoint configuration"); + } + wifiConfiguration = buildWifiConfigurationForPasspoint(); + + } else { + if (mSsid == null) { + throw new IllegalStateException("setSsid should be invoked for suggestion"); + } + if (TextUtils.isEmpty(mSsid)) { + throw new IllegalStateException("invalid ssid for suggestion"); + } + if (mBssid != null + && (mBssid.equals(MacAddress.BROADCAST_ADDRESS) + || mBssid.equals(MacAddress.ALL_ZEROS_ADDRESS))) { + throw new IllegalStateException("invalid bssid for suggestion"); + } + wifiConfiguration = buildWifiConfiguration(); + } return new WifiNetworkSuggestion( - buildWifiConfiguration(), + wifiConfiguration, + mPasspointConfiguration, mIsAppInteractionRequired, mIsUserInteractionRequired, Process.myUid(), @@ -448,6 +506,12 @@ public final class WifiNetworkSuggestion implements Parcelable { public final WifiConfiguration wifiConfiguration; /** + * Passpoint configuration for the provided network. + * @hide + */ + public final PasspointConfiguration passpointConfiguration; + + /** * Whether app needs to log in to captive portal to obtain Internet access. * @hide */ @@ -474,6 +538,7 @@ public final class WifiNetworkSuggestion implements Parcelable { /** @hide */ public WifiNetworkSuggestion() { this.wifiConfiguration = null; + this.passpointConfiguration = null; this.isAppInteractionRequired = false; this.isUserInteractionRequired = false; this.suggestorUid = -1; @@ -481,14 +546,16 @@ public final class WifiNetworkSuggestion implements Parcelable { } /** @hide */ - public WifiNetworkSuggestion(@NonNull WifiConfiguration wifiConfiguration, + public WifiNetworkSuggestion(@NonNull WifiConfiguration networkConfiguration, + @Nullable PasspointConfiguration passpointConfiguration, boolean isAppInteractionRequired, boolean isUserInteractionRequired, int suggestorUid, @NonNull String suggestorPackageName) { - checkNotNull(wifiConfiguration); + checkNotNull(networkConfiguration); checkNotNull(suggestorPackageName); + this.wifiConfiguration = networkConfiguration; + this.passpointConfiguration = passpointConfiguration; - this.wifiConfiguration = wifiConfiguration; this.isAppInteractionRequired = isAppInteractionRequired; this.isUserInteractionRequired = isUserInteractionRequired; this.suggestorUid = suggestorUid; @@ -501,6 +568,7 @@ public final class WifiNetworkSuggestion implements Parcelable { public WifiNetworkSuggestion createFromParcel(Parcel in) { return new WifiNetworkSuggestion( in.readParcelable(null), // wifiConfiguration + in.readParcelable(null), // PasspointConfiguration in.readBoolean(), // isAppInteractionRequired in.readBoolean(), // isUserInteractionRequired in.readInt(), // suggestorUid @@ -522,6 +590,7 @@ public final class WifiNetworkSuggestion implements Parcelable { @Override public void writeToParcel(Parcel dest, int flags) { dest.writeParcelable(wifiConfiguration, flags); + dest.writeParcelable(passpointConfiguration, flags); dest.writeBoolean(isAppInteractionRequired); dest.writeBoolean(isUserInteractionRequired); dest.writeInt(suggestorUid); @@ -531,7 +600,8 @@ public final class WifiNetworkSuggestion implements Parcelable { @Override public int hashCode() { return Objects.hash(wifiConfiguration.SSID, wifiConfiguration.BSSID, - wifiConfiguration.allowedKeyManagement, suggestorUid, suggestorPackageName); + wifiConfiguration.allowedKeyManagement, wifiConfiguration.FQDN, + suggestorUid, suggestorPackageName); } /** @@ -546,12 +616,17 @@ public final class WifiNetworkSuggestion implements Parcelable { return false; } WifiNetworkSuggestion lhs = (WifiNetworkSuggestion) obj; - return Objects.equals(this.wifiConfiguration.SSID, lhs.wifiConfiguration.SSID) - && Objects.equals(this.wifiConfiguration.BSSID, lhs.wifiConfiguration.BSSID) + if (this.passpointConfiguration == null ^ lhs.passpointConfiguration == null) { + return false; + } + + return TextUtils.equals(this.wifiConfiguration.SSID, lhs.wifiConfiguration.SSID) + && TextUtils.equals(this.wifiConfiguration.BSSID, lhs.wifiConfiguration.BSSID) && Objects.equals(this.wifiConfiguration.allowedKeyManagement, - lhs.wifiConfiguration.allowedKeyManagement) - && suggestorUid == lhs.suggestorUid - && TextUtils.equals(suggestorPackageName, lhs.suggestorPackageName); + lhs.wifiConfiguration.allowedKeyManagement) + && TextUtils.equals(this.wifiConfiguration.FQDN, lhs.wifiConfiguration.FQDN) + && this.suggestorUid == lhs.suggestorUid + && TextUtils.equals(this.suggestorPackageName, lhs.suggestorPackageName); } @Override @@ -559,6 +634,7 @@ public final class WifiNetworkSuggestion implements Parcelable { StringBuilder sb = new StringBuilder("WifiNetworkSuggestion [") .append(", SSID=").append(wifiConfiguration.SSID) .append(", BSSID=").append(wifiConfiguration.BSSID) + .append(", FQDN=").append(wifiConfiguration.FQDN) .append(", isAppInteractionRequired=").append(isAppInteractionRequired) .append(", isUserInteractionRequired=").append(isUserInteractionRequired) .append(", suggestorUid=").append(suggestorUid) diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index 075531ce158e..68948cbbe7a9 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -17,6 +17,7 @@ package android.net.wifi; import android.Manifest; +import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.annotation.SystemApi; @@ -58,13 +59,23 @@ public class WifiScanner { /** 5 GHz band excluding DFS channels */ public static final int WIFI_BAND_5_GHZ = 2; /* 5 GHz band without DFS channels */ /** DFS channels from 5 GHz band only */ - public static final int WIFI_BAND_5_GHZ_DFS_ONLY = 4; /* 5 GHz band with DFS channels */ + public static final int WIFI_BAND_5_GHZ_DFS_ONLY = 4; /* 5 GHz band DFS channels */ + /** + * 2.4Ghz band + DFS channels from 5 GHz band only + * @hide + */ + public static final int WIFI_BAND_24_GHZ_WITH_5GHZ_DFS = 5; /** 5 GHz band including DFS channels */ public static final int WIFI_BAND_5_GHZ_WITH_DFS = 6; /* 5 GHz band with DFS channels */ /** Both 2.4 GHz band and 5 GHz band; no DFS channels */ public static final int WIFI_BAND_BOTH = 3; /* both bands without DFS channels */ /** Both 2.4 GHz band and 5 GHz band; with DFS channels */ public static final int WIFI_BAND_BOTH_WITH_DFS = 7; /* both bands with DFS channels */ + /** + * Max band value + * @hide + */ + public static final int WIFI_BAND_MAX = 8; /** Minimum supported scanning period */ public static final int MIN_SCAN_PERIOD_MS = 1000; /* minimum supported period */ @@ -375,19 +386,27 @@ public class WifiScanner { */ private int mBandScanned; /** all scan results discovered in this scan, sorted by timestamp in ascending order */ - private ScanResult mResults[]; + private final List<ScanResult> mResults; - ScanData() {} + ScanData() { + mResults = new ArrayList<>(); + } public ScanData(int id, int flags, ScanResult[] results) { mId = id; mFlags = flags; - mResults = results; + mResults = new ArrayList<>(Arrays.asList(results)); } /** {@hide} */ public ScanData(int id, int flags, int bucketsScanned, int bandScanned, ScanResult[] results) { + this(id, flags, bucketsScanned, bandScanned, new ArrayList<>(Arrays.asList(results))); + } + + /** {@hide} */ + public ScanData(int id, int flags, int bucketsScanned, int bandScanned, + List<ScanResult> results) { mId = id; mFlags = flags; mBucketsScanned = bucketsScanned; @@ -400,11 +419,9 @@ public class WifiScanner { mFlags = s.mFlags; mBucketsScanned = s.mBucketsScanned; mBandScanned = s.mBandScanned; - mResults = new ScanResult[s.mResults.length]; - for (int i = 0; i < s.mResults.length; i++) { - ScanResult result = s.mResults[i]; - ScanResult newResult = new ScanResult(result); - mResults[i] = newResult; + mResults = new ArrayList<>(); + for (ScanResult scanResult : s.mResults) { + mResults.add(new ScanResult(scanResult)); } } @@ -427,7 +444,14 @@ public class WifiScanner { } public ScanResult[] getResults() { - return mResults; + return mResults.toArray(new ScanResult[0]); + } + + /** {@hide} */ + public void addResults(@NonNull ScanResult[] newResults) { + for (ScanResult result : newResults) { + mResults.add(new ScanResult(result)); + } } /** Implement the Parcelable interface {@hide} */ @@ -437,19 +461,11 @@ public class WifiScanner { /** Implement the Parcelable interface {@hide} */ public void writeToParcel(Parcel dest, int flags) { - if (mResults != null) { - dest.writeInt(mId); - dest.writeInt(mFlags); - dest.writeInt(mBucketsScanned); - dest.writeInt(mBandScanned); - dest.writeInt(mResults.length); - for (int i = 0; i < mResults.length; i++) { - ScanResult result = mResults[i]; - result.writeToParcel(dest, flags); - } - } else { - dest.writeInt(0); - } + dest.writeInt(mId); + dest.writeInt(mFlags); + dest.writeInt(mBucketsScanned); + dest.writeInt(mBandScanned); + dest.writeParcelableList(mResults, 0); } /** Implement the Parcelable interface {@hide} */ @@ -460,11 +476,8 @@ public class WifiScanner { int flags = in.readInt(); int bucketsScanned = in.readInt(); int bandScanned = in.readInt(); - int n = in.readInt(); - ScanResult results[] = new ScanResult[n]; - for (int i = 0; i < n; i++) { - results[i] = ScanResult.CREATOR.createFromParcel(in); - } + List<ScanResult> results = new ArrayList<>(); + in.readParcelableList(results, ScanResult.class.getClassLoader()); return new ScanData(id, flags, bucketsScanned, bandScanned, results); } diff --git a/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java b/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java index e59516485112..8f3635fd2f04 100644 --- a/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java +++ b/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java @@ -20,8 +20,8 @@ import android.annotation.IntDef; import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; -import android.telephony.TelephonyManager.NetworkType; +import android.telephony.Annotation.NetworkType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/wifi/java/android/net/wifi/hotspot2/ConfigParser.java b/wifi/java/android/net/wifi/hotspot2/ConfigParser.java index e8e873199e17..bb01365d6722 100644 --- a/wifi/java/android/net/wifi/hotspot2/ConfigParser.java +++ b/wifi/java/android/net/wifi/hotspot2/ConfigParser.java @@ -182,6 +182,12 @@ public final class ConfigParser { throw new IOException("Passpoint profile missing credential"); } + // Don't allow the installer to make changes to the update identifier. This is an + // indicator of an R2 (or newer) network. + if (config.getUpdateIdentifier() != Integer.MIN_VALUE) { + config.setUpdateIdentifier(Integer.MIN_VALUE); + } + // Parse CA (Certificate Authority) certificate. byte[] caCertData = mimeParts.get(TYPE_CA_CERT); if (caCertData != null) { diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java index 557b7c9b05e9..e9aa076798e1 100644 --- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java +++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java @@ -65,6 +65,7 @@ public final class PasspointConfiguration implements Parcelable { * Configurations under HomeSp subtree. */ private HomeSp mHomeSp = null; + /** * Set the Home SP (Service Provider) information. * @@ -248,7 +249,10 @@ public final class PasspointConfiguration implements Parcelable { mSubscriptionExpirationTimeInMillis = subscriptionExpirationTimeInMillis; } /** - * @hide + * Utility method to get the time this subscription will expire. It is in the format of number + * of milliseconds since January 1, 1970, 00:00:00 GMT. + * + * @return The time this subscription will expire, or Long.MIN_VALUE to indicate unset value */ public long getSubscriptionExpirationTimeInMillis() { return mSubscriptionExpirationTimeInMillis; @@ -521,6 +525,8 @@ public final class PasspointConfiguration implements Parcelable { .append("\n"); builder.append("UsageLimitDataLimit: ").append(mUsageLimitDataLimit).append("\n"); builder.append("UsageLimitTimeLimit: ").append(mUsageLimitTimeLimitInMinutes).append("\n"); + builder.append("Provisioned by a subscription server: ") + .append(isOsuProvisioned() ? "Yes" : "No").append("\n"); if (mHomeSp != null) { builder.append("HomeSP Begin ---\n"); builder.append(mHomeSp); @@ -728,4 +734,14 @@ public final class PasspointConfiguration implements Parcelable { } return true; } + + /** + * Indicates if the Passpoint Configuration was provisioned by a subscription (OSU) server, + * which means that it's an R2 (or R3) profile. + * + * @return true if the Passpoint Configuration was provisioned by a subscription server. + */ + public boolean isOsuProvisioned() { + return getUpdateIdentifier() != Integer.MIN_VALUE; + } } diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index 03eb169f60b9..300f1a28416b 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -21,11 +21,15 @@ 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.ILocalOnlyHotspotCallback; import android.net.wifi.INetworkRequestMatchCallback; import android.net.wifi.IOnWifiUsabilityStatsListener; +import android.net.wifi.IScanResultsListener; 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; @@ -205,11 +209,6 @@ public class BaseWifiService extends IWifiManager.Stub { } @Override - public void setCountryCode(String country) { - throw new UnsupportedOperationException(); - } - - @Override public String getCountryCode() { throw new UnsupportedOperationException(); } @@ -284,22 +283,34 @@ public class BaseWifiService extends IWifiManager.Stub { throw new UnsupportedOperationException(); } - @Override + /** @deprecated replaced by {@link #startLocalOnlyHotspot(ILocalOnlyHotspotCallback, String)} */ + @Deprecated public int startLocalOnlyHotspot(Messenger messenger, IBinder binder, String packageName) { throw new UnsupportedOperationException(); } @Override - public void stopLocalOnlyHotspot() { + public int startLocalOnlyHotspot(ILocalOnlyHotspotCallback callback, String packageName) { throw new UnsupportedOperationException(); } @Override + public void stopLocalOnlyHotspot() { + throw new UnsupportedOperationException(); + } + + /** @deprecated replaced by {@link #startWatchLocalOnlyHotspot(ILocalOnlyHotspotCallback)} */ + @Deprecated public void startWatchLocalOnlyHotspot(Messenger messenger, IBinder binder) { throw new UnsupportedOperationException(); } @Override + public void startWatchLocalOnlyHotspot(ILocalOnlyHotspotCallback callback) { + throw new UnsupportedOperationException(); + } + + @Override public void stopWatchLocalOnlyHotspot() { throw new UnsupportedOperationException(); } @@ -325,11 +336,6 @@ public class BaseWifiService extends IWifiManager.Stub { } @Override - public Messenger getWifiServiceMessenger(String packageName) { - throw new UnsupportedOperationException(); - } - - @Override public void enableTdls(String remoteIPAddress, boolean enable) { throw new UnsupportedOperationException(); } @@ -494,6 +500,41 @@ public class BaseWifiService extends IWifiManager.Stub { } @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(); + } + + @Override + public void registerScanResultsListener( + IBinder binder, IScanResultsListener listener, int listenerIdentifier) { + throw new UnsupportedOperationException(); + } + + @Override + public void unregisterScanResultsListener(int listenerIdentifier) { + throw new UnsupportedOperationException(); + } + + @Override public boolean isWifiCoverageExtendFeatureEnabled() { throw new UnsupportedOperationException(); } |