Loading api/system-current.txt +8 −1 Original line number Diff line number Diff line Loading @@ -5392,11 +5392,15 @@ package android.net.wifi { ctor public EasyConnectStatusCallback(); method public abstract void onConfiguratorSuccess(int); method public abstract void onEnrolleeSuccess(int); method public abstract void onFailure(int); method public void onFailure(int); method public void onFailure(int, @Nullable String, @NonNull android.util.SparseArray<int[]>, @NonNull int[]); method public abstract void onProgress(int); field public static final int EASY_CONNECT_EVENT_FAILURE_AUTHENTICATION = -2; // 0xfffffffe field public static final int EASY_CONNECT_EVENT_FAILURE_BUSY = -5; // 0xfffffffb field public static final int EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK = -10; // 0xfffffff6 field public static final int EASY_CONNECT_EVENT_FAILURE_CONFIGURATION = -4; // 0xfffffffc field public static final int EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION = -11; // 0xfffffff5 field public static final int EASY_CONNECT_EVENT_FAILURE_ENROLLEE_REJECTED_CONFIGURATION = -12; // 0xfffffff4 field public static final int EASY_CONNECT_EVENT_FAILURE_GENERIC = -7; // 0xfffffff9 field public static final int EASY_CONNECT_EVENT_FAILURE_INVALID_NETWORK = -9; // 0xfffffff7 field public static final int EASY_CONNECT_EVENT_FAILURE_INVALID_URI = -1; // 0xffffffff Loading @@ -5404,7 +5408,10 @@ package android.net.wifi { field public static final int EASY_CONNECT_EVENT_FAILURE_NOT_SUPPORTED = -8; // 0xfffffff8 field public static final int EASY_CONNECT_EVENT_FAILURE_TIMEOUT = -6; // 0xfffffffa field public static final int EASY_CONNECT_EVENT_PROGRESS_AUTHENTICATION_SUCCESS = 0; // 0x0 field public static final int EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_ACCEPTED = 3; // 0x3 field public static final int EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_SENT_WAITING_RESPONSE = 2; // 0x2 field public static final int EASY_CONNECT_EVENT_PROGRESS_RESPONSE_PENDING = 1; // 0x1 field public static final int EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED = 1; // 0x1 field public static final int EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT = 0; // 0x0 } Loading wifi/java/android/net/wifi/EasyConnectStatusCallback.java +83 −19 Original line number Diff line number Diff line Loading @@ -17,32 +17,46 @@ package android.net.wifi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.os.Handler; import android.util.SparseArray; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.concurrent.Executor; /** * Easy Connect (DPP) Status Callback. Use this callback to get status updates (success, failure, * progress) from the Easy Connect operation started with * {@link WifiManager#startEasyConnectAsConfiguratorInitiator(String, * int, int, Handler, EasyConnectStatusCallback)} or * {@link WifiManager#startEasyConnectAsEnrolleeInitiator(String, * Handler, EasyConnectStatusCallback)} * {@link WifiManager#startEasyConnectAsConfiguratorInitiator(String, int, int, Executor, * EasyConnectStatusCallback)} or {@link WifiManager#startEasyConnectAsEnrolleeInitiator(String, * Executor, EasyConnectStatusCallback)} * * @hide */ @SystemApi public abstract class EasyConnectStatusCallback { /** * Easy Connect Success event: Configuration sent (Configurator mode). * Easy Connect R1 Success event: Configuration sent (Configurator mode). This is the last * and final Easy Connect event when either the local device or remote device implement R1. * If both devices implement R2, this event will never be received, and the * {@link EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED} will be received. */ public static final int EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT = 0; /** * East Connect R2 Success event: Configuration applied by Enrollee (Configurator mode). * This is the last and final Easy Connect event when both the local device and remote device * implement R2. If either the local device or remote device implement R1, this event will never * be received, and the {@link EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT} will be received. */ public static final int EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED = 1; /** @hide */ @IntDef(prefix = {"EASY_CONNECT_EVENT_SUCCESS_"}, value = { EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT, EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED, }) @Retention(RetentionPolicy.SOURCE) public @interface EasyConnectSuccessStatusCode { Loading @@ -58,10 +72,22 @@ public abstract class EasyConnectStatusCallback { */ public static final int EASY_CONNECT_EVENT_PROGRESS_RESPONSE_PENDING = 1; /** * Easy Connect R2 Progress event: Configuration sent to Enrollee, waiting for response */ public static final int EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_SENT_WAITING_RESPONSE = 2; /** * Easy Connect R2 Progress event: Configuration accepted by Enrollee, waiting for response */ public static final int EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_ACCEPTED = 3; /** @hide */ @IntDef(prefix = {"EASY_CONNECT_EVENT_PROGRESS_"}, value = { EASY_CONNECT_EVENT_PROGRESS_AUTHENTICATION_SUCCESS, EASY_CONNECT_EVENT_PROGRESS_RESPONSE_PENDING, EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_SENT_WAITING_RESPONSE, EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_ACCEPTED, }) @Retention(RetentionPolicy.SOURCE) public @interface EasyConnectProgressStatusCode { Loading Loading @@ -114,6 +140,20 @@ public abstract class EasyConnectStatusCallback { */ public static final int EASY_CONNECT_EVENT_FAILURE_INVALID_NETWORK = -9; /** * Easy Connect R2 Failure event: Enrollee cannot find the network. */ public static final int EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK = -10; /** * Easy Connect R2 Failure event: Enrollee failed to authenticate with the network. */ public static final int EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION = -11; /** * Easy Connect R2 Failure event: Enrollee rejected the configuration. */ public static final int EASY_CONNECT_EVENT_FAILURE_ENROLLEE_REJECTED_CONFIGURATION = -12; /** @hide */ @IntDef(prefix = {"EASY_CONNECT_EVENT_FAILURE_"}, value = { Loading @@ -126,6 +166,9 @@ public abstract class EasyConnectStatusCallback { EASY_CONNECT_EVENT_FAILURE_GENERIC, EASY_CONNECT_EVENT_FAILURE_NOT_SUPPORTED, EASY_CONNECT_EVENT_FAILURE_INVALID_NETWORK, EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK, EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION, EASY_CONNECT_EVENT_FAILURE_ENROLLEE_REJECTED_CONFIGURATION, }) @Retention(RetentionPolicy.SOURCE) public @interface EasyConnectFailureStatusCode { Loading @@ -138,8 +181,7 @@ public abstract class EasyConnectStatusCallback { * current Easy Connect * session, and no further callbacks will be called. This callback is the successful outcome * of a Easy Connect flow starting with * {@link WifiManager#startEasyConnectAsEnrolleeInitiator(String, * Handler, * {@link WifiManager#startEasyConnectAsEnrolleeInitiator(String, Executor, * EasyConnectStatusCallback)} . * * @param newNetworkId New Wi-Fi configuration with a network ID received from the configurator Loading @@ -148,13 +190,11 @@ public abstract class EasyConnectStatusCallback { /** * Called when a Easy Connect success event takes place, except for when configuration is * received from * an external Configurator. The callback onSuccessConfigReceived will be used in this case. * This callback marks the successful end of the current Easy Connect session, and no further * callbacks will be called. This callback is the successful outcome of a Easy Connect flow * starting with * {@link WifiManager#startEasyConnectAsConfiguratorInitiator(String, int, int, Handler, * EasyConnectStatusCallback)}. * received from an external Configurator. The callback onSuccessConfigReceived will be used in * this case. This callback marks the successful end of the current Easy Connect session, and no * further callbacks will be called. This callback is the successful outcome of a Easy Connect * flow starting with {@link WifiManager#startEasyConnectAsConfiguratorInitiator(String, int, * int, Executor,EasyConnectStatusCallback)}. * * @param code Easy Connect success status code. */ Loading @@ -162,12 +202,36 @@ public abstract class EasyConnectStatusCallback { /** * Called when a Easy Connect Failure event takes place. This callback marks the unsuccessful * end of the * current Easy Connect session, and no further callbacks will be called. * end of the current Easy Connect session, and no further callbacks will be called. * * @param code Easy Connect failure status code. */ public abstract void onFailure(@EasyConnectFailureStatusCode int code); public void onFailure(@EasyConnectFailureStatusCode int code) {} /** * Called when a Easy Connect Failure event takes place. This callback marks the unsuccessful * end of the current Easy Connect session, and no further callbacks will be called. * * Note: Easy Connect (DPP) R2, provides additional details for the Configurator when the * remote Enrollee is unable to connect to a network. The ssid, channelList and bandList * inputs are initialized only for the EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK failure * code, and the ssid and bandList are initialized for the * EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION failure code. * * @param code Easy Connect failure status code. * @param ssid SSID of the network the Enrollee tried to connect to. * @param channelListArray List of Global Operating classes and channel sets the Enrollee used * to scan to find the network, see the "DPP Connection Status Object" * section in the specification for the format, and Table E-4 in * IEEE Std 802.11-2016 - Global operating classes for more details. * @param operatingClassArray Array of bands the Enrollee supports as expressed as the Global * Operating Class, see Table E-4 in IEEE Std 802.11-2016 - Global * operating classes. */ public void onFailure(@EasyConnectFailureStatusCode int code, @Nullable String ssid, @NonNull SparseArray<int[]> channelListArray, @NonNull int[] operatingClassArray) { onFailure(code); } /** * Called when Easy Connect events that indicate progress take place. Can be used by UI elements Loading wifi/java/android/net/wifi/IDppCallback.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ oneway interface IDppCallback /** * Called when DPP Failure events take place. */ void onFailure(int status); void onFailure(int status, String ssid, String channelList, in int[] bandArray); /** * Called when DPP events that indicate progress take place. Can be used by UI elements Loading wifi/java/android/net/wifi/WifiManager.java +84 −2 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ import android.text.TextUtils; import android.util.CloseGuard; import android.util.Log; import android.util.Pair; import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; Loading @@ -70,6 +71,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.StringTokenizer; import java.util.concurrent.Executor; /** Loading Loading @@ -5177,6 +5179,7 @@ public class WifiManager { @Override public void onSuccessConfigReceived(int newNetworkId) { Log.d(TAG, "Easy Connect onSuccessConfigReceived callback"); Binder.clearCallingIdentity(); mExecutor.execute(() -> { mEasyConnectStatusCallback.onEnrolleeSuccess(newNetworkId); }); Loading @@ -5185,22 +5188,28 @@ public class WifiManager { @Override public void onSuccess(int status) { Log.d(TAG, "Easy Connect onSuccess callback"); Binder.clearCallingIdentity(); mExecutor.execute(() -> { mEasyConnectStatusCallback.onConfiguratorSuccess(status); }); } @Override public void onFailure(int status) { public void onFailure(int status, String ssid, String channelList, int[] operatingClassArray) { Log.d(TAG, "Easy Connect onFailure callback"); Binder.clearCallingIdentity(); mExecutor.execute(() -> { mEasyConnectStatusCallback.onFailure(status); SparseArray<int[]> channelListArray = parseDppChannelList(channelList); mEasyConnectStatusCallback.onFailure(status, ssid, channelListArray, operatingClassArray); }); } @Override public void onProgress(int status) { Log.d(TAG, "Easy Connect onProgress callback"); Binder.clearCallingIdentity(); mExecutor.execute(() -> { mEasyConnectStatusCallback.onProgress(status); }); Loading Loading @@ -5532,4 +5541,77 @@ public class WifiManager { throw e.rethrowFromSystemServer(); } } /** * Parse the list of channels the DPP enrollee reports when it fails to find an AP. * * @param channelList List of channels in the format defined in the DPP specification. * @return A parsed sparse array, where the operating class is the key. * @hide */ @VisibleForTesting public static SparseArray<int[]> parseDppChannelList(String channelList) { SparseArray<int[]> channelListArray = new SparseArray<>(); if (TextUtils.isEmpty(channelList)) { return channelListArray; } StringTokenizer str = new StringTokenizer(channelList, ","); String classStr = null; List<Integer> channelsInClass = new ArrayList<>(); try { while (str.hasMoreElements()) { String cur = str.nextToken(); /** * Example for a channel list: * * 81/1,2,3,4,5,6,7,8,9,10,11,115/36,40,44,48,118/52,56,60,64,121/100,104,108,112, * 116,120,124,128,132,136,140,0/144,124/149,153,157,161,125/165 * * Detect operating class by the delimiter of '/' and use a string tokenizer with * ',' as a delimiter. */ int classDelim = cur.indexOf('/'); if (classDelim != -1) { if (classStr != null) { // Store the last channel array in the sparse array, where the operating // class is the key (as an integer). int[] channelsArray = new int[channelsInClass.size()]; for (int i = 0; i < channelsInClass.size(); i++) { channelsArray[i] = channelsInClass.get(i); } channelListArray.append(Integer.parseInt(classStr), channelsArray); channelsInClass = new ArrayList<>(); } // Init a new operating class and store the first channel classStr = cur.substring(0, classDelim); String channelStr = cur.substring(classDelim + 1); channelsInClass.add(Integer.parseInt(channelStr)); } else { if (classStr == null) { // Invalid format Log.e(TAG, "Cannot parse DPP channel list"); return new SparseArray<>(); } channelsInClass.add(Integer.parseInt(cur)); } } // Store the last array if (classStr != null) { int[] channelsArray = new int[channelsInClass.size()]; for (int i = 0; i < channelsInClass.size(); i++) { channelsArray[i] = channelsInClass.get(i); } channelListArray.append(Integer.parseInt(classStr), channelsArray); } return channelListArray; } catch (NumberFormatException e) { Log.e(TAG, "Cannot parse DPP channel list"); return new SparseArray<>(); } } } wifi/tests/src/android/net/wifi/EasyConnectStatusCallbackTest.java 0 → 100644 +84 −0 Original line number Diff line number Diff line /* * 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 static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import android.util.SparseArray; import androidx.test.filters.SmallTest; import org.junit.Before; import org.junit.Test; /** * Unit tests for {@link android.net.wifi.EasyConnectStatusCallbackTest}. */ @SmallTest public class EasyConnectStatusCallbackTest { private EasyConnectStatusCallback mEasyConnectStatusCallback = new EasyConnectStatusCallback() { @Override public void onEnrolleeSuccess(int newNetworkId) { } @Override public void onConfiguratorSuccess(int code) { } @Override public void onProgress(int code) { } @Override public void onFailure(int code) { mOnFailureR1EventReceived = true; mLastCode = code; } }; private boolean mOnFailureR1EventReceived; private int mLastCode; @Before public void setUp() { mOnFailureR1EventReceived = false; mLastCode = 0; } /** * Test that the legacy R1 onFailure is called by default if the R2 onFailure is not overridden * by the app. */ @Test public void testR1OnFailureCalled() { SparseArray<int[]> channelList = new SparseArray<>(); int[] channelArray = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; channelList.append(81, channelArray); mEasyConnectStatusCallback.onFailure( EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK, "SomeSSID", channelList, new int[] {81}); assertTrue(mOnFailureR1EventReceived); assertEquals(mLastCode, EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK); } } Loading
api/system-current.txt +8 −1 Original line number Diff line number Diff line Loading @@ -5392,11 +5392,15 @@ package android.net.wifi { ctor public EasyConnectStatusCallback(); method public abstract void onConfiguratorSuccess(int); method public abstract void onEnrolleeSuccess(int); method public abstract void onFailure(int); method public void onFailure(int); method public void onFailure(int, @Nullable String, @NonNull android.util.SparseArray<int[]>, @NonNull int[]); method public abstract void onProgress(int); field public static final int EASY_CONNECT_EVENT_FAILURE_AUTHENTICATION = -2; // 0xfffffffe field public static final int EASY_CONNECT_EVENT_FAILURE_BUSY = -5; // 0xfffffffb field public static final int EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK = -10; // 0xfffffff6 field public static final int EASY_CONNECT_EVENT_FAILURE_CONFIGURATION = -4; // 0xfffffffc field public static final int EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION = -11; // 0xfffffff5 field public static final int EASY_CONNECT_EVENT_FAILURE_ENROLLEE_REJECTED_CONFIGURATION = -12; // 0xfffffff4 field public static final int EASY_CONNECT_EVENT_FAILURE_GENERIC = -7; // 0xfffffff9 field public static final int EASY_CONNECT_EVENT_FAILURE_INVALID_NETWORK = -9; // 0xfffffff7 field public static final int EASY_CONNECT_EVENT_FAILURE_INVALID_URI = -1; // 0xffffffff Loading @@ -5404,7 +5408,10 @@ package android.net.wifi { field public static final int EASY_CONNECT_EVENT_FAILURE_NOT_SUPPORTED = -8; // 0xfffffff8 field public static final int EASY_CONNECT_EVENT_FAILURE_TIMEOUT = -6; // 0xfffffffa field public static final int EASY_CONNECT_EVENT_PROGRESS_AUTHENTICATION_SUCCESS = 0; // 0x0 field public static final int EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_ACCEPTED = 3; // 0x3 field public static final int EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_SENT_WAITING_RESPONSE = 2; // 0x2 field public static final int EASY_CONNECT_EVENT_PROGRESS_RESPONSE_PENDING = 1; // 0x1 field public static final int EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED = 1; // 0x1 field public static final int EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT = 0; // 0x0 } Loading
wifi/java/android/net/wifi/EasyConnectStatusCallback.java +83 −19 Original line number Diff line number Diff line Loading @@ -17,32 +17,46 @@ package android.net.wifi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.os.Handler; import android.util.SparseArray; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.concurrent.Executor; /** * Easy Connect (DPP) Status Callback. Use this callback to get status updates (success, failure, * progress) from the Easy Connect operation started with * {@link WifiManager#startEasyConnectAsConfiguratorInitiator(String, * int, int, Handler, EasyConnectStatusCallback)} or * {@link WifiManager#startEasyConnectAsEnrolleeInitiator(String, * Handler, EasyConnectStatusCallback)} * {@link WifiManager#startEasyConnectAsConfiguratorInitiator(String, int, int, Executor, * EasyConnectStatusCallback)} or {@link WifiManager#startEasyConnectAsEnrolleeInitiator(String, * Executor, EasyConnectStatusCallback)} * * @hide */ @SystemApi public abstract class EasyConnectStatusCallback { /** * Easy Connect Success event: Configuration sent (Configurator mode). * Easy Connect R1 Success event: Configuration sent (Configurator mode). This is the last * and final Easy Connect event when either the local device or remote device implement R1. * If both devices implement R2, this event will never be received, and the * {@link EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED} will be received. */ public static final int EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT = 0; /** * East Connect R2 Success event: Configuration applied by Enrollee (Configurator mode). * This is the last and final Easy Connect event when both the local device and remote device * implement R2. If either the local device or remote device implement R1, this event will never * be received, and the {@link EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT} will be received. */ public static final int EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED = 1; /** @hide */ @IntDef(prefix = {"EASY_CONNECT_EVENT_SUCCESS_"}, value = { EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT, EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED, }) @Retention(RetentionPolicy.SOURCE) public @interface EasyConnectSuccessStatusCode { Loading @@ -58,10 +72,22 @@ public abstract class EasyConnectStatusCallback { */ public static final int EASY_CONNECT_EVENT_PROGRESS_RESPONSE_PENDING = 1; /** * Easy Connect R2 Progress event: Configuration sent to Enrollee, waiting for response */ public static final int EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_SENT_WAITING_RESPONSE = 2; /** * Easy Connect R2 Progress event: Configuration accepted by Enrollee, waiting for response */ public static final int EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_ACCEPTED = 3; /** @hide */ @IntDef(prefix = {"EASY_CONNECT_EVENT_PROGRESS_"}, value = { EASY_CONNECT_EVENT_PROGRESS_AUTHENTICATION_SUCCESS, EASY_CONNECT_EVENT_PROGRESS_RESPONSE_PENDING, EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_SENT_WAITING_RESPONSE, EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_ACCEPTED, }) @Retention(RetentionPolicy.SOURCE) public @interface EasyConnectProgressStatusCode { Loading Loading @@ -114,6 +140,20 @@ public abstract class EasyConnectStatusCallback { */ public static final int EASY_CONNECT_EVENT_FAILURE_INVALID_NETWORK = -9; /** * Easy Connect R2 Failure event: Enrollee cannot find the network. */ public static final int EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK = -10; /** * Easy Connect R2 Failure event: Enrollee failed to authenticate with the network. */ public static final int EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION = -11; /** * Easy Connect R2 Failure event: Enrollee rejected the configuration. */ public static final int EASY_CONNECT_EVENT_FAILURE_ENROLLEE_REJECTED_CONFIGURATION = -12; /** @hide */ @IntDef(prefix = {"EASY_CONNECT_EVENT_FAILURE_"}, value = { Loading @@ -126,6 +166,9 @@ public abstract class EasyConnectStatusCallback { EASY_CONNECT_EVENT_FAILURE_GENERIC, EASY_CONNECT_EVENT_FAILURE_NOT_SUPPORTED, EASY_CONNECT_EVENT_FAILURE_INVALID_NETWORK, EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK, EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION, EASY_CONNECT_EVENT_FAILURE_ENROLLEE_REJECTED_CONFIGURATION, }) @Retention(RetentionPolicy.SOURCE) public @interface EasyConnectFailureStatusCode { Loading @@ -138,8 +181,7 @@ public abstract class EasyConnectStatusCallback { * current Easy Connect * session, and no further callbacks will be called. This callback is the successful outcome * of a Easy Connect flow starting with * {@link WifiManager#startEasyConnectAsEnrolleeInitiator(String, * Handler, * {@link WifiManager#startEasyConnectAsEnrolleeInitiator(String, Executor, * EasyConnectStatusCallback)} . * * @param newNetworkId New Wi-Fi configuration with a network ID received from the configurator Loading @@ -148,13 +190,11 @@ public abstract class EasyConnectStatusCallback { /** * Called when a Easy Connect success event takes place, except for when configuration is * received from * an external Configurator. The callback onSuccessConfigReceived will be used in this case. * This callback marks the successful end of the current Easy Connect session, and no further * callbacks will be called. This callback is the successful outcome of a Easy Connect flow * starting with * {@link WifiManager#startEasyConnectAsConfiguratorInitiator(String, int, int, Handler, * EasyConnectStatusCallback)}. * received from an external Configurator. The callback onSuccessConfigReceived will be used in * this case. This callback marks the successful end of the current Easy Connect session, and no * further callbacks will be called. This callback is the successful outcome of a Easy Connect * flow starting with {@link WifiManager#startEasyConnectAsConfiguratorInitiator(String, int, * int, Executor,EasyConnectStatusCallback)}. * * @param code Easy Connect success status code. */ Loading @@ -162,12 +202,36 @@ public abstract class EasyConnectStatusCallback { /** * Called when a Easy Connect Failure event takes place. This callback marks the unsuccessful * end of the * current Easy Connect session, and no further callbacks will be called. * end of the current Easy Connect session, and no further callbacks will be called. * * @param code Easy Connect failure status code. */ public abstract void onFailure(@EasyConnectFailureStatusCode int code); public void onFailure(@EasyConnectFailureStatusCode int code) {} /** * Called when a Easy Connect Failure event takes place. This callback marks the unsuccessful * end of the current Easy Connect session, and no further callbacks will be called. * * Note: Easy Connect (DPP) R2, provides additional details for the Configurator when the * remote Enrollee is unable to connect to a network. The ssid, channelList and bandList * inputs are initialized only for the EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK failure * code, and the ssid and bandList are initialized for the * EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION failure code. * * @param code Easy Connect failure status code. * @param ssid SSID of the network the Enrollee tried to connect to. * @param channelListArray List of Global Operating classes and channel sets the Enrollee used * to scan to find the network, see the "DPP Connection Status Object" * section in the specification for the format, and Table E-4 in * IEEE Std 802.11-2016 - Global operating classes for more details. * @param operatingClassArray Array of bands the Enrollee supports as expressed as the Global * Operating Class, see Table E-4 in IEEE Std 802.11-2016 - Global * operating classes. */ public void onFailure(@EasyConnectFailureStatusCode int code, @Nullable String ssid, @NonNull SparseArray<int[]> channelListArray, @NonNull int[] operatingClassArray) { onFailure(code); } /** * Called when Easy Connect events that indicate progress take place. Can be used by UI elements Loading
wifi/java/android/net/wifi/IDppCallback.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ oneway interface IDppCallback /** * Called when DPP Failure events take place. */ void onFailure(int status); void onFailure(int status, String ssid, String channelList, in int[] bandArray); /** * Called when DPP events that indicate progress take place. Can be used by UI elements Loading
wifi/java/android/net/wifi/WifiManager.java +84 −2 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ import android.text.TextUtils; import android.util.CloseGuard; import android.util.Log; import android.util.Pair; import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; Loading @@ -70,6 +71,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.StringTokenizer; import java.util.concurrent.Executor; /** Loading Loading @@ -5177,6 +5179,7 @@ public class WifiManager { @Override public void onSuccessConfigReceived(int newNetworkId) { Log.d(TAG, "Easy Connect onSuccessConfigReceived callback"); Binder.clearCallingIdentity(); mExecutor.execute(() -> { mEasyConnectStatusCallback.onEnrolleeSuccess(newNetworkId); }); Loading @@ -5185,22 +5188,28 @@ public class WifiManager { @Override public void onSuccess(int status) { Log.d(TAG, "Easy Connect onSuccess callback"); Binder.clearCallingIdentity(); mExecutor.execute(() -> { mEasyConnectStatusCallback.onConfiguratorSuccess(status); }); } @Override public void onFailure(int status) { public void onFailure(int status, String ssid, String channelList, int[] operatingClassArray) { Log.d(TAG, "Easy Connect onFailure callback"); Binder.clearCallingIdentity(); mExecutor.execute(() -> { mEasyConnectStatusCallback.onFailure(status); SparseArray<int[]> channelListArray = parseDppChannelList(channelList); mEasyConnectStatusCallback.onFailure(status, ssid, channelListArray, operatingClassArray); }); } @Override public void onProgress(int status) { Log.d(TAG, "Easy Connect onProgress callback"); Binder.clearCallingIdentity(); mExecutor.execute(() -> { mEasyConnectStatusCallback.onProgress(status); }); Loading Loading @@ -5532,4 +5541,77 @@ public class WifiManager { throw e.rethrowFromSystemServer(); } } /** * Parse the list of channels the DPP enrollee reports when it fails to find an AP. * * @param channelList List of channels in the format defined in the DPP specification. * @return A parsed sparse array, where the operating class is the key. * @hide */ @VisibleForTesting public static SparseArray<int[]> parseDppChannelList(String channelList) { SparseArray<int[]> channelListArray = new SparseArray<>(); if (TextUtils.isEmpty(channelList)) { return channelListArray; } StringTokenizer str = new StringTokenizer(channelList, ","); String classStr = null; List<Integer> channelsInClass = new ArrayList<>(); try { while (str.hasMoreElements()) { String cur = str.nextToken(); /** * Example for a channel list: * * 81/1,2,3,4,5,6,7,8,9,10,11,115/36,40,44,48,118/52,56,60,64,121/100,104,108,112, * 116,120,124,128,132,136,140,0/144,124/149,153,157,161,125/165 * * Detect operating class by the delimiter of '/' and use a string tokenizer with * ',' as a delimiter. */ int classDelim = cur.indexOf('/'); if (classDelim != -1) { if (classStr != null) { // Store the last channel array in the sparse array, where the operating // class is the key (as an integer). int[] channelsArray = new int[channelsInClass.size()]; for (int i = 0; i < channelsInClass.size(); i++) { channelsArray[i] = channelsInClass.get(i); } channelListArray.append(Integer.parseInt(classStr), channelsArray); channelsInClass = new ArrayList<>(); } // Init a new operating class and store the first channel classStr = cur.substring(0, classDelim); String channelStr = cur.substring(classDelim + 1); channelsInClass.add(Integer.parseInt(channelStr)); } else { if (classStr == null) { // Invalid format Log.e(TAG, "Cannot parse DPP channel list"); return new SparseArray<>(); } channelsInClass.add(Integer.parseInt(cur)); } } // Store the last array if (classStr != null) { int[] channelsArray = new int[channelsInClass.size()]; for (int i = 0; i < channelsInClass.size(); i++) { channelsArray[i] = channelsInClass.get(i); } channelListArray.append(Integer.parseInt(classStr), channelsArray); } return channelListArray; } catch (NumberFormatException e) { Log.e(TAG, "Cannot parse DPP channel list"); return new SparseArray<>(); } } }
wifi/tests/src/android/net/wifi/EasyConnectStatusCallbackTest.java 0 → 100644 +84 −0 Original line number Diff line number Diff line /* * 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 static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import android.util.SparseArray; import androidx.test.filters.SmallTest; import org.junit.Before; import org.junit.Test; /** * Unit tests for {@link android.net.wifi.EasyConnectStatusCallbackTest}. */ @SmallTest public class EasyConnectStatusCallbackTest { private EasyConnectStatusCallback mEasyConnectStatusCallback = new EasyConnectStatusCallback() { @Override public void onEnrolleeSuccess(int newNetworkId) { } @Override public void onConfiguratorSuccess(int code) { } @Override public void onProgress(int code) { } @Override public void onFailure(int code) { mOnFailureR1EventReceived = true; mLastCode = code; } }; private boolean mOnFailureR1EventReceived; private int mLastCode; @Before public void setUp() { mOnFailureR1EventReceived = false; mLastCode = 0; } /** * Test that the legacy R1 onFailure is called by default if the R2 onFailure is not overridden * by the app. */ @Test public void testR1OnFailureCalled() { SparseArray<int[]> channelList = new SparseArray<>(); int[] channelArray = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; channelList.append(81, channelArray); mEasyConnectStatusCallback.onFailure( EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK, "SomeSSID", channelList, new int[] {81}); assertTrue(mOnFailureR1EventReceived); assertEquals(mLastCode, EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK); } }