From a330174d8d132cecce7eebc35b2df1cec30ca80c Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Mon, 8 Apr 2019 18:15:26 +0800 Subject: p2p: unit tests for WifiP2pGroupList Bug: 130138124 Test: atest FrameworksWifiApiTests Change-Id: I51f6fb88983ce8d0f45139241954ca1de1553fcf --- .../android/net/wifi/p2p/WifiP2pGroupListTest.java | 115 +++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 wifi/tests/src/android/net/wifi/p2p/WifiP2pGroupListTest.java (limited to 'wifi') diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pGroupListTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pGroupListTest.java new file mode 100644 index 000000000000..2402f5bb4658 --- /dev/null +++ b/wifi/tests/src/android/net/wifi/p2p/WifiP2pGroupListTest.java @@ -0,0 +1,115 @@ +/* + * 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.p2p; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import android.os.Parcel; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Test; + +/** + * Unit test harness for {@link android.net.wifi.p2p.WifiP2pGroupList} + */ +@SmallTest +public class WifiP2pGroupListTest { + + private static final WifiP2pDevice TEST_GROUP_OWNER_1 = new WifiP2pDevice("aa:bb:cc:dd:ee:f0"); + private static final WifiP2pDevice TEST_GROUP_OWNER_2 = new WifiP2pDevice("aa:bb:cc:dd:ee:f1"); + private static final WifiP2pDevice TEST_GROUP_OWNER_3 = new WifiP2pDevice("aa:bb:cc:dd:ee:f2"); + private static final WifiP2pDevice TEST_GROUP_OWNER_OTHER = + new WifiP2pDevice("aa:bb:cc:dd:ee:f3"); + + private WifiP2pGroup mTestGroup1; + private WifiP2pGroup mTestGroup2; + private WifiP2pGroup mTestGroup3; + private WifiP2pGroup mTestGroup4; + + private WifiP2pGroup createGroup( + int networkId, String networkName, + String passphrase, boolean isGo, + WifiP2pDevice goDev) { + WifiP2pGroup group = new WifiP2pGroup(); + group.setNetworkId(networkId); + group.setNetworkName(networkName); + group.setPassphrase(passphrase); + group.setIsGroupOwner(isGo); + group.setOwner(goDev); + return group; + } + + @Before + public void setUp() throws Exception { + mTestGroup1 = createGroup(0, "testGroup1", "12345678", false, TEST_GROUP_OWNER_1); + mTestGroup2 = createGroup(1, "testGroup2", "12345678", true, TEST_GROUP_OWNER_2); + mTestGroup3 = createGroup(2, "testGroup3", "12345678", false, TEST_GROUP_OWNER_3); + mTestGroup4 = createGroup(3, "testGroup4", "12345678", false, TEST_GROUP_OWNER_1); + } + + /** + * Verify basic operations. + */ + @Test + public void testListOperations() throws Exception { + WifiP2pGroupList list = new WifiP2pGroupList(); + list.add(mTestGroup1); + list.add(mTestGroup2); + list.add(mTestGroup3); + list.add(mTestGroup4); + assertEquals(4, list.getGroupList().size()); + + // in list + assertEquals(mTestGroup2.getNetworkId(), + list.getNetworkId(TEST_GROUP_OWNER_2.deviceAddress)); + assertEquals(TEST_GROUP_OWNER_2.deviceAddress, + list.getOwnerAddr(mTestGroup2.getNetworkId())); + // not in list + assertEquals(-1, list.getNetworkId(TEST_GROUP_OWNER_OTHER.deviceAddress)); + // if there are groups with the same GO, return the first one found. + assertEquals(mTestGroup1.getNetworkId(), + list.getNetworkId(TEST_GROUP_OWNER_1.deviceAddress)); + // identify groups with the same GO, but different network names. + assertEquals(mTestGroup4.getNetworkId(), + list.getNetworkId(TEST_GROUP_OWNER_1.deviceAddress, "testGroup4")); + + list.remove(mTestGroup3.getNetworkId()); + assertEquals(-1, list.getNetworkId(TEST_GROUP_OWNER_3.deviceAddress)); + assertFalse(list.contains(mTestGroup3.getNetworkId())); + + assertEquals(3, list.getGroupList().size()); + + Parcel parcelW = Parcel.obtain(); + list.writeToParcel(parcelW, 0); + byte[] bytes = parcelW.marshall(); + parcelW.recycle(); + + Parcel parcelR = Parcel.obtain(); + parcelR.unmarshall(bytes, 0, bytes.length); + parcelR.setDataPosition(0); + WifiP2pGroupList fromParcel = WifiP2pGroupList.CREATOR.createFromParcel(parcelR); + + assertEquals(list.toString(), fromParcel.toString()); + + list.clear(); + assertEquals(0, list.getGroupList().size()); + + } +} -- cgit v1.2.3 From ed4fc9abf73bd141a8422af8eec14b1110d0389d Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Mon, 8 Apr 2019 17:41:04 +0800 Subject: p2p: unit tests for WifiP2pGroup Bug: 130138124 Test: atest FrameworksWifiApiTests Change-Id: I40818ac3ab02facecb0976cf4cd5ab0ca18d84d5 --- .../src/android/net/wifi/p2p/WifiP2pGroupTest.java | 92 ++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 wifi/tests/src/android/net/wifi/p2p/WifiP2pGroupTest.java (limited to 'wifi') diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pGroupTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pGroupTest.java new file mode 100644 index 000000000000..9473e42184e3 --- /dev/null +++ b/wifi/tests/src/android/net/wifi/p2p/WifiP2pGroupTest.java @@ -0,0 +1,92 @@ +/* + * 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.p2p; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import android.os.Parcel; + +import androidx.test.filters.SmallTest; + +import org.junit.Test; + +/** + * Unit test harness for {@link android.net.wifi.p2p.WifiP2pGroup} + */ +@SmallTest +public class WifiP2pGroupTest { + + private static final String INTERFACE = "p2p-p2p0-3"; + private static final int NETWORK_ID = 9; + private static final String NETWORK_NAME = "DIRECT-xy-Hello"; + private static final String PASSPHRASE = "HelloWorld"; + private static final WifiP2pDevice GROUP_OWNER = new WifiP2pDevice("de:ad:be:ef:00:01"); + private static final int FREQUENCY = 5300; + private static final WifiP2pDevice CLIENT_1 = new WifiP2pDevice("aa:bb:cc:dd:ee:01"); + private static final WifiP2pDevice CLIENT_2 = new WifiP2pDevice("aa:bb:cc:dd:ee:02"); + + /** + * Verify setter/getter functions. + */ + @Test + public void testSetterGetter() throws Exception { + WifiP2pGroup group = new WifiP2pGroup(); + + group.setInterface(INTERFACE); + group.setNetworkId(NETWORK_ID); + group.setNetworkName(NETWORK_NAME); + group.setPassphrase(PASSPHRASE); + group.setIsGroupOwner(false); + group.setOwner(GROUP_OWNER); + group.setFrequency(FREQUENCY); + group.addClient(CLIENT_1.deviceAddress); + group.addClient(CLIENT_2); + + assertEquals(INTERFACE, group.getInterface()); + assertEquals(NETWORK_ID, group.getNetworkId()); + assertEquals(NETWORK_NAME, group.getNetworkName()); + assertEquals(PASSPHRASE, group.getPassphrase()); + assertFalse(group.isGroupOwner()); + assertEquals(GROUP_OWNER, group.getOwner()); + assertEquals(FREQUENCY, group.getFrequency()); + + assertFalse(group.isClientListEmpty()); + assertTrue(group.contains(CLIENT_1)); + + assertEquals(2, group.getClientList().size()); + + group.removeClient(CLIENT_1); + group.removeClient(CLIENT_2.deviceAddress); + assertFalse(group.contains(CLIENT_1)); + assertTrue(group.isClientListEmpty()); + + Parcel parcelW = Parcel.obtain(); + group.writeToParcel(parcelW, 0); + byte[] bytes = parcelW.marshall(); + parcelW.recycle(); + + Parcel parcelR = Parcel.obtain(); + parcelR.unmarshall(bytes, 0, bytes.length); + parcelR.setDataPosition(0); + WifiP2pGroup fromParcel = WifiP2pGroup.CREATOR.createFromParcel(parcelR); + + assertEquals(group.toString(), fromParcel.toString()); + + } +} -- cgit v1.2.3 From d9c7a28786a0e6d52069fcfb3b55dec2be6fb60e Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Mon, 8 Apr 2019 16:37:19 +0800 Subject: p2p: unit tests for P2P UPNP service discovery Bug: 130138124 Test: atest FrameworksWifiApiTests Change-Id: Id3218378e6548ca013484f5f693db1863bf419e1 --- .../wifi/p2p/nsd/WifiP2pUpnpServiceInfoTest.java | 80 ++++++++++++++++++++++ .../p2p/nsd/WifiP2pUpnpServiceRequestTest.java | 49 +++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfoTest.java create mode 100644 wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceRequestTest.java (limited to 'wifi') diff --git a/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfoTest.java b/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfoTest.java new file mode 100644 index 000000000000..49ead11065ae --- /dev/null +++ b/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfoTest.java @@ -0,0 +1,80 @@ +/* + * 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.p2p.nsd; + +import static org.junit.Assert.fail; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +/** + * Unit test harness for {@link android.net.wifi.p2p.nsd.WifiP2pUpnpServiceInfo} + */ +@SmallTest +public class WifiP2pUpnpServiceInfoTest { + + private static final String UUID = "6859dede-8574-59ab-9332-123456789012"; + private static final String DEVICE = "aa:bb:cc:dd:ee:ff"; + + private List mServiceList = new ArrayList<>(); + + @Before + public void setUp() throws Exception { + mServiceList.add("urn:schemas-upnp-org:service:ContentDirectory:1"); + } + + /** + * Verify newInstance API + */ + @Test + public void testNewInstance() throws Exception { + WifiP2pUpnpServiceInfo info = null; + + // the least arguments + info = WifiP2pUpnpServiceInfo.newInstance( + UUID, DEVICE, null); + + // all arguments are given. + info = WifiP2pUpnpServiceInfo.newInstance( + UUID, DEVICE, mServiceList); + + // failure case due to no UUID. + try { + info = WifiP2pUpnpServiceInfo.newInstance( + null, DEVICE, null); + fail("should throw IllegalArgumentException"); + } catch (IllegalArgumentException ex) { + // expected exception. + } + + // failure case due to no device. + try { + info = WifiP2pUpnpServiceInfo.newInstance( + UUID, + null, + null); + fail("should throw IllegalArgumentException"); + } catch (IllegalArgumentException ex) { + // expected exception. + } + } +} diff --git a/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceRequestTest.java b/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceRequestTest.java new file mode 100644 index 000000000000..79930dc83372 --- /dev/null +++ b/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceRequestTest.java @@ -0,0 +1,49 @@ +/* + * 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.p2p.nsd; + +import static org.junit.Assert.fail; + +import androidx.test.filters.SmallTest; + +import org.junit.Test; + +/** + * Unit test harness for {@link android.net.wifi.p2p.nsd.WifiP2pUpnpServiceRequest} + */ +@SmallTest +public class WifiP2pUpnpServiceRequestTest { + + @Test + public void testNewInstance() throws Exception { + WifiP2pUpnpServiceRequest request = null; + + // Create a service discovery request to search all UPnP services. + request = WifiP2pUpnpServiceRequest.newInstance(); + + // Create a service discovery request to search specified UPnP services. + request = WifiP2pUpnpServiceRequest.newInstance("ssdp:all"); + + // failure case due to null target string + try { + request = WifiP2pUpnpServiceRequest.newInstance(null); + fail("should throw IllegalArgumentException"); + } catch (IllegalArgumentException ex) { + // expected exception. + } + } +} -- cgit v1.2.3 From b3eb4e3d632ee805d3b79ced41ed66a9e342a240 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Mon, 8 Apr 2019 16:27:12 +0800 Subject: p2p: unit tests for P2P DNS SD service discovery Bug: 130138124 Test: atest FrameworksWifiApiTests Change-Id: I454441ab024f1a72f2e5a92e08894993be749d3d --- .../wifi/p2p/nsd/WifiP2pDnsSdServiceInfoTest.java | 88 ++++++++++++++++++++++ .../p2p/nsd/WifiP2pDnsSdServiceRequestTest.java | 72 ++++++++++++++++++ 2 files changed, 160 insertions(+) create mode 100644 wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfoTest.java create mode 100644 wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceRequestTest.java (limited to 'wifi') diff --git a/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfoTest.java b/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfoTest.java new file mode 100644 index 000000000000..e1cffee361e8 --- /dev/null +++ b/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfoTest.java @@ -0,0 +1,88 @@ +/* + * 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.p2p.nsd; + +import static org.junit.Assert.fail; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +/** + * Unit test harness for {@link android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceInfo} + */ +@SmallTest +public class WifiP2pDnsSdServiceInfoTest { + + private static final String INSTANCE_NAME = "MyPrinter"; + private static final String SERVICE_TYPE = "_ipp._tcp"; + private static final String TXTRECORD_PROP_AVAILABLE = "available"; + private static final String TXTRECORD_PROP_AVAILABLE_VISABLE = "visable"; + + private Map mTxtMap = new HashMap<>(); + + @Before + public void setUp() throws Exception { + mTxtMap.put(TXTRECORD_PROP_AVAILABLE, TXTRECORD_PROP_AVAILABLE_VISABLE); + } + + /** + * Verify newInstance API + */ + @Test + public void testNewInstance() throws Exception { + WifiP2pDnsSdServiceInfo info = null; + + // the least arguments + info = WifiP2pDnsSdServiceInfo.newInstance( + INSTANCE_NAME, + SERVICE_TYPE, + null); + + // all arguments are given. + info = WifiP2pDnsSdServiceInfo.newInstance( + INSTANCE_NAME, + SERVICE_TYPE, + mTxtMap); + + // failure case due to no instance name. + try { + info = WifiP2pDnsSdServiceInfo.newInstance( + null, + SERVICE_TYPE, + null); + fail("should throw IllegalArgumentException"); + } catch (IllegalArgumentException ex) { + // expected exception. + } + + // failure case due to no service type. + try { + info = WifiP2pDnsSdServiceInfo.newInstance( + INSTANCE_NAME, + null, + null); + fail("should throw IllegalArgumentException"); + } catch (IllegalArgumentException ex) { + // expected exception. + } + } +} diff --git a/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceRequestTest.java b/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceRequestTest.java new file mode 100644 index 000000000000..7d46a5f3a79d --- /dev/null +++ b/wifi/tests/src/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceRequestTest.java @@ -0,0 +1,72 @@ +/* + * 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.p2p.nsd; + +import static org.junit.Assert.fail; + +import androidx.test.filters.SmallTest; + +import org.junit.Test; + +/** + * Unit test harness for {@link android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceRequest} + */ +@SmallTest +public class WifiP2pDnsSdServiceRequestTest { + + private static final String SERVICE_NAME = "MyPrinter"; + private static final String SERVICE_TYPE = "_ipp._tcp"; + + @Test + public void testNewInstance() throws Exception { + WifiP2pDnsSdServiceRequest request = null; + + // default new instance + request = WifiP2pDnsSdServiceRequest.newInstance(); + + // set service type + request = WifiP2pDnsSdServiceRequest.newInstance(SERVICE_TYPE); + + // set service type + request = WifiP2pDnsSdServiceRequest.newInstance(SERVICE_NAME, SERVICE_TYPE); + + // failure case due to null service type + try { + request = WifiP2pDnsSdServiceRequest.newInstance(null); + fail("should throw IllegalArgumentException"); + } catch (IllegalArgumentException ex) { + // expected exception. + } + + // failure case due to null service name + try { + request = WifiP2pDnsSdServiceRequest.newInstance(SERVICE_NAME, null); + fail("should throw IllegalArgumentException"); + } catch (IllegalArgumentException ex) { + // expected exception. + } + + // failure case due to null service type + try { + request = WifiP2pDnsSdServiceRequest.newInstance(null, SERVICE_TYPE); + fail("should throw IllegalArgumentException"); + } catch (IllegalArgumentException ex) { + // expected exception. + } + + } +} -- cgit v1.2.3 From e518f2ed77099d758cb0b4c261579cb5e39fd407 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Mon, 8 Apr 2019 16:55:27 +0800 Subject: p2p: unit tests for WifiP2pConfig Bug: 130138124 Test: atest FrameworksWifiApiTests Change-Id: I5cb6c9e0c0125d87672401e0dbd227b646a3a9d4 --- .../android/net/wifi/p2p/WifiP2pConfigTest.java | 44 ++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'wifi') diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pConfigTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pConfigTest.java index 01a4c53d618b..41f109a63759 100644 --- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pConfigTest.java +++ b/wifi/tests/src/android/net/wifi/p2p/WifiP2pConfigTest.java @@ -16,8 +16,11 @@ package android.net.wifi.p2p; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; +import android.os.Parcel; + import androidx.test.filters.SmallTest; import org.junit.Test; @@ -27,6 +30,8 @@ import org.junit.Test; */ @SmallTest public class WifiP2pConfigTest { + + private static final String DEVICE_ADDRESS = "aa:bb:cc:dd:ee:ff"; /** * Check network name setter */ @@ -113,4 +118,43 @@ public class WifiP2pConfigTest { // expected exception. } } + + @Test + /* + * Verify WifiP2pConfig basic operations + */ + public void testWifiP2pConfig() throws Exception { + WifiP2pConfig config = new WifiP2pConfig(); + config.deviceAddress = DEVICE_ADDRESS; + + WifiP2pConfig copiedConfig = new WifiP2pConfig(config); + // no equals operator, use toString for comparison. + assertEquals(config.toString(), copiedConfig.toString()); + + Parcel parcelW = Parcel.obtain(); + config.writeToParcel(parcelW, 0); + byte[] bytes = parcelW.marshall(); + parcelW.recycle(); + + Parcel parcelR = Parcel.obtain(); + parcelR.unmarshall(bytes, 0, bytes.length); + parcelR.setDataPosition(0); + WifiP2pConfig configFromParcel = WifiP2pConfig.CREATOR.createFromParcel(parcelR); + + // no equals operator, use toString for comparison. + assertEquals(config.toString(), configFromParcel.toString()); + + } + + @Test + /* + * Verify WifiP2pConfig invalidate API + */ + public void testInvalidate() throws Exception { + WifiP2pConfig config = new WifiP2pConfig(); + config.deviceAddress = DEVICE_ADDRESS; + config.invalidate(); + assertEquals("", config.deviceAddress); + } + } -- cgit v1.2.3 From 7619525014ce839e15a9e4d77ae49912c6f0abbe Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Mon, 8 Apr 2019 17:40:37 +0800 Subject: p2p: unit tests for WifiP2pDeviceList Bug: 130138124 Test: atest FrameworksWifiApiTests Change-Id: I53d05702a50509117720a10f50df93e496ff9d65 --- .../net/wifi/p2p/WifiP2pDeviceListTest.java | 75 ++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceListTest.java (limited to 'wifi') diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceListTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceListTest.java new file mode 100644 index 000000000000..22936bd352fe --- /dev/null +++ b/wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceListTest.java @@ -0,0 +1,75 @@ +/* + * 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.p2p; + +import static org.junit.Assert.assertEquals; + +import android.os.Parcel; + +import androidx.test.filters.SmallTest; + +import org.junit.Test; + +/** + * Unit test harness for {@link android.net.wifi.p2p.WifiP2pDeviceList} + */ +@SmallTest +public class WifiP2pDeviceListTest { + + private static final WifiP2pDevice TEST_DEVICE_1 = new WifiP2pDevice("aa:bb:cc:dd:ee:ff"); + private static final WifiP2pDevice TEST_DEVICE_2 = new WifiP2pDevice("aa:bb:cc:dd:ee:f1"); + private static final WifiP2pDevice TEST_DEVICE_3 = new WifiP2pDevice("11:22:33:44:55:66"); + private static final WifiP2pDevice TEST_DEVICE_4 = new WifiP2pDevice("a0:b0:c0:d0:e0:f0"); + + /** + * Verify basic operations. + */ + @Test + public void testListOperations() throws Exception { + WifiP2pDeviceList list = new WifiP2pDeviceList(); + list.update(TEST_DEVICE_1); + list.update(TEST_DEVICE_2); + list.update(TEST_DEVICE_3); + assertEquals(3, list.getDeviceList().size()); + + assertEquals(TEST_DEVICE_1, list.get(TEST_DEVICE_1.deviceAddress)); + assertEquals(null, list.get(TEST_DEVICE_4.deviceAddress)); + + list.remove(TEST_DEVICE_2.deviceAddress); + assertEquals(null, list.get(TEST_DEVICE_2.deviceAddress)); + + list.remove(TEST_DEVICE_3); + assertEquals(null, list.get(TEST_DEVICE_3.deviceAddress)); + + assertEquals(1, list.getDeviceList().size()); + + list.clear(); + assertEquals(0, list.getDeviceList().size()); + + Parcel parcelW = Parcel.obtain(); + list.writeToParcel(parcelW, 0); + byte[] bytes = parcelW.marshall(); + parcelW.recycle(); + + Parcel parcelR = Parcel.obtain(); + parcelR.unmarshall(bytes, 0, bytes.length); + parcelR.setDataPosition(0); + WifiP2pDeviceList fromParcel = WifiP2pDeviceList.CREATOR.createFromParcel(parcelR); + + assertEquals(list.toString(), fromParcel.toString()); + } +} -- cgit v1.2.3 From 7e6b62ea2d8702b58e404684b72dfb069ace26d2 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Wed, 10 Apr 2019 17:33:20 +0800 Subject: p2p: unit tests for WifiP2pProvDiscEvent Bug: 130138124 Test: atest FrameworksWifiApiTests Change-Id: I3eb9f7bcd19e1ec074174cdb2a6822fb983976ba --- .../net/wifi/p2p/WifiP2pProvDiscEventTest.java | 111 +++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 wifi/tests/src/android/net/wifi/p2p/WifiP2pProvDiscEventTest.java (limited to 'wifi') diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pProvDiscEventTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pProvDiscEventTest.java new file mode 100644 index 000000000000..e3b10a7a52f0 --- /dev/null +++ b/wifi/tests/src/android/net/wifi/p2p/WifiP2pProvDiscEventTest.java @@ -0,0 +1,111 @@ +/* + * 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.p2p; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import androidx.test.filters.SmallTest; + +import org.junit.Test; + +/** + * Unit test harness for {@link android.net.wifi.p2p.WifiP2pProvDiscEvent} + */ +@SmallTest +public class WifiP2pProvDiscEventTest { + + private static final String DEVICE_ADDRESS = "aa:bb:cc:dd:ee:ff"; + private static final String EVENT_PBC_REQ_STRING = "P2P-PROV-DISC-PBC-REQ"; + private static final String EVENT_PBC_RSP_STRING = "P2P-PROV-DISC-PBC-RESP"; + private static final String EVENT_ENTER_PIN_STRING = "P2P-PROV-DISC-ENTER-PIN"; + private static final String EVENT_SHOW_PIN_STRING = "P2P-PROV-DISC-SHOW-PIN"; + private static final String TEST_PIN = "44490607"; + + /** + * Test parsing PBC request event. + */ + @Test + public void testPbcReqEvent() throws Exception { + WifiP2pProvDiscEvent event = + new WifiP2pProvDiscEvent(EVENT_PBC_REQ_STRING + " " + DEVICE_ADDRESS); + assertEquals(WifiP2pProvDiscEvent.PBC_REQ, event.event); + assertEquals(DEVICE_ADDRESS, event.device.deviceAddress); + } + + + /** + * Test parsing PBC response event. + */ + @Test + public void testPbcRespEvent() throws Exception { + WifiP2pProvDiscEvent event = + new WifiP2pProvDiscEvent(EVENT_PBC_RSP_STRING + " " + DEVICE_ADDRESS); + assertEquals(WifiP2pProvDiscEvent.PBC_RSP, event.event); + assertEquals(DEVICE_ADDRESS, event.device.deviceAddress); + } + + /** + * Test parsing ENTER-PIN event. + */ + @Test + public void testEnterPinEvent() throws Exception { + WifiP2pProvDiscEvent event = + new WifiP2pProvDiscEvent(EVENT_ENTER_PIN_STRING + " " + DEVICE_ADDRESS); + assertEquals(WifiP2pProvDiscEvent.ENTER_PIN, event.event); + assertEquals(DEVICE_ADDRESS, event.device.deviceAddress); + } + + /** + * Test parsing SHOW-PIN event. + */ + @Test + public void testShowPinEvent() throws Exception { + WifiP2pProvDiscEvent event = + new WifiP2pProvDiscEvent( + EVENT_SHOW_PIN_STRING + " " + DEVICE_ADDRESS + " " + TEST_PIN); + assertEquals(WifiP2pProvDiscEvent.SHOW_PIN, event.event); + assertEquals(DEVICE_ADDRESS, event.device.deviceAddress); + assertEquals(TEST_PIN, event.pin); + } + + /** + * Test parsing malformed input. + */ + @Test + public void testMalformedInput() throws Exception { + try { + WifiP2pProvDiscEvent event = new WifiP2pProvDiscEvent("OneToken"); + fail("Should throw IllegalArgumentException exception."); + } catch (IllegalArgumentException ex) { + // expected exception. + } + } + + /** + * Test parsing malformed event. + */ + @Test + public void testMalformedEvent() throws Exception { + try { + WifiP2pProvDiscEvent event = new WifiP2pProvDiscEvent("XXX " + DEVICE_ADDRESS); + fail("Should throw IllegalArgumentException exception."); + } catch (IllegalArgumentException ex) { + // expected exception. + } + } +} -- cgit v1.2.3 From c16ba42bddfbe3e3599088227e466d77436c7782 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Wed, 10 Apr 2019 17:50:10 +0800 Subject: p2p: unit tests for WifiP2pInfo Bug: 130138124 Test: atest FrameworksWifiApiTest Change-Id: I7a6bec4faf81ec6e9164b8737588a51503caaaf7 --- .../src/android/net/wifi/p2p/WifiP2pInfoTest.java | 83 ++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 wifi/tests/src/android/net/wifi/p2p/WifiP2pInfoTest.java (limited to 'wifi') diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pInfoTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pInfoTest.java new file mode 100644 index 000000000000..e207ca1f3e7a --- /dev/null +++ b/wifi/tests/src/android/net/wifi/p2p/WifiP2pInfoTest.java @@ -0,0 +1,83 @@ +/* + * 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.p2p; + +import static org.junit.Assert.assertEquals; + +import android.os.Parcel; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Test; + +import java.net.InetAddress; + +/** + * Unit test harness for {@link android.net.wifi.p2p.WifiP2pInfo} + */ +@SmallTest +public class WifiP2pInfoTest { + + private InetAddress mGroupOnwerIpv4Address; + + @Before + public void setUp() throws Exception { + byte[] ipv4 = {(byte) 192, (byte) 168, (byte) 49, (byte) 1}; + mGroupOnwerIpv4Address = InetAddress.getByAddress(ipv4); + } + + /** + * Verifies copy constructor. + */ + @Test + public void testCopyOperator() throws Exception { + WifiP2pInfo info = new WifiP2pInfo(); + info.groupFormed = true; + info.isGroupOwner = true; + info.groupOwnerAddress = mGroupOnwerIpv4Address; + + WifiP2pInfo copiedInfo = new WifiP2pInfo(info); + + // no equals operator, use toString for data comparison. + assertEquals(info.toString(), copiedInfo.toString()); + } + + /** + * Verifies parcel serialization/deserialization. + */ + @Test + public void testParcelOperation() throws Exception { + WifiP2pInfo info = new WifiP2pInfo(); + info.groupFormed = true; + info.isGroupOwner = true; + info.groupOwnerAddress = mGroupOnwerIpv4Address; + + Parcel parcelW = Parcel.obtain(); + info.writeToParcel(parcelW, 0); + byte[] bytes = parcelW.marshall(); + parcelW.recycle(); + + Parcel parcelR = Parcel.obtain(); + parcelR.unmarshall(bytes, 0, bytes.length); + parcelR.setDataPosition(0); + WifiP2pInfo fromParcel = WifiP2pInfo.CREATOR.createFromParcel(parcelR); + + // no equals operator, use toString for data comparison. + assertEquals(info.toString(), fromParcel.toString()); + } +} -- cgit v1.2.3 From 573b2b0c96597ce988bb91f80a575f24bf577f39 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Wed, 10 Apr 2019 18:37:58 +0800 Subject: p2p: unit tests for WifiP2pWfdInfo Bug: 130138124 Test: atest FrameworksWifiApiTest Change-Id: I7368f9b4f3e67985f404f701e92dfe82286935be --- .../android/net/wifi/p2p/WifiP2pWfdInfoTest.java | 110 +++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java (limited to 'wifi') diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java new file mode 100644 index 000000000000..d2f11688e4e5 --- /dev/null +++ b/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java @@ -0,0 +1,110 @@ +/* + * 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.p2p; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import android.os.Parcel; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Test; + +/** + * Unit test harness for {@link android.net.wifi.p2p.WifiP2pWfdInfo} + */ +@SmallTest +public class WifiP2pWfdInfoTest { + + private static final int TEST_CTRL_PORT = 9999; + private static final int TEST_MAX_TPUT = 1024; + + private WifiP2pWfdInfo mSourceInfo = new WifiP2pWfdInfo( + 0, + TEST_CTRL_PORT, + TEST_MAX_TPUT); + + @Before + public void setUp() { + // initialize device info flags. + mSourceInfo.setDeviceType(WifiP2pWfdInfo.WFD_SOURCE); + mSourceInfo.setSessionAvailable(true); + } + + /** + * Verifies setters/getters. + */ + @Test + public void testSettersGetters() throws Exception { + WifiP2pWfdInfo info = new WifiP2pWfdInfo(); + + info.setWfdEnabled(true); + assertTrue(info.isWfdEnabled()); + + info.setDeviceType(WifiP2pWfdInfo.WFD_SOURCE); + assertEquals(WifiP2pWfdInfo.WFD_SOURCE, info.getDeviceType()); + + info.setCoupledSinkSupportAtSource(true); + assertTrue(info.isCoupledSinkSupportedAtSource()); + + info.setCoupledSinkSupportAtSink(true); + assertTrue(info.isCoupledSinkSupportedAtSink()); + + info.setSessionAvailable(true); + assertTrue(info.isSessionAvailable()); + + info.setControlPort(TEST_CTRL_PORT); + assertEquals(TEST_CTRL_PORT, info.getControlPort()); + + info.setMaxThroughput(TEST_MAX_TPUT); + assertEquals(TEST_MAX_TPUT, info.getMaxThroughput()); + + assertEquals("0018270f0400", info.getDeviceInfoHex()); + } + + /** + * Verifies copy constructor. + */ + @Test + public void testCopyOperator() throws Exception { + WifiP2pWfdInfo copiedInfo = new WifiP2pWfdInfo(mSourceInfo); + + // no equals operator, use toString for data comparison. + assertEquals(mSourceInfo.toString(), copiedInfo.toString()); + } + + /** + * Verifies parcel serialization/deserialization. + */ + @Test + public void testParcelOperation() throws Exception { + Parcel parcelW = Parcel.obtain(); + mSourceInfo.writeToParcel(parcelW, 0); + byte[] bytes = parcelW.marshall(); + parcelW.recycle(); + + Parcel parcelR = Parcel.obtain(); + parcelR.unmarshall(bytes, 0, bytes.length); + parcelR.setDataPosition(0); + WifiP2pWfdInfo fromParcel = WifiP2pWfdInfo.CREATOR.createFromParcel(parcelR); + + // no equals operator, use toString for data comparison. + assertEquals(mSourceInfo.toString(), fromParcel.toString()); + } +} -- cgit v1.2.3 From ce5f7f8720959f51abbaa1d7a61a7ed16fb2fbb1 Mon Sep 17 00:00:00 2001 From: Ecco Park Date: Fri, 5 Apr 2019 16:44:10 -0700 Subject: Passpoint: add NETWORK_CARRIER_PROVISIONING for removePasspointConfigurations There is a requirement that carrier provisioning app has to add/remove passspoint profiles whenever sim is inserted/delete. In order to do this, the permission needs to be added for the carrier provisioining app to remove the profile. Bug: 130053265 Test: ./frameworks/base/wifi/tests/runtests.sh Change-Id: I883550d92a4d716fe5a59ab9141dd70b4cc4da94 Signed-off-by: Ecco Park --- wifi/java/android/net/wifi/WifiManager.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 4115663b8bb8..1a16aaa1036b 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1752,7 +1752,10 @@ public class WifiManager { * @deprecated This is no longer supported. */ @Deprecated - @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_SETTINGS, + android.Manifest.permission.NETWORK_CARRIER_PROVISIONING + }) public void removePasspointConfiguration(String fqdn) { try { if (!mService.removePasspointConfiguration(fqdn, mContext.getOpPackageName())) { -- cgit v1.2.3 From 152978d0ceed6c2df1e9c112eab64f71e78d202e Mon Sep 17 00:00:00 2001 From: David Su Date: Tue, 9 Jul 2019 16:56:07 -0700 Subject: Wifi: remove dead code Remove unused Parcelables from frameworks/base Bug: 134712974 Test: compiles Change-Id: I3e5bb51780750d22a0e49922c32fae21addc53cc --- wifi/java/android/net/wifi/IWifiManager.aidl | 1 - .../wifi/PasspointManagementObjectDefinition.aidl | 19 ----- .../wifi/PasspointManagementObjectDefinition.java | 81 ------------------- wifi/java/android/net/wifi/WpsResult.aidl | 19 ----- wifi/java/android/net/wifi/WpsResult.java | 90 ---------------------- .../java/android/net/wifi/hotspot2/pps/Policy.aidl | 19 ----- .../net/wifi/hotspot2/pps/UpdateParameter.aidl | 19 ----- .../android/net/wifi/p2p/WifiP2pGroupList.aidl | 19 ----- .../net/wifi/p2p/nsd/WifiP2pServiceResponse.aidl | 19 ----- 9 files changed, 286 deletions(-) delete mode 100644 wifi/java/android/net/wifi/PasspointManagementObjectDefinition.aidl delete mode 100644 wifi/java/android/net/wifi/PasspointManagementObjectDefinition.java delete mode 100644 wifi/java/android/net/wifi/WpsResult.aidl delete mode 100644 wifi/java/android/net/wifi/WpsResult.java delete mode 100644 wifi/java/android/net/wifi/hotspot2/pps/Policy.aidl delete mode 100644 wifi/java/android/net/wifi/hotspot2/pps/UpdateParameter.aidl delete mode 100644 wifi/java/android/net/wifi/p2p/WifiP2pGroupList.aidl delete mode 100644 wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceResponse.aidl (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 9010f3c9943e..1829baac4c58 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -29,7 +29,6 @@ import android.net.wifi.INetworkRequestMatchCallback; import android.net.wifi.ISoftApCallback; import android.net.wifi.ITrafficStateCallback; import android.net.wifi.IOnWifiUsabilityStatsListener; -import android.net.wifi.PasspointManagementObjectDefinition; import android.net.wifi.ScanResult; import android.net.wifi.WifiActivityEnergyInfo; import android.net.wifi.WifiConfiguration; diff --git a/wifi/java/android/net/wifi/PasspointManagementObjectDefinition.aidl b/wifi/java/android/net/wifi/PasspointManagementObjectDefinition.aidl deleted file mode 100644 index eb7cc39d5e33..000000000000 --- a/wifi/java/android/net/wifi/PasspointManagementObjectDefinition.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2008, 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; - -parcelable PasspointManagementObjectDefinition; diff --git a/wifi/java/android/net/wifi/PasspointManagementObjectDefinition.java b/wifi/java/android/net/wifi/PasspointManagementObjectDefinition.java deleted file mode 100644 index 70577b9695e5..000000000000 --- a/wifi/java/android/net/wifi/PasspointManagementObjectDefinition.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2016 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; - -/** - * This object describes a partial tree structure in the Hotspot 2.0 release 2 management object. - * The object is used during subscription remediation to modify parts of an existing PPS MO - * tree (Hotspot 2.0 specification section 9.1). - * @hide - */ -public class PasspointManagementObjectDefinition implements Parcelable { - private final String mBaseUri; - private final String mUrn; - private final String mMoTree; - - public PasspointManagementObjectDefinition(String baseUri, String urn, String moTree) { - mBaseUri = baseUri; - mUrn = urn; - mMoTree = moTree; - } - - public String getBaseUri() { - return mBaseUri; - } - - public String getUrn() { - return mUrn; - } - - public String getMoTree() { - return mMoTree; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(mBaseUri); - dest.writeString(mUrn); - dest.writeString(mMoTree); - } - - /** - * Implement the Parcelable interface {@hide} - */ - public static final @android.annotation.NonNull Creator CREATOR = - new Creator() { - public PasspointManagementObjectDefinition createFromParcel(Parcel in) { - return new PasspointManagementObjectDefinition( - in.readString(), /* base URI */ - in.readString(), /* URN */ - in.readString() /* Tree XML */ - ); - } - - public PasspointManagementObjectDefinition[] newArray(int size) { - return new PasspointManagementObjectDefinition[size]; - } - }; -} - diff --git a/wifi/java/android/net/wifi/WpsResult.aidl b/wifi/java/android/net/wifi/WpsResult.aidl deleted file mode 100644 index eb4c4f5539ba..000000000000 --- a/wifi/java/android/net/wifi/WpsResult.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2010, 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; - -parcelable WpsResult; diff --git a/wifi/java/android/net/wifi/WpsResult.java b/wifi/java/android/net/wifi/WpsResult.java deleted file mode 100644 index f2ffb6f52520..000000000000 --- a/wifi/java/android/net/wifi/WpsResult.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2010 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; - -/** - * A class representing the result of a WPS request - * @hide - */ -public class WpsResult implements Parcelable { - - public enum Status { - SUCCESS, - FAILURE, - IN_PROGRESS, - } - - public Status status; - - public String pin; - - public WpsResult() { - status = Status.FAILURE; - pin = null; - } - - public WpsResult(Status s) { - status = s; - pin = null; - } - - public String toString() { - StringBuffer sbuf = new StringBuffer(); - sbuf.append(" status: ").append(status.toString()); - sbuf.append('\n'); - sbuf.append(" pin: ").append(pin); - sbuf.append("\n"); - return sbuf.toString(); - } - - /** Implement the Parcelable interface {@hide} */ - public int describeContents() { - return 0; - } - - /** copy constructor {@hide} */ - public WpsResult(WpsResult source) { - if (source != null) { - status = source.status; - pin = source.pin; - } - } - - /** Implement the Parcelable interface {@hide} */ - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(status.name()); - dest.writeString(pin); - } - - /** Implement the Parcelable interface {@hide} */ - public static final @android.annotation.NonNull Creator CREATOR = - new Creator() { - public WpsResult createFromParcel(Parcel in) { - WpsResult result = new WpsResult(); - result.status = Status.valueOf(in.readString()); - result.pin = in.readString(); - return result; - } - - public WpsResult[] newArray(int size) { - return new WpsResult[size]; - } - }; -} diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Policy.aidl b/wifi/java/android/net/wifi/hotspot2/pps/Policy.aidl deleted file mode 100644 index e923f1f0fee8..000000000000 --- a/wifi/java/android/net/wifi/hotspot2/pps/Policy.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2017, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.wifi.hotspot2.pps; - -parcelable Policy; diff --git a/wifi/java/android/net/wifi/hotspot2/pps/UpdateParameter.aidl b/wifi/java/android/net/wifi/hotspot2/pps/UpdateParameter.aidl deleted file mode 100644 index 701db479076a..000000000000 --- a/wifi/java/android/net/wifi/hotspot2/pps/UpdateParameter.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2017, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.wifi.hotspot2.pps; - -parcelable UpdateParameter; diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.aidl b/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.aidl deleted file mode 100644 index 3d8a47682f6e..000000000000 --- a/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.aidl +++ /dev/null @@ -1,19 +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.p2p; - -parcelable WifiP2pGroupList; \ No newline at end of file diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceResponse.aidl b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceResponse.aidl deleted file mode 100644 index c81d1f98422d..000000000000 --- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceResponse.aidl +++ /dev/null @@ -1,19 +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.p2p.servicediscovery; - -parcelable WifiP2pServiceResponse; -- cgit v1.2.3 From 3cc44fa7baa7297a66bd4af64585d81aa20035a6 Mon Sep 17 00:00:00 2001 From: Nate Jiang Date: Mon, 15 Jul 2019 16:47:54 -0700 Subject: [NetworkSuggestion] add network suggestion disconnect API Change the doc. remove suggestion may cause disconnect. Test: None Bug: 137582811 Change-Id: I89a9ba090a4b984f8411594e212a1fa013e77dc8 --- wifi/java/android/net/wifi/WifiManager.java | 2 ++ 1 file changed, 2 insertions(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 1a16aaa1036b..89ed0800e31c 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1691,6 +1691,8 @@ public class WifiManager { /** * Remove some or all of the network suggestions that were previously provided by the app. + * If the current network is a suggestion being removed and if it was only provided by this app + * and is not a saved network then the framework will immediately disconnect. * See {@link WifiNetworkSuggestion} for a detailed explanation of the parameters. * See {@link WifiNetworkSuggestion#equals(Object)} for the equivalence evaluation used. * -- cgit v1.2.3 From f6b731a861a52995413d3b087f17f05820e0481e Mon Sep 17 00:00:00 2001 From: Nate Jiang Date: Thu, 25 Jul 2019 11:43:26 -0700 Subject: [WifiManger] add API to get suggestion Develop a new API for Apps to get the network suggestion suggestedby its own. Bug: 138447131 Test: atest android.net.wifi Test: atest com.android.server.wifi Change-Id: Ib8b9c23fe0c7b5e913475bb368fb3d7d4f443e2d --- wifi/java/android/net/wifi/IWifiManager.aidl | 2 ++ wifi/java/android/net/wifi/WifiManager.java | 15 +++++++++++++++ wifi/java/com/android/server/wifi/BaseWifiService.java | 5 +++++ wifi/tests/src/android/net/wifi/WifiManagerTest.java | 13 ++++++++++--- 4 files changed, 32 insertions(+), 3 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 1829baac4c58..931e5dd7405f 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -205,6 +205,8 @@ interface IWifiManager int removeNetworkSuggestions(in List networkSuggestions, in String packageName); + List getNetworkSuggestions(in String packageName); + String[] getFactoryMacAddresses(); void setDeviceMobilityState(int state); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 89ed0800e31c..cdbdd266e39c 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1713,6 +1713,21 @@ public class WifiManager { } } + /** + * Get all network suggestions provided by the calling app. + * See {@link #addNetworkSuggestions(List)} + * See {@link #removeNetworkSuggestions(List)} + * @return a list of {@link WifiNetworkSuggestion} + */ + @RequiresPermission(ACCESS_WIFI_STATE) + public @NonNull List getNetworkSuggestions() { + try { + return mService.getNetworkSuggestions(mContext.getOpPackageName()); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + } + /** * Returns the max number of network suggestions that are allowed per app on the device. * @see #addNetworkSuggestions(List) diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index fcf8bd5eaa3e..bc06e7de8502 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -439,6 +439,11 @@ public class BaseWifiService extends IWifiManager.Stub { throw new UnsupportedOperationException(); } + @Override + public List getNetworkSuggestions(String packageName) { + throw new UnsupportedOperationException(); + } + @Override public String[] getFactoryMacAddresses() { throw new UnsupportedOperationException(); diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index b75a1acf87c9..e478f3830c0a 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -1313,20 +1313,27 @@ i * Verify that a call to cancel WPS immediately returns a failure. } /** - * Verify calls to {@link WifiManager#addNetworkSuggestions(List)} and + * Verify calls to {@link WifiManager#addNetworkSuggestions(List)}, + * {@link WifiManager#getNetworkSuggestions()} and * {@link WifiManager#removeNetworkSuggestions(List)}. */ @Test - public void addRemoveNetworkSuggestions() throws Exception { + public void addGetRemoveNetworkSuggestions() throws Exception { + List testList = new ArrayList<>(); when(mWifiService.addNetworkSuggestions(any(List.class), anyString())) .thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS); when(mWifiService.removeNetworkSuggestions(any(List.class), anyString())) .thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS); + when(mWifiService.getNetworkSuggestions(anyString())) + .thenReturn(testList); assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS, - mWifiManager.addNetworkSuggestions(new ArrayList<>())); + mWifiManager.addNetworkSuggestions(testList)); verify(mWifiService).addNetworkSuggestions(anyList(), eq(TEST_PACKAGE_NAME)); + assertEquals(testList, mWifiManager.getNetworkSuggestions()); + verify(mWifiService).getNetworkSuggestions(eq(TEST_PACKAGE_NAME)); + assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS, mWifiManager.removeNetworkSuggestions(new ArrayList<>())); verify(mWifiService).removeNetworkSuggestions(anyList(), eq(TEST_PACKAGE_NAME)); -- cgit v1.2.3 From 855a10697316642169283c91dfa5ce61a1b996fe Mon Sep 17 00:00:00 2001 From: xshu Date: Fri, 2 Aug 2019 15:47:51 -0700 Subject: Fix runtest.sh in frameworks/base/wifi The "make" command seems no longer supported after syncing today to TOT: build/core/main.mk:13: Calling make directly is no longer supported. build/core/main.mk:14: Either use 'envsetup.sh; m' or 'build/soong/soong_ui.bash --make-mode' Made the fix as suggested above. Bug: 138863873 Test: unit tests Change-Id: I2e24da0195327b750a7438427ef5033bcd6f5373 --- wifi/tests/runtests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/tests/runtests.sh b/wifi/tests/runtests.sh index 219a45ee188f..7a0dfb08fcfe 100755 --- a/wifi/tests/runtests.sh +++ b/wifi/tests/runtests.sh @@ -12,7 +12,7 @@ set -e # fail early echo "+ mmma -j32 $ANDROID_BUILD_TOP/frameworks/base/wifi/tests" # NOTE Don't actually run the command above since this shell doesn't inherit functions from the # caller. -make -j32 -C $ANDROID_BUILD_TOP -f build/core/main.mk MODULES-IN-frameworks-base-wifi-tests +$ANDROID_BUILD_TOP/build/soong/soong_ui.bash --make-mode MODULES-IN-frameworks-base-wifi-tests set -x # print commands -- cgit v1.2.3 From 2161b39d386a38214181907f0cbfd36dafdfb933 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Fri, 12 Jul 2019 11:06:16 -0700 Subject: WifiManager: Retrieve IWifiManager service lazily Wifi services will be initialized a little later in the bootup sequence because it is now a separate APK. So, retrieve wifi services lazily (on the first method call on the object). This will alleviate the need to modify all the clients which instantiate WifiManager very early in the bootup sequence (Sysui, some vendor apps, etc). Bug: 137374831 Test: Device boots up & connects to wifi networks. Change-Id: I8e1f0eb3a5a8fdb79b088447fbb9f97413f64483 Merged-In: I8e1f0eb3a5a8fdb79b088447fbb9f97413f64483 --- wifi/java/android/net/wifi/WifiManager.java | 214 ++++++++++++++++------------ 1 file changed, 121 insertions(+), 93 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 20d772c8fb11..ca65736d8ec2 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -50,6 +50,7 @@ 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.util.Log; import android.util.Pair; @@ -1149,18 +1150,40 @@ public class WifiManager { * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve * the standard {@link android.content.Context#WIFI_SERVICE Context.WIFI_SERVICE}. * @param context the application context - * @param service the Binder interface * @hide - hide this because it takes in a parameter of type IWifiManager, which * is a system private class. */ - public WifiManager(Context context, IWifiManager service, Looper looper) { + public WifiManager(Context context, Looper looper) { mContext = context; - mService = service; mLooper = looper; mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion; + } + + /** + * This is used only for unit testing. + * @hide + */ + @VisibleForTesting + public WifiManager(Context context, IWifiManager service, Looper looper) { + this(context, looper); + mService = service; updateVerboseLoggingEnabledFromService(); } + private IWifiManager getIWifiManager() throws RemoteException { + if (mService == null) { + synchronized (this) { + mService = IWifiManager.Stub.asInterface( + ServiceManager.getService(Context.WIFI_SERVICE)); + if (mService == null) { + throw new RemoteException("Wifi Service not running"); + } + updateVerboseLoggingEnabledFromService(); + } + } + return mService; + } + /** * Return a list of all the networks configured for the current foreground * user. @@ -1201,7 +1224,7 @@ public class WifiManager { public List getConfiguredNetworks() { try { ParceledListSlice parceledList = - mService.getConfiguredNetworks(mContext.getOpPackageName()); + getIWifiManager().getConfiguredNetworks(mContext.getOpPackageName()); if (parceledList == null) { return Collections.emptyList(); } @@ -1217,7 +1240,7 @@ public class WifiManager { public List getPrivilegedConfiguredNetworks() { try { ParceledListSlice parceledList = - mService.getPrivilegedConfiguredNetworks(mContext.getOpPackageName()); + getIWifiManager().getPrivilegedConfiguredNetworks(mContext.getOpPackageName()); if (parceledList == null) { return Collections.emptyList(); } @@ -1249,13 +1272,13 @@ public class WifiManager { List>>> configs = new ArrayList<>(); try { Map>> results = - mService.getAllMatchingFqdnsForScanResults( + getIWifiManager().getAllMatchingFqdnsForScanResults( scanResults); if (results.isEmpty()) { return configs; } List wifiConfigurations = - mService.getWifiConfigsForPasspointProfiles( + getIWifiManager().getWifiConfigsForPasspointProfiles( new ArrayList<>(results.keySet())); for (WifiConfiguration configuration : wifiConfigurations) { Map> scanResultsPerNetworkType = results.get( @@ -1293,7 +1316,7 @@ public class WifiManager { return new HashMap<>(); } try { - return mService.getMatchingOsuProviders(scanResults); + return getIWifiManager().getMatchingOsuProviders(scanResults); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1320,7 +1343,7 @@ public class WifiManager { public Map getMatchingPasspointConfigsForOsuProviders( @NonNull Set osuProviders) { try { - return mService.getMatchingPasspointConfigsForOsuProviders( + return getIWifiManager().getMatchingPasspointConfigsForOsuProviders( new ArrayList<>(osuProviders)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -1405,7 +1428,7 @@ public class WifiManager { */ private int addOrUpdateNetwork(WifiConfiguration config) { try { - return mService.addOrUpdateNetwork(config, mContext.getOpPackageName()); + return getIWifiManager().addOrUpdateNetwork(config, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1631,7 +1654,7 @@ public class WifiManager { Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper(); Binder binder = new Binder(); try { - mService.registerNetworkRequestMatchCallback( + getIWifiManager().registerNetworkRequestMatchCallback( binder, new NetworkRequestMatchCallbackProxy(looper, callback), callback.hashCode()); } catch (RemoteException e) { @@ -1657,7 +1680,7 @@ public class WifiManager { Log.v(TAG, "unregisterNetworkRequestMatchCallback: callback=" + callback); try { - mService.unregisterNetworkRequestMatchCallback(callback.hashCode()); + getIWifiManager().unregisterNetworkRequestMatchCallback(callback.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1691,7 +1714,8 @@ public class WifiManager { public @NetworkSuggestionsStatusCode int addNetworkSuggestions( @NonNull List networkSuggestions) { try { - return mService.addNetworkSuggestions(networkSuggestions, mContext.getOpPackageName()); + return getIWifiManager().addNetworkSuggestions( + networkSuggestions, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1714,7 +1738,7 @@ public class WifiManager { public @NetworkSuggestionsStatusCode int removeNetworkSuggestions( @NonNull List networkSuggestions) { try { - return mService.removeNetworkSuggestions( + return getIWifiManager().removeNetworkSuggestions( networkSuggestions, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -1760,7 +1784,8 @@ public class WifiManager { */ public void addOrUpdatePasspointConfiguration(PasspointConfiguration config) { try { - if (!mService.addOrUpdatePasspointConfiguration(config, mContext.getOpPackageName())) { + if (!getIWifiManager().addOrUpdatePasspointConfiguration( + config, mContext.getOpPackageName())) { throw new IllegalArgumentException(); } } catch (RemoteException e) { @@ -1783,7 +1808,8 @@ public class WifiManager { }) public void removePasspointConfiguration(String fqdn) { try { - if (!mService.removePasspointConfiguration(fqdn, mContext.getOpPackageName())) { + if (!getIWifiManager().removePasspointConfiguration( + fqdn, mContext.getOpPackageName())) { throw new IllegalArgumentException(); } } catch (RemoteException e) { @@ -1806,7 +1832,7 @@ public class WifiManager { }) public List getPasspointConfigurations() { try { - return mService.getPasspointConfigurations(mContext.getOpPackageName()); + return getIWifiManager().getPasspointConfigurations(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1826,7 +1852,7 @@ public class WifiManager { */ public void queryPasspointIcon(long bssid, String fileName) { try { - mService.queryPasspointIcon(bssid, fileName); + getIWifiManager().queryPasspointIcon(bssid, fileName); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1840,7 +1866,7 @@ public class WifiManager { */ public int matchProviderWithCurrentNetwork(String fqdn) { try { - return mService.matchProviderWithCurrentNetwork(fqdn); + return getIWifiManager().matchProviderWithCurrentNetwork(fqdn); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1854,7 +1880,7 @@ public class WifiManager { */ public void deauthenticateNetwork(long holdoff, boolean ess) { try { - mService.deauthenticateNetwork(holdoff, ess); + getIWifiManager().deauthenticateNetwork(holdoff, ess); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1884,7 +1910,7 @@ public class WifiManager { @Deprecated public boolean removeNetwork(int netId) { try { - return mService.removeNetwork(netId, mContext.getOpPackageName()); + return getIWifiManager().removeNetwork(netId, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1939,7 +1965,8 @@ public class WifiManager { boolean success; try { - success = mService.enableNetwork(netId, attemptConnect, mContext.getOpPackageName()); + success = getIWifiManager().enableNetwork( + netId, attemptConnect, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1975,7 +2002,7 @@ public class WifiManager { @Deprecated public boolean disableNetwork(int netId) { try { - return mService.disableNetwork(netId, mContext.getOpPackageName()); + return getIWifiManager().disableNetwork(netId, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1998,7 +2025,7 @@ public class WifiManager { @Deprecated public boolean disconnect() { try { - return mService.disconnect(mContext.getOpPackageName()); + return getIWifiManager().disconnect(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2022,7 +2049,7 @@ public class WifiManager { @Deprecated public boolean reconnect() { try { - return mService.reconnect(mContext.getOpPackageName()); + return getIWifiManager().reconnect(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2046,7 +2073,7 @@ public class WifiManager { @Deprecated public boolean reassociate() { try { - return mService.reassociate(mContext.getOpPackageName()); + return getIWifiManager().reassociate(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2132,7 +2159,7 @@ public class WifiManager { private long getSupportedFeatures() { try { - return mService.getSupportedFeatures(); + return getIWifiManager().getSupportedFeatures(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2261,10 +2288,9 @@ public class WifiManager { * @hide */ public WifiActivityEnergyInfo getControllerActivityEnergyInfo() { - if (mService == null) return null; try { synchronized(this) { - return mService.reportActivityInfo(); + return getIWifiManager().reportActivityInfo(); } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -2304,7 +2330,7 @@ public class WifiManager { public boolean startScan(WorkSource workSource) { try { String packageName = mContext.getOpPackageName(); - return mService.startScan(packageName); + return getIWifiManager().startScan(packageName); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2333,7 +2359,7 @@ public class WifiManager { */ public WifiInfo getConnectionInfo() { try { - return mService.getConnectionInfo(mContext.getOpPackageName()); + return getIWifiManager().getConnectionInfo(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2347,7 +2373,7 @@ public class WifiManager { */ public List getScanResults() { try { - return mService.getScanResults(mContext.getOpPackageName()); + return getIWifiManager().getScanResults(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2366,7 +2392,7 @@ public class WifiManager { @Deprecated public boolean isScanAlwaysAvailable() { try { - return mService.isScanAlwaysAvailable(); + return getIWifiManager().isScanAlwaysAvailable(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2397,7 +2423,7 @@ public class WifiManager { */ public void setCountryCode(@NonNull String country) { try { - mService.setCountryCode(country); + getIWifiManager().setCountryCode(country); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2411,12 +2437,12 @@ public class WifiManager { */ @UnsupportedAppUsage public String getCountryCode() { - try { - String country = mService.getCountryCode(); - return country; - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + try { + String country = getIWifiManager().getCountryCode(); + return country; + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } } /** @@ -2427,7 +2453,7 @@ public class WifiManager { @UnsupportedAppUsage public boolean isDualBandSupported() { try { - return mService.isDualBandSupported(); + return getIWifiManager().isDualBandSupported(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2440,7 +2466,7 @@ public class WifiManager { */ public boolean isDualModeSupported() { try { - return mService.needs5GHzToAnyApBandConversion(); + return getIWifiManager().needs5GHzToAnyApBandConversion(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2453,7 +2479,7 @@ public class WifiManager { */ public DhcpInfo getDhcpInfo() { try { - return mService.getDhcpInfo(); + return getIWifiManager().getDhcpInfo(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2480,7 +2506,7 @@ public class WifiManager { @Deprecated public boolean setWifiEnabled(boolean enabled) { try { - return mService.setWifiEnabled(mContext.getOpPackageName(), enabled); + return getIWifiManager().setWifiEnabled(mContext.getOpPackageName(), enabled); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2495,7 +2521,7 @@ public class WifiManager { */ public int getWifiState() { try { - return mService.getWifiEnabledState(); + return getIWifiManager().getWifiEnabledState(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2569,7 +2595,7 @@ public class WifiManager { */ public void updateInterfaceIpState(String ifaceName, int mode) { try { - mService.updateInterfaceIpState(ifaceName, mode); + getIWifiManager().updateInterfaceIpState(ifaceName, mode); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2587,7 +2613,7 @@ public class WifiManager { */ public boolean startSoftAp(@Nullable WifiConfiguration wifiConfig) { try { - return mService.startSoftAp(wifiConfig); + return getIWifiManager().startSoftAp(wifiConfig); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2602,7 +2628,7 @@ public class WifiManager { */ public boolean stopSoftAp() { try { - return mService.stopSoftAp(); + return getIWifiManager().stopSoftAp(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2671,7 +2697,7 @@ public class WifiManager { new LocalOnlyHotspotCallbackProxy(this, looper, callback); try { String packageName = mContext.getOpPackageName(); - int returnCode = mService.startLocalOnlyHotspot( + int returnCode = getIWifiManager().startLocalOnlyHotspot( proxy.getMessenger(), new Binder(), packageName); if (returnCode != LocalOnlyHotspotCallback.REQUEST_REGISTERED) { // Send message to the proxy to make sure we call back on the correct thread @@ -2723,7 +2749,7 @@ public class WifiManager { } mLOHSCallbackProxy = null; try { - mService.stopLocalOnlyHotspot(); + getIWifiManager().stopLocalOnlyHotspot(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2753,7 +2779,7 @@ public class WifiManager { Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper(); mLOHSObserverProxy = new LocalOnlyHotspotObserverProxy(this, looper, observer); try { - mService.startWatchLocalOnlyHotspot( + getIWifiManager().startWatchLocalOnlyHotspot( mLOHSObserverProxy.getMessenger(), new Binder()); mLOHSObserverProxy.registered(); } catch (RemoteException e) { @@ -2777,7 +2803,7 @@ public class WifiManager { } mLOHSObserverProxy = null; try { - mService.stopWatchLocalOnlyHotspot(); + getIWifiManager().stopWatchLocalOnlyHotspot(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2797,7 +2823,7 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public int getWifiApState() { try { - return mService.getWifiApEnabledState(); + return getIWifiManager().getWifiApEnabledState(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2826,7 +2852,7 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public WifiConfiguration getWifiApConfiguration() { try { - return mService.getWifiApConfiguration(); + return getIWifiManager().getWifiApConfiguration(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2843,7 +2869,8 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public boolean setWifiApConfiguration(WifiConfiguration wifiConfig) { try { - return mService.setWifiApConfiguration(wifiConfig, mContext.getOpPackageName()); + return getIWifiManager().setWifiApConfiguration( + wifiConfig, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2858,7 +2885,7 @@ public class WifiManager { public void notifyUserOfApBandConversion() { Log.d(TAG, "apBand was converted, notify the user"); try { - mService.notifyUserOfApBandConversion(mContext.getOpPackageName()); + getIWifiManager().notifyUserOfApBandConversion(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2886,7 +2913,7 @@ public class WifiManager { */ public void setTdlsEnabled(InetAddress remoteIPAddress, boolean enable) { try { - mService.enableTdls(remoteIPAddress.getHostAddress(), enable); + getIWifiManager().enableTdls(remoteIPAddress.getHostAddress(), enable); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2900,7 +2927,7 @@ public class WifiManager { */ public void setTdlsEnabledWithMacAddress(String remoteMacAddress, boolean enable) { try { - mService.enableTdlsWithMacAddress(remoteMacAddress, enable); + getIWifiManager().enableTdlsWithMacAddress(remoteMacAddress, enable); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -3189,8 +3216,8 @@ public class WifiManager { Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper(); Binder binder = new Binder(); try { - mService.registerSoftApCallback(binder, new SoftApCallbackProxy(looper, callback), - callback.hashCode()); + getIWifiManager().registerSoftApCallback( + binder, new SoftApCallbackProxy(looper, callback), callback.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -3210,7 +3237,7 @@ public class WifiManager { Log.v(TAG, "unregisterSoftApCallback: callback=" + callback); try { - mService.unregisterSoftApCallback(callback.hashCode()); + getIWifiManager().unregisterSoftApCallback(callback.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -3780,7 +3807,7 @@ public class WifiManager { public void disableEphemeralNetwork(String SSID) { if (SSID == null) throw new IllegalArgumentException("SSID cannot be null"); try { - mService.disableEphemeralNetwork(SSID, mContext.getOpPackageName()); + getIWifiManager().disableEphemeralNetwork(SSID, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -3824,7 +3851,7 @@ public class WifiManager { @UnsupportedAppUsage private Messenger getWifiServiceMessenger() { try { - return mService.getWifiServiceMessenger(mContext.getOpPackageName()); + return getIWifiManager().getWifiServiceMessenger(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -3884,10 +3911,10 @@ public class WifiManager { synchronized (mBinder) { if (mRefCounted ? (++mRefCount == 1) : (!mHeld)) { try { - mService.acquireWifiLock(mBinder, mLockType, mTag, mWorkSource); + getIWifiManager().acquireWifiLock(mBinder, mLockType, mTag, mWorkSource); synchronized (WifiManager.this) { if (mActiveLockCount >= MAX_ACTIVE_LOCKS) { - mService.releaseWifiLock(mBinder); + getIWifiManager().releaseWifiLock(mBinder); throw new UnsupportedOperationException( "Exceeded maximum number of wifi locks"); } @@ -3917,7 +3944,7 @@ public class WifiManager { synchronized (mBinder) { if (mRefCounted ? (--mRefCount == 0) : (mHeld)) { try { - mService.releaseWifiLock(mBinder); + getIWifiManager().releaseWifiLock(mBinder); synchronized (WifiManager.this) { mActiveLockCount--; } @@ -3980,7 +4007,7 @@ public class WifiManager { } if (changed && mHeld) { try { - mService.updateWifiLockWorkSource(mBinder, mWorkSource); + getIWifiManager().updateWifiLockWorkSource(mBinder, mWorkSource); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4008,7 +4035,7 @@ public class WifiManager { synchronized (mBinder) { if (mHeld) { try { - mService.releaseWifiLock(mBinder); + getIWifiManager().releaseWifiLock(mBinder); synchronized (WifiManager.this) { mActiveLockCount--; } @@ -4121,10 +4148,10 @@ public class WifiManager { synchronized (mBinder) { if (mRefCounted ? (++mRefCount == 1) : (!mHeld)) { try { - mService.acquireMulticastLock(mBinder, mTag); + getIWifiManager().acquireMulticastLock(mBinder, mTag); synchronized (WifiManager.this) { if (mActiveLockCount >= MAX_ACTIVE_LOCKS) { - mService.releaseMulticastLock(mTag); + getIWifiManager().releaseMulticastLock(mTag); throw new UnsupportedOperationException( "Exceeded maximum number of wifi locks"); } @@ -4166,7 +4193,7 @@ public class WifiManager { synchronized (mBinder) { if (mRefCounted ? (--mRefCount == 0) : (mHeld)) { try { - mService.releaseMulticastLock(mTag); + getIWifiManager().releaseMulticastLock(mTag); synchronized (WifiManager.this) { mActiveLockCount--; } @@ -4243,7 +4270,7 @@ public class WifiManager { */ public boolean isMulticastEnabled() { try { - return mService.isMulticastEnabled(); + return getIWifiManager().isMulticastEnabled(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4256,7 +4283,7 @@ public class WifiManager { @UnsupportedAppUsage public boolean initializeMulticastFiltering() { try { - mService.initializeMulticastFiltering(); + getIWifiManager().initializeMulticastFiltering(); return true; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -4281,7 +4308,7 @@ public class WifiManager { @UnsupportedAppUsage public void enableVerboseLogging (int verbose) { try { - mService.enableVerboseLogging(verbose); + getIWifiManager().enableVerboseLogging(verbose); } catch (Exception e) { //ignore any failure here Log.e(TAG, "enableVerboseLogging " + e.toString()); @@ -4296,7 +4323,7 @@ public class WifiManager { @UnsupportedAppUsage public int getVerboseLoggingLevel() { try { - return mService.getVerboseLoggingLevel(); + return getIWifiManager().getVerboseLoggingLevel(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4309,7 +4336,7 @@ public class WifiManager { */ public void factoryReset() { try { - mService.factoryReset(mContext.getOpPackageName()); + getIWifiManager().factoryReset(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4323,7 +4350,7 @@ public class WifiManager { @UnsupportedAppUsage public Network getCurrentNetwork() { try { - return mService.getCurrentNetwork(); + return getIWifiManager().getCurrentNetwork(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4355,7 +4382,7 @@ public class WifiManager { */ public void enableWifiConnectivityManager(boolean enabled) { try { - mService.enableWifiConnectivityManager(enabled); + getIWifiManager().enableWifiConnectivityManager(enabled); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4367,7 +4394,7 @@ public class WifiManager { */ public byte[] retrieveBackupData() { try { - return mService.retrieveBackupData(); + return getIWifiManager().retrieveBackupData(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4379,7 +4406,7 @@ public class WifiManager { */ public void restoreBackupData(byte[] data) { try { - mService.restoreBackupData(data); + getIWifiManager().restoreBackupData(data); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4395,7 +4422,7 @@ public class WifiManager { @Deprecated public void restoreSupplicantBackupData(byte[] supplicantData, byte[] ipConfigData) { try { - mService.restoreSupplicantBackupData(supplicantData, ipConfigData); + getIWifiManager().restoreSupplicantBackupData(supplicantData, ipConfigData); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4424,7 +4451,7 @@ public class WifiManager { throw new IllegalArgumentException("callback must not be null"); } try { - mService.startSubscriptionProvisioning(provider, + getIWifiManager().startSubscriptionProvisioning(provider, new ProvisioningCallbackProxy(executor, callback)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -4538,7 +4565,7 @@ public class WifiManager { Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper(); Binder binder = new Binder(); try { - mService.registerTrafficStateCallback( + getIWifiManager().registerTrafficStateCallback( binder, new TrafficStateCallbackProxy(looper, callback), callback.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -4558,7 +4585,7 @@ public class WifiManager { Log.v(TAG, "unregisterTrafficStateCallback: callback=" + callback); try { - mService.unregisterTrafficStateCallback(callback.hashCode()); + getIWifiManager().unregisterTrafficStateCallback(callback.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4614,7 +4641,7 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public String[] getFactoryMacAddresses() { try { - return mService.getFactoryMacAddresses(); + return getIWifiManager().getFactoryMacAddresses(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4683,7 +4710,7 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.WIFI_SET_DEVICE_MOBILITY_STATE) public void setDeviceMobilityState(@DeviceMobilityState int state) { try { - mService.setDeviceMobilityState(state); + getIWifiManager().setDeviceMobilityState(state); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4738,8 +4765,9 @@ public class WifiManager { @NonNull EasyConnectStatusCallback callback) { Binder binder = new Binder(); try { - mService.startDppAsConfiguratorInitiator(binder, enrolleeUri, selectedNetworkId, - enrolleeNetworkRole, new EasyConnectCallbackProxy(executor, callback)); + getIWifiManager().startDppAsConfiguratorInitiator( + binder, enrolleeUri, selectedNetworkId, enrolleeNetworkRole, + new EasyConnectCallbackProxy(executor, callback)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4764,7 +4792,7 @@ public class WifiManager { @NonNull EasyConnectStatusCallback callback) { Binder binder = new Binder(); try { - mService.startDppAsEnrolleeInitiator(binder, configuratorUri, + getIWifiManager().startDppAsEnrolleeInitiator(binder, configuratorUri, new EasyConnectCallbackProxy(executor, callback)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -4786,7 +4814,7 @@ public class WifiManager { public void stopEasyConnectSession() { try { /* Request lower layers to stop/abort and clear resources */ - mService.stopDppSession(); + getIWifiManager().stopDppSession(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4885,7 +4913,7 @@ public class WifiManager { Log.v(TAG, "addOnWifiUsabilityStatsListener: listener=" + listener); } try { - mService.addOnWifiUsabilityStatsListener(new Binder(), + getIWifiManager().addOnWifiUsabilityStatsListener(new Binder(), new IOnWifiUsabilityStatsListener.Stub() { @Override public void onWifiUsabilityStats(int seqNum, boolean isSameBssidAndFreq, @@ -4922,7 +4950,7 @@ public class WifiManager { Log.v(TAG, "removeOnWifiUsabilityStatsListener: listener=" + listener); } try { - mService.removeOnWifiUsabilityStatsListener(listener.hashCode()); + getIWifiManager().removeOnWifiUsabilityStatsListener(listener.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4945,7 +4973,7 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public void updateWifiUsabilityScore(int seqNum, int score, int predictionHorizonSec) { try { - mService.updateWifiUsabilityScore(seqNum, score, predictionHorizonSec); + getIWifiManager().updateWifiUsabilityScore(seqNum, score, predictionHorizonSec); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } -- cgit v1.2.3 From 478c8aa0accfc34e36935c51a95d111d38e08ffb Mon Sep 17 00:00:00 2001 From: David Su Date: Mon, 12 Aug 2019 16:41:06 -0700 Subject: IFACE_IP_MODE_*: add IntDef and clean up JavaDocs Add IntDef and clean up JavaDocs Bug: 139157226 Test: compiles Change-Id: I7858cfa59b0fac9cf48b925ba5b1767d883e6a55 --- wifi/java/android/net/wifi/WifiManager.java | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index ca65736d8ec2..107edb0665c3 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -635,10 +635,19 @@ public class WifiManager { */ public static final int SAP_START_FAILURE_NO_CHANNEL = 1; + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"IFACE_IP_MODE_"}, value = { + IFACE_IP_MODE_UNSPECIFIED, + IFACE_IP_MODE_CONFIGURATION_ERROR, + IFACE_IP_MODE_TETHERED, + IFACE_IP_MODE_LOCAL_ONLY}) + public @interface IfaceIpMode {} + /** * Interface IP mode unspecified. * - * @see updateInterfaceIpState(String, int) + * @see #updateInterfaceIpState(String, int) * * @hide */ @@ -647,7 +656,7 @@ public class WifiManager { /** * Interface IP mode for configuration error. * - * @see updateInterfaceIpState(String, int) + * @see #updateInterfaceIpState(String, int) * * @hide */ @@ -656,7 +665,7 @@ public class WifiManager { /** * Interface IP mode for tethering. * - * @see updateInterfaceIpState(String, int) + * @see #updateInterfaceIpState(String, int) * * @hide */ @@ -665,7 +674,7 @@ public class WifiManager { /** * Interface IP mode for Local Only Hotspot. * - * @see updateInterfaceIpState(String, int) + * @see #updateInterfaceIpState(String, int) * * @hide */ @@ -2584,9 +2593,9 @@ 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} + * 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 -- cgit v1.2.3 From dfb747ef8dc8ddced934ffa1d5e4b2897ad6bc20 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Wed, 21 Aug 2019 10:38:24 -0700 Subject: WifiManager: Return dummy values when wifi service is not up Many system/vendor modules assume that wifi service is up by the time they run. This is no longer the case since wifi stack now starts a little later in the bootup sequence (to support pluggable wifi stack module for mainline). If any of these modules invoke a WifiManager call, a) Return an appropriate dummy value if the API returns a value b) Raise a RemoteException if the API returns nothing (void). Bug: 139492857 Bug: 137650946 Test: Verified that SUW & CNE receiver no longer crashes with the stack traces in the linked bugs. Also, verified that SUW still can connect to wifi networks & detect when wifi auto-connects after SUW comes up. Test: Verified wifi/softap toggle from Settings/Sysui. Change-Id: Ia100a4612fc903ae470a0c89523d4fda27eb3fbc --- wifi/java/android/net/wifi/WifiManager.java | 416 ++++++++++++++++++++++------ 1 file changed, 327 insertions(+), 89 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index ca65736d8ec2..e9c24cd6e3e0 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -70,7 +70,6 @@ import java.lang.ref.WeakReference; import java.net.InetAddress; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -1170,15 +1169,16 @@ public class WifiManager { updateVerboseLoggingEnabledFromService(); } - private IWifiManager getIWifiManager() throws RemoteException { + private IWifiManager getIWifiManager() { if (mService == null) { synchronized (this) { mService = IWifiManager.Stub.asInterface( ServiceManager.getService(Context.WIFI_SERVICE)); - if (mService == null) { - throw new RemoteException("Wifi Service not running"); + if (mService != null) { + updateVerboseLoggingEnabledFromService(); + } else { + Log.e(TAG, "Wifi Service not running yet, ignoring WifiManager API call"); } - updateVerboseLoggingEnabledFromService(); } } return mService; @@ -1223,8 +1223,10 @@ public class WifiManager { @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE}) public List getConfiguredNetworks() { try { + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return Collections.emptyList(); ParceledListSlice parceledList = - getIWifiManager().getConfiguredNetworks(mContext.getOpPackageName()); + iWifiManager.getConfiguredNetworks(mContext.getOpPackageName()); if (parceledList == null) { return Collections.emptyList(); } @@ -1239,8 +1241,10 @@ public class WifiManager { @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE, READ_WIFI_CREDENTIAL}) public List getPrivilegedConfiguredNetworks() { try { + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return Collections.emptyList(); ParceledListSlice parceledList = - getIWifiManager().getPrivilegedConfiguredNetworks(mContext.getOpPackageName()); + iWifiManager.getPrivilegedConfiguredNetworks(mContext.getOpPackageName()); if (parceledList == null) { return Collections.emptyList(); } @@ -1271,14 +1275,16 @@ public class WifiManager { @NonNull List scanResults) { List>>> configs = new ArrayList<>(); try { + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return Collections.emptyList(); Map>> results = - getIWifiManager().getAllMatchingFqdnsForScanResults( + iWifiManager.getAllMatchingFqdnsForScanResults( scanResults); if (results.isEmpty()) { return configs; } List wifiConfigurations = - getIWifiManager().getWifiConfigsForPasspointProfiles( + iWifiManager.getWifiConfigsForPasspointProfiles( new ArrayList<>(results.keySet())); for (WifiConfiguration configuration : wifiConfigurations) { Map> scanResultsPerNetworkType = results.get( @@ -1313,10 +1319,12 @@ public class WifiManager { public Map> getMatchingOsuProviders( @Nullable List scanResults) { if (scanResults == null) { - return new HashMap<>(); + return Collections.emptyMap(); } try { - return getIWifiManager().getMatchingOsuProviders(scanResults); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return Collections.emptyMap(); + return iWifiManager.getMatchingOsuProviders(scanResults); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1343,7 +1351,9 @@ public class WifiManager { public Map getMatchingPasspointConfigsForOsuProviders( @NonNull Set osuProviders) { try { - return getIWifiManager().getMatchingPasspointConfigsForOsuProviders( + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return Collections.emptyMap(); + return iWifiManager.getMatchingPasspointConfigsForOsuProviders( new ArrayList<>(osuProviders)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -1428,7 +1438,9 @@ public class WifiManager { */ private int addOrUpdateNetwork(WifiConfiguration config) { try { - return getIWifiManager().addOrUpdateNetwork(config, mContext.getOpPackageName()); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return -1; + return iWifiManager.addOrUpdateNetwork(config, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1654,7 +1666,11 @@ public class WifiManager { Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper(); Binder binder = new Binder(); try { - getIWifiManager().registerNetworkRequestMatchCallback( + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.registerNetworkRequestMatchCallback( binder, new NetworkRequestMatchCallbackProxy(looper, callback), callback.hashCode()); } catch (RemoteException e) { @@ -1680,7 +1696,11 @@ public class WifiManager { Log.v(TAG, "unregisterNetworkRequestMatchCallback: callback=" + callback); try { - getIWifiManager().unregisterNetworkRequestMatchCallback(callback.hashCode()); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.unregisterNetworkRequestMatchCallback(callback.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1714,7 +1734,9 @@ public class WifiManager { public @NetworkSuggestionsStatusCode int addNetworkSuggestions( @NonNull List networkSuggestions) { try { - return getIWifiManager().addNetworkSuggestions( + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL; + return iWifiManager.addNetworkSuggestions( networkSuggestions, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -1738,7 +1760,9 @@ public class WifiManager { public @NetworkSuggestionsStatusCode int removeNetworkSuggestions( @NonNull List networkSuggestions) { try { - return getIWifiManager().removeNetworkSuggestions( + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL; + return iWifiManager.removeNetworkSuggestions( networkSuggestions, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -1754,7 +1778,9 @@ public class WifiManager { @RequiresPermission(ACCESS_WIFI_STATE) public @NonNull List getNetworkSuggestions() { try { - return mService.getNetworkSuggestions(mContext.getOpPackageName()); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return Collections.emptyList(); + return iWifiManager.getNetworkSuggestions(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); } @@ -1784,7 +1810,11 @@ public class WifiManager { */ public void addOrUpdatePasspointConfiguration(PasspointConfiguration config) { try { - if (!getIWifiManager().addOrUpdatePasspointConfiguration( + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + if (!iWifiManager.addOrUpdatePasspointConfiguration( config, mContext.getOpPackageName())) { throw new IllegalArgumentException(); } @@ -1808,7 +1838,11 @@ public class WifiManager { }) public void removePasspointConfiguration(String fqdn) { try { - if (!getIWifiManager().removePasspointConfiguration( + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + if (!iWifiManager.removePasspointConfiguration( fqdn, mContext.getOpPackageName())) { throw new IllegalArgumentException(); } @@ -1832,7 +1866,9 @@ public class WifiManager { }) public List getPasspointConfigurations() { try { - return getIWifiManager().getPasspointConfigurations(mContext.getOpPackageName()); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) Collections.emptyList(); + return iWifiManager.getPasspointConfigurations(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1852,7 +1888,11 @@ public class WifiManager { */ public void queryPasspointIcon(long bssid, String fileName) { try { - getIWifiManager().queryPasspointIcon(bssid, fileName); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.queryPasspointIcon(bssid, fileName); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1866,7 +1906,9 @@ public class WifiManager { */ public int matchProviderWithCurrentNetwork(String fqdn) { try { - return getIWifiManager().matchProviderWithCurrentNetwork(fqdn); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return -1; + return iWifiManager.matchProviderWithCurrentNetwork(fqdn); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1880,7 +1922,11 @@ public class WifiManager { */ public void deauthenticateNetwork(long holdoff, boolean ess) { try { - getIWifiManager().deauthenticateNetwork(holdoff, ess); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.deauthenticateNetwork(holdoff, ess); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1910,7 +1956,9 @@ public class WifiManager { @Deprecated public boolean removeNetwork(int netId) { try { - return getIWifiManager().removeNetwork(netId, mContext.getOpPackageName()); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return false; + return iWifiManager.removeNetwork(netId, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1965,7 +2013,9 @@ public class WifiManager { boolean success; try { - success = getIWifiManager().enableNetwork( + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return false; + success = iWifiManager.enableNetwork( netId, attemptConnect, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -2002,7 +2052,9 @@ public class WifiManager { @Deprecated public boolean disableNetwork(int netId) { try { - return getIWifiManager().disableNetwork(netId, mContext.getOpPackageName()); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return false; + return iWifiManager.disableNetwork(netId, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2025,7 +2077,9 @@ public class WifiManager { @Deprecated public boolean disconnect() { try { - return getIWifiManager().disconnect(mContext.getOpPackageName()); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return false; + return iWifiManager.disconnect(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2049,7 +2103,9 @@ public class WifiManager { @Deprecated public boolean reconnect() { try { - return getIWifiManager().reconnect(mContext.getOpPackageName()); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return false; + return iWifiManager.reconnect(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2073,7 +2129,9 @@ public class WifiManager { @Deprecated public boolean reassociate() { try { - return getIWifiManager().reassociate(mContext.getOpPackageName()); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return false; + return iWifiManager.reassociate(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2159,7 +2217,9 @@ public class WifiManager { private long getSupportedFeatures() { try { - return getIWifiManager().getSupportedFeatures(); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return 0L; + return iWifiManager.getSupportedFeatures(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2289,8 +2349,10 @@ public class WifiManager { */ public WifiActivityEnergyInfo getControllerActivityEnergyInfo() { try { + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return null; synchronized(this) { - return getIWifiManager().reportActivityInfo(); + return iWifiManager.reportActivityInfo(); } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -2329,8 +2391,10 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public boolean startScan(WorkSource workSource) { try { + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return false; String packageName = mContext.getOpPackageName(); - return getIWifiManager().startScan(packageName); + return iWifiManager.startScan(packageName); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2359,7 +2423,9 @@ public class WifiManager { */ public WifiInfo getConnectionInfo() { try { - return getIWifiManager().getConnectionInfo(mContext.getOpPackageName()); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return null; + return iWifiManager.getConnectionInfo(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2373,7 +2439,9 @@ public class WifiManager { */ public List getScanResults() { try { - return getIWifiManager().getScanResults(mContext.getOpPackageName()); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return Collections.emptyList(); + return iWifiManager.getScanResults(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2392,7 +2460,9 @@ public class WifiManager { @Deprecated public boolean isScanAlwaysAvailable() { try { - return getIWifiManager().isScanAlwaysAvailable(); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return false; + return iWifiManager.isScanAlwaysAvailable(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2423,7 +2493,11 @@ public class WifiManager { */ public void setCountryCode(@NonNull String country) { try { - getIWifiManager().setCountryCode(country); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.setCountryCode(country); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2438,7 +2512,9 @@ public class WifiManager { @UnsupportedAppUsage public String getCountryCode() { try { - String country = getIWifiManager().getCountryCode(); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return null; + String country = iWifiManager.getCountryCode(); return country; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -2453,7 +2529,9 @@ public class WifiManager { @UnsupportedAppUsage public boolean isDualBandSupported() { try { - return getIWifiManager().isDualBandSupported(); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return false; + return iWifiManager.isDualBandSupported(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2466,7 +2544,9 @@ public class WifiManager { */ public boolean isDualModeSupported() { try { - return getIWifiManager().needs5GHzToAnyApBandConversion(); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return false; + return iWifiManager.needs5GHzToAnyApBandConversion(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2479,7 +2559,9 @@ public class WifiManager { */ public DhcpInfo getDhcpInfo() { try { - return getIWifiManager().getDhcpInfo(); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return null; + return iWifiManager.getDhcpInfo(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2506,7 +2588,9 @@ public class WifiManager { @Deprecated public boolean setWifiEnabled(boolean enabled) { try { - return getIWifiManager().setWifiEnabled(mContext.getOpPackageName(), enabled); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return false; + return iWifiManager.setWifiEnabled(mContext.getOpPackageName(), enabled); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2521,7 +2605,9 @@ public class WifiManager { */ public int getWifiState() { try { - return getIWifiManager().getWifiEnabledState(); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return WIFI_STATE_UNKNOWN; + return iWifiManager.getWifiEnabledState(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2595,7 +2681,11 @@ public class WifiManager { */ public void updateInterfaceIpState(String ifaceName, int mode) { try { - getIWifiManager().updateInterfaceIpState(ifaceName, mode); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.updateInterfaceIpState(ifaceName, mode); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2613,7 +2703,9 @@ public class WifiManager { */ public boolean startSoftAp(@Nullable WifiConfiguration wifiConfig) { try { - return getIWifiManager().startSoftAp(wifiConfig); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return false; + return iWifiManager.startSoftAp(wifiConfig); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2628,7 +2720,9 @@ public class WifiManager { */ public boolean stopSoftAp() { try { - return getIWifiManager().stopSoftAp(); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return false; + return iWifiManager.stopSoftAp(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2696,8 +2790,12 @@ public class WifiManager { LocalOnlyHotspotCallbackProxy proxy = new LocalOnlyHotspotCallbackProxy(this, looper, callback); try { + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } String packageName = mContext.getOpPackageName(); - int returnCode = getIWifiManager().startLocalOnlyHotspot( + int returnCode = iWifiManager.startLocalOnlyHotspot( proxy.getMessenger(), new Binder(), packageName); if (returnCode != LocalOnlyHotspotCallback.REQUEST_REGISTERED) { // Send message to the proxy to make sure we call back on the correct thread @@ -2749,7 +2847,11 @@ public class WifiManager { } mLOHSCallbackProxy = null; try { - getIWifiManager().stopLocalOnlyHotspot(); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.stopLocalOnlyHotspot(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2779,7 +2881,11 @@ public class WifiManager { Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper(); mLOHSObserverProxy = new LocalOnlyHotspotObserverProxy(this, looper, observer); try { - getIWifiManager().startWatchLocalOnlyHotspot( + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.startWatchLocalOnlyHotspot( mLOHSObserverProxy.getMessenger(), new Binder()); mLOHSObserverProxy.registered(); } catch (RemoteException e) { @@ -2803,7 +2909,11 @@ public class WifiManager { } mLOHSObserverProxy = null; try { - getIWifiManager().stopWatchLocalOnlyHotspot(); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.stopWatchLocalOnlyHotspot(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2823,7 +2933,9 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public int getWifiApState() { try { - return getIWifiManager().getWifiApEnabledState(); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return WIFI_AP_STATE_FAILED; + return iWifiManager.getWifiApEnabledState(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2852,7 +2964,9 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public WifiConfiguration getWifiApConfiguration() { try { - return getIWifiManager().getWifiApConfiguration(); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return null; + return iWifiManager.getWifiApConfiguration(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2869,7 +2983,9 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public boolean setWifiApConfiguration(WifiConfiguration wifiConfig) { try { - return getIWifiManager().setWifiApConfiguration( + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return false; + return iWifiManager.setWifiApConfiguration( wifiConfig, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -2885,7 +3001,11 @@ public class WifiManager { public void notifyUserOfApBandConversion() { Log.d(TAG, "apBand was converted, notify the user"); try { - getIWifiManager().notifyUserOfApBandConversion(mContext.getOpPackageName()); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.notifyUserOfApBandConversion(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2913,7 +3033,11 @@ public class WifiManager { */ public void setTdlsEnabled(InetAddress remoteIPAddress, boolean enable) { try { - getIWifiManager().enableTdls(remoteIPAddress.getHostAddress(), enable); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.enableTdls(remoteIPAddress.getHostAddress(), enable); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2927,7 +3051,11 @@ public class WifiManager { */ public void setTdlsEnabledWithMacAddress(String remoteMacAddress, boolean enable) { try { - getIWifiManager().enableTdlsWithMacAddress(remoteMacAddress, enable); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.enableTdlsWithMacAddress(remoteMacAddress, enable); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -3216,7 +3344,11 @@ public class WifiManager { Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper(); Binder binder = new Binder(); try { - getIWifiManager().registerSoftApCallback( + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.registerSoftApCallback( binder, new SoftApCallbackProxy(looper, callback), callback.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -3237,7 +3369,11 @@ public class WifiManager { Log.v(TAG, "unregisterSoftApCallback: callback=" + callback); try { - getIWifiManager().unregisterSoftApCallback(callback.hashCode()); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.unregisterSoftApCallback(callback.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -3807,7 +3943,11 @@ public class WifiManager { public void disableEphemeralNetwork(String SSID) { if (SSID == null) throw new IllegalArgumentException("SSID cannot be null"); try { - getIWifiManager().disableEphemeralNetwork(SSID, mContext.getOpPackageName()); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.disableEphemeralNetwork(SSID, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -3851,7 +3991,9 @@ public class WifiManager { @UnsupportedAppUsage private Messenger getWifiServiceMessenger() { try { - return getIWifiManager().getWifiServiceMessenger(mContext.getOpPackageName()); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return null; + return iWifiManager.getWifiServiceMessenger(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -3911,10 +4053,14 @@ public class WifiManager { synchronized (mBinder) { if (mRefCounted ? (++mRefCount == 1) : (!mHeld)) { try { - getIWifiManager().acquireWifiLock(mBinder, mLockType, mTag, mWorkSource); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.acquireWifiLock(mBinder, mLockType, mTag, mWorkSource); synchronized (WifiManager.this) { if (mActiveLockCount >= MAX_ACTIVE_LOCKS) { - getIWifiManager().releaseWifiLock(mBinder); + iWifiManager.releaseWifiLock(mBinder); throw new UnsupportedOperationException( "Exceeded maximum number of wifi locks"); } @@ -3944,7 +4090,11 @@ public class WifiManager { synchronized (mBinder) { if (mRefCounted ? (--mRefCount == 0) : (mHeld)) { try { - getIWifiManager().releaseWifiLock(mBinder); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.releaseWifiLock(mBinder); synchronized (WifiManager.this) { mActiveLockCount--; } @@ -4007,7 +4157,11 @@ public class WifiManager { } if (changed && mHeld) { try { - getIWifiManager().updateWifiLockWorkSource(mBinder, mWorkSource); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.updateWifiLockWorkSource(mBinder, mWorkSource); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4035,7 +4189,11 @@ public class WifiManager { synchronized (mBinder) { if (mHeld) { try { - getIWifiManager().releaseWifiLock(mBinder); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.releaseWifiLock(mBinder); synchronized (WifiManager.this) { mActiveLockCount--; } @@ -4148,10 +4306,14 @@ public class WifiManager { synchronized (mBinder) { if (mRefCounted ? (++mRefCount == 1) : (!mHeld)) { try { - getIWifiManager().acquireMulticastLock(mBinder, mTag); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.acquireMulticastLock(mBinder, mTag); synchronized (WifiManager.this) { if (mActiveLockCount >= MAX_ACTIVE_LOCKS) { - getIWifiManager().releaseMulticastLock(mTag); + iWifiManager.releaseMulticastLock(mTag); throw new UnsupportedOperationException( "Exceeded maximum number of wifi locks"); } @@ -4193,7 +4355,11 @@ public class WifiManager { synchronized (mBinder) { if (mRefCounted ? (--mRefCount == 0) : (mHeld)) { try { - getIWifiManager().releaseMulticastLock(mTag); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.releaseMulticastLock(mTag); synchronized (WifiManager.this) { mActiveLockCount--; } @@ -4270,7 +4436,9 @@ public class WifiManager { */ public boolean isMulticastEnabled() { try { - return getIWifiManager().isMulticastEnabled(); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return false; + return iWifiManager.isMulticastEnabled(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4283,7 +4451,9 @@ public class WifiManager { @UnsupportedAppUsage public boolean initializeMulticastFiltering() { try { - getIWifiManager().initializeMulticastFiltering(); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return false; + iWifiManager.initializeMulticastFiltering(); return true; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -4308,7 +4478,11 @@ public class WifiManager { @UnsupportedAppUsage public void enableVerboseLogging (int verbose) { try { - getIWifiManager().enableVerboseLogging(verbose); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.enableVerboseLogging(verbose); } catch (Exception e) { //ignore any failure here Log.e(TAG, "enableVerboseLogging " + e.toString()); @@ -4323,7 +4497,9 @@ public class WifiManager { @UnsupportedAppUsage public int getVerboseLoggingLevel() { try { - return getIWifiManager().getVerboseLoggingLevel(); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return -1; + return iWifiManager.getVerboseLoggingLevel(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4336,7 +4512,11 @@ public class WifiManager { */ public void factoryReset() { try { - getIWifiManager().factoryReset(mContext.getOpPackageName()); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.factoryReset(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4350,7 +4530,9 @@ public class WifiManager { @UnsupportedAppUsage public Network getCurrentNetwork() { try { - return getIWifiManager().getCurrentNetwork(); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return null; + return iWifiManager.getCurrentNetwork(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4382,7 +4564,11 @@ public class WifiManager { */ public void enableWifiConnectivityManager(boolean enabled) { try { - getIWifiManager().enableWifiConnectivityManager(enabled); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.enableWifiConnectivityManager(enabled); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4394,7 +4580,9 @@ public class WifiManager { */ public byte[] retrieveBackupData() { try { - return getIWifiManager().retrieveBackupData(); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return null; + return iWifiManager.retrieveBackupData(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4406,7 +4594,11 @@ public class WifiManager { */ public void restoreBackupData(byte[] data) { try { - getIWifiManager().restoreBackupData(data); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.restoreBackupData(data); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4422,7 +4614,11 @@ public class WifiManager { @Deprecated public void restoreSupplicantBackupData(byte[] supplicantData, byte[] ipConfigData) { try { - getIWifiManager().restoreSupplicantBackupData(supplicantData, ipConfigData); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.restoreSupplicantBackupData(supplicantData, ipConfigData); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4451,7 +4647,11 @@ public class WifiManager { throw new IllegalArgumentException("callback must not be null"); } try { - getIWifiManager().startSubscriptionProvisioning(provider, + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.startSubscriptionProvisioning(provider, new ProvisioningCallbackProxy(executor, callback)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -4565,7 +4765,11 @@ public class WifiManager { Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper(); Binder binder = new Binder(); try { - getIWifiManager().registerTrafficStateCallback( + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.registerTrafficStateCallback( binder, new TrafficStateCallbackProxy(looper, callback), callback.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -4585,7 +4789,11 @@ public class WifiManager { Log.v(TAG, "unregisterTrafficStateCallback: callback=" + callback); try { - getIWifiManager().unregisterTrafficStateCallback(callback.hashCode()); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.unregisterTrafficStateCallback(callback.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4641,7 +4849,9 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public String[] getFactoryMacAddresses() { try { - return getIWifiManager().getFactoryMacAddresses(); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) return null; + return iWifiManager.getFactoryMacAddresses(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4710,7 +4920,11 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.WIFI_SET_DEVICE_MOBILITY_STATE) public void setDeviceMobilityState(@DeviceMobilityState int state) { try { - getIWifiManager().setDeviceMobilityState(state); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.setDeviceMobilityState(state); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4765,7 +4979,11 @@ public class WifiManager { @NonNull EasyConnectStatusCallback callback) { Binder binder = new Binder(); try { - getIWifiManager().startDppAsConfiguratorInitiator( + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.startDppAsConfiguratorInitiator( binder, enrolleeUri, selectedNetworkId, enrolleeNetworkRole, new EasyConnectCallbackProxy(executor, callback)); } catch (RemoteException e) { @@ -4792,7 +5010,11 @@ public class WifiManager { @NonNull EasyConnectStatusCallback callback) { Binder binder = new Binder(); try { - getIWifiManager().startDppAsEnrolleeInitiator(binder, configuratorUri, + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.startDppAsEnrolleeInitiator(binder, configuratorUri, new EasyConnectCallbackProxy(executor, callback)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -4813,8 +5035,12 @@ public class WifiManager { android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void stopEasyConnectSession() { try { + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } /* Request lower layers to stop/abort and clear resources */ - getIWifiManager().stopDppSession(); + iWifiManager.stopDppSession(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4913,7 +5139,11 @@ public class WifiManager { Log.v(TAG, "addOnWifiUsabilityStatsListener: listener=" + listener); } try { - getIWifiManager().addOnWifiUsabilityStatsListener(new Binder(), + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.addOnWifiUsabilityStatsListener(new Binder(), new IOnWifiUsabilityStatsListener.Stub() { @Override public void onWifiUsabilityStats(int seqNum, boolean isSameBssidAndFreq, @@ -4950,7 +5180,11 @@ public class WifiManager { Log.v(TAG, "removeOnWifiUsabilityStatsListener: listener=" + listener); } try { - getIWifiManager().removeOnWifiUsabilityStatsListener(listener.hashCode()); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.removeOnWifiUsabilityStatsListener(listener.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4973,7 +5207,11 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public void updateWifiUsabilityScore(int seqNum, int score, int predictionHorizonSec) { try { - getIWifiManager().updateWifiUsabilityScore(seqNum, score, predictionHorizonSec); + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.updateWifiUsabilityScore(seqNum, score, predictionHorizonSec); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } -- cgit v1.2.3 From 3c9c642fdbd2649175f992b45e9f093299b564a4 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Wed, 7 Aug 2019 18:15:52 +0800 Subject: wifi: common name support in PPS-MO profile Bug: 120107510 Test: atest FrameworksWifiApiTests Change-Id: I82d3e280ebf3169288409a9a1c2a845f88d8e345 --- .../net/wifi/hotspot2/PasspointConfiguration.java | 33 +++++ .../net/wifi/hotspot2/omadm/PpsMoParser.java | 133 ++++++++++++++++++++- .../android/net/wifi/hotspot2/pps/Credential.java | 1 + wifi/tests/assets/pps/PerProviderSubscription.xml | 24 ++++ .../wifi/hotspot2/PasspointConfigurationTest.java | 30 +++++ .../net/wifi/hotspot2/omadm/PpsMoParserTest.java | 3 + 6 files changed, 221 insertions(+), 3 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java index 9095b5d927a2..557b7c9b05e9 100644 --- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java +++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java @@ -16,6 +16,7 @@ package android.net.wifi.hotspot2; +import android.annotation.Nullable; import android.net.wifi.hotspot2.pps.Credential; import android.net.wifi.hotspot2.pps.HomeSp; import android.net.wifi.hotspot2.pps.Policy; @@ -77,6 +78,29 @@ public final class PasspointConfiguration implements Parcelable { */ public HomeSp getHomeSp() { return mHomeSp; } + /** + * Configurations under AAAServerTrustedNames subtree. + */ + private String[] mAaaServerTrustedNames = null; + /** + * Set the AAA server trusted names information. + * + * @param aaaServerTrustedNames The AAA server trusted names information to set to + * @hide + */ + public void setAaaServerTrustedNames(@Nullable String[] aaaServerTrustedNames) { + mAaaServerTrustedNames = aaaServerTrustedNames; + } + /** + * Get the AAA server trusted names information. + * + * @return AAA server trusted names information + * @hide + */ + public @Nullable String[] getAaaServerTrustedNames() { + return mAaaServerTrustedNames; + } + /** * Configurations under Credential subtree. */ @@ -409,6 +433,7 @@ public final class PasspointConfiguration implements Parcelable { mUsageLimitTimeLimitInMinutes = source.mUsageLimitTimeLimitInMinutes; mUsageLimitUsageTimePeriodInMinutes = source.mUsageLimitUsageTimePeriodInMinutes; mServiceFriendlyNames = source.mServiceFriendlyNames; + mAaaServerTrustedNames = source.mAaaServerTrustedNames; } @Override @@ -432,6 +457,7 @@ public final class PasspointConfiguration implements Parcelable { dest.writeLong(mUsageLimitStartTimeInMillis); dest.writeLong(mUsageLimitDataLimit); dest.writeLong(mUsageLimitTimeLimitInMinutes); + dest.writeStringArray(mAaaServerTrustedNames); Bundle bundle = new Bundle(); bundle.putSerializable("serviceFriendlyNames", (HashMap) mServiceFriendlyNames); @@ -448,6 +474,8 @@ public final class PasspointConfiguration implements Parcelable { } PasspointConfiguration that = (PasspointConfiguration) thatObject; return (mHomeSp == null ? that.mHomeSp == null : mHomeSp.equals(that.mHomeSp)) + && (mAaaServerTrustedNames == null ? that.mAaaServerTrustedNames == null + : Arrays.equals(mAaaServerTrustedNames, that.mAaaServerTrustedNames)) && (mCredential == null ? that.mCredential == null : mCredential.equals(that.mCredential)) && (mPolicy == null ? that.mPolicy == null : mPolicy.equals(that.mPolicy)) @@ -517,6 +545,10 @@ public final class PasspointConfiguration implements Parcelable { builder.append("TrustRootCertServers: ").append(mTrustRootCertList.keySet()) .append("\n"); } + if (mAaaServerTrustedNames != null) { + builder.append("AAAServerTrustedNames: ") + .append(String.join(";", mAaaServerTrustedNames)).append("\n"); + } if (mServiceFriendlyNames != null) { builder.append("ServiceFriendlyNames: ").append(mServiceFriendlyNames); } @@ -619,6 +651,7 @@ public final class PasspointConfiguration implements Parcelable { config.setUsageLimitStartTimeInMillis(in.readLong()); config.setUsageLimitDataLimit(in.readLong()); config.setUsageLimitTimeLimitInMinutes(in.readLong()); + config.setAaaServerTrustedNames(in.createStringArray()); Bundle bundle = in.readBundle(); Map friendlyNamesMap = (HashMap) bundle.getSerializable( "serviceFriendlyNames"); diff --git a/wifi/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java b/wifi/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java index 984cf7d62aa5..68358abe188d 100644 --- a/wifi/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java +++ b/wifi/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java @@ -25,6 +25,8 @@ import android.text.TextUtils; import android.util.Log; import android.util.Pair; +import org.xml.sax.SAXException; + import java.io.IOException; import java.text.DateFormat; import java.text.ParseException; @@ -36,8 +38,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import org.xml.sax.SAXException; - /** * Utility class for converting OMA-DM (Open Mobile Alliance's Device Management) * PPS-MO (PerProviderSubscription Management Object) XML tree to a @@ -146,6 +146,47 @@ public final class PpsMoParser { private static final String NODE_CREDENTIAL_PRIORITY = "CredentialPriority"; private static final String NODE_EXTENSION = "Extension"; + /** + * Fields under Extension/Android subtree. + */ + /* + * This node is used to put Android specific extension nodes and must be put + * under "Extension" node. Nodes with unknown names are allowed under this subtree. + * If there is any new node added in later release, it won't break older release parsing. + *

+ * Ex: + * + * Extension + * + * Android + * + * AndroidSpecificAttribute + * AndroidSpecificValue + * + * + * AndroidSpecificAttribute2 + * AndroidSpecificValue2 + * + * + * + */ + private static final String NODE_VENDOR_ANDROID = "Android"; + /* + * This node describes AAA server trusted names. The trusted name must be put in + * a leaf named "FQDN". More than one trusted names can be provided by using + * semicolons to separate the strings (e.g., example.org;example.com). + *

+ * Ex: + * + * AAAServerTrustedNames + * + * FQDN + * trusted.com;auth.net + * + * + */ + private static final String NODE_AAA_SERVER_TRUSTED_NAMES = "AAAServerTrustedNames"; + /** * Fields under HomeSP subtree. */ @@ -633,7 +674,7 @@ public final class PpsMoParser { break; case NODE_EXTENSION: // All vendor specific information will be under this node. - Log.d(TAG, "Ignore Extension node for vendor specific information"); + parseExtension(child, config); break; default: throw new ParsingException("Unknown node: " + child.getName()); @@ -1571,6 +1612,92 @@ public final class PpsMoParser { } } + /** + * Parse configurations under PerProviderSubscription/Extension/Android/AAAServerTrustedNames + * subtree. + * + * @param node PPSNode representing the root of the + * PerProviderSubscription/Extension/Android/AAAServerTrustedNames subtree + * @return String[] list of trusted name + * @throws ParsingException + */ + private static String[] parseAaaServerTrustedNames(PPSNode node) throws ParsingException { + if (node.isLeaf()) { + throw new ParsingException("Leaf node not expected for AAAServerTrustedNames instance"); + } + String fqdnListStr = null; + String[] fqdnListArray = null; + for (PPSNode child : node.getChildren()) { + switch (child.getName()) { + case NODE_FQDN: + fqdnListStr = getPpsNodeValue(child); + fqdnListArray = fqdnListStr.split(";"); + break; + default: + throw new ParsingException( + "Unknown node under AAAServerTrustedNames instance: " + + child.getName()); + } + } + if (fqdnListArray == null) { + throw new ParsingException("AAAServerTrustedNames instance missing FQDN field"); + } + + return fqdnListArray; + } + + /** + * Parse configurations under PerProviderSubscription/Extension/Android subtree. + * + * @param node PPSNode representing the root of PerProviderSubscription/Extension + * subtree + * @param config Instance of {@link PasspointConfiguration} + * @throws ParsingException + */ + private static void parseVendorAndroidExtension(PPSNode node, PasspointConfiguration config) + throws ParsingException { + if (node.isLeaf()) { + throw new ParsingException("Leaf node not expected for Extension"); + } + for (PPSNode child : node.getChildren()) { + switch (child.getName()) { + case NODE_AAA_SERVER_TRUSTED_NAMES: + config.setAaaServerTrustedNames(parseAaaServerTrustedNames(child)); + break; + default: + // Don't raise an exception for unknown nodes to avoid breaking old release + Log.w(TAG, "Unknown node under Android Extension: " + child.getName()); + } + } + } + + /** + * Parse configurations under PerProviderSubscription/Extension subtree. + * + * @param node PPSNode representing the root of PerProviderSubscription/Extension + * subtree + * @param config Instance of {@link PasspointConfiguration} + * @throws ParsingException + */ + private static void parseExtension(PPSNode node, PasspointConfiguration config) + throws ParsingException { + if (node.isLeaf()) { + throw new ParsingException("Leaf node not expected for Extension"); + } + for (PPSNode child : node.getChildren()) { + switch (child.getName()) { + case NODE_VENDOR_ANDROID: + parseVendorAndroidExtension(child, config); + break; + default: + // Unknown nodes under Extension won't raise exception. + // This allows adding new nodes in the future and + // won't break older release. + Log.w(TAG, "Unknown node under Extension: " + child.getName()); + } + } + } + /** * Convert a hex string to a byte array. * diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java index 9409c03c614d..b037703ca056 100644 --- a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java +++ b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java @@ -1135,6 +1135,7 @@ public final class Credential implements Parcelable { Log.d(TAG, "Missing CA Certificate for user credential"); return false; } + return true; } diff --git a/wifi/tests/assets/pps/PerProviderSubscription.xml b/wifi/tests/assets/pps/PerProviderSubscription.xml index e4472ce19d51..e9afb35fec94 100644 --- a/wifi/tests/assets/pps/PerProviderSubscription.xml +++ b/wifi/tests/assets/pps/PerProviderSubscription.xml @@ -19,6 +19,30 @@ VendorSpecific Test + + VendorExtension + + VendorAttribute + VendorValue + + + + Android + + AAAServerTrustedNames + + FQDN + trusted.fqdn.com;another-trusted.fqdn.com + + + + NewSubTree + + NewAttribute + NewValue + + + HomeSP diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java index fc03e7eb6176..88740d850643 100644 --- a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java @@ -149,6 +149,8 @@ public class PasspointConfigurationTest { PasspointConfiguration config = new PasspointConfiguration(); config.setUpdateIdentifier(1234); config.setHomeSp(createHomeSp()); + config.setAaaServerTrustedNames( + new String[] {"trusted.fqdn.com", "another-trusted.fqdn.com"}); config.setCredential(createCredential()); config.setPolicy(createPolicy()); config.setSubscriptionUpdate(createSubscriptionUpdate()); @@ -283,6 +285,19 @@ public class PasspointConfigurationTest { verifyParcel(config); } + /** + * Verify parcel read/write for a configuration that doesn't contain AAA server trusted names + * list. + * + * @throws Exception + */ + @Test + public void verifyParcelWithoutAaaServerTrustedNames() throws Exception { + PasspointConfiguration config = createConfig(); + config.setAaaServerTrustedNames(null); + verifyParcel(config); + } + /** * Verify that a default/empty configuration is invalid. * @@ -382,6 +397,21 @@ public class PasspointConfigurationTest { assertFalse(config.validateForR2()); } + /** + * Verify that a configuration without AAA server trusted names is valid for R1 and R2, + * since AAA server trusted names are optional for R1 and R2. + * + * @throws Exception + */ + @Test + public void validateConfigWithoutAaaServerTrustedNames() throws Exception { + PasspointConfiguration config = createConfig(); + config.setAaaServerTrustedNames(null); + + assertTrue(config.validate()); + assertTrue(config.validateForR2()); + } + /** * Verify that a configuration with a trust root certificate URL exceeding the max size * is invalid. diff --git a/wifi/tests/src/android/net/wifi/hotspot2/omadm/PpsMoParserTest.java b/wifi/tests/src/android/net/wifi/hotspot2/omadm/PpsMoParserTest.java index 66c595f92861..1ac9cb87c0e1 100644 --- a/wifi/tests/src/android/net/wifi/hotspot2/omadm/PpsMoParserTest.java +++ b/wifi/tests/src/android/net/wifi/hotspot2/omadm/PpsMoParserTest.java @@ -135,6 +135,9 @@ public class PpsMoParserTest { homeSp.setOtherHomePartners(new String[] {"other.fqdn.com"}); config.setHomeSp(homeSp); + config.setAaaServerTrustedNames( + new String[] {"trusted.fqdn.com", "another-trusted.fqdn.com"}); + // Credential configuration. Credential credential = new Credential(); credential.setCreationTimeInMillis(format.parse("2016-01-01T10:00:00Z").getTime()); -- cgit v1.2.3 From 29ffdcb6bbf5e01610cc61ceaf43f4910ee8e9fc Mon Sep 17 00:00:00 2001 From: xshu Date: Tue, 13 Aug 2019 16:52:52 -0700 Subject: [Mac rand] recording when the randomized mac is last changed Bug:137796328 Test: unit tests Change-Id: Ifc03c0a117675c61328d21dc0f413540b47ada89 --- wifi/java/android/net/wifi/WifiConfiguration.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index ed416429a279..f2ae44730973 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -1029,6 +1029,13 @@ public class WifiConfiguration implements Parcelable { @NonNull private MacAddress mRandomizedMacAddress; + /** + * @hide + * The wall clock time of when |mRandomizedMacAddress| last changed. + * Used to determine when we should re-randomize in aggressive mode. + */ + public long randomizedMacLastModifiedTimeMs = 0; + /** * @hide * Checks if the given MAC address can be used for Connected Mac Randomization @@ -1908,6 +1915,8 @@ public class WifiConfiguration implements Parcelable { } sbuf.append(" macRandomizationSetting: ").append(macRandomizationSetting).append("\n"); sbuf.append(" mRandomizedMacAddress: ").append(mRandomizedMacAddress).append("\n"); + sbuf.append(" randomizedMacLastModifiedTimeMs: ").append(randomizedMacLastModifiedTimeMs) + .append("\n"); sbuf.append(" KeyMgmt:"); for (int k = 0; k < this.allowedKeyManagement.size(); k++) { if (this.allowedKeyManagement.get(k)) { @@ -2429,6 +2438,7 @@ public class WifiConfiguration implements Parcelable { recentFailure.setAssociationStatus(source.recentFailure.getAssociationStatus()); mRandomizedMacAddress = source.mRandomizedMacAddress; macRandomizationSetting = source.macRandomizationSetting; + randomizedMacLastModifiedTimeMs = source.randomizedMacLastModifiedTimeMs; requirePMF = source.requirePMF; updateIdentifier = source.updateIdentifier; } @@ -2502,6 +2512,7 @@ public class WifiConfiguration implements Parcelable { dest.writeParcelable(mRandomizedMacAddress, flags); dest.writeInt(macRandomizationSetting); dest.writeInt(osu ? 1 : 0); + dest.writeLong(randomizedMacLastModifiedTimeMs); } /** Implement the Parcelable interface {@hide} */ @@ -2575,6 +2586,7 @@ public class WifiConfiguration implements Parcelable { config.mRandomizedMacAddress = in.readParcelable(null); config.macRandomizationSetting = in.readInt(); config.osu = in.readInt() != 0; + config.randomizedMacLastModifiedTimeMs = in.readLong(); return config; } -- cgit v1.2.3 From 8d91c0702860d82082415980c2c21af812dc9b10 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Wed, 24 Jul 2019 17:45:40 +0800 Subject: wifi: add SAE password identifier to WifiConfiguration Bug: 138305265 Test: atest FrameworksWifiApiTests Test: atest FrameworksWifiTests Test: connect to a WPA3 SAE access point with different password/identifer combinations. Change-Id: I1f26a5dbf5654ca2a6734f94eec547f33c349e9e --- wifi/java/android/net/wifi/WifiConfiguration.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index ed416429a279..35d85bb7159b 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -18,6 +18,7 @@ package android.net.wifi; import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; import android.content.pm.PackageManager; @@ -509,6 +510,12 @@ public class WifiConfiguration implements Parcelable { */ public String preSharedKey; + /** + * Optional SAE Password Id for use with WPA3-SAE. It is an ASCII string. + * @hide + */ + public @Nullable String saePasswordId; + /** * Four WEP keys. For each of the four values, provide either an ASCII * string enclosed in double quotation marks (e.g., {@code "abcdef"}), @@ -1995,6 +2002,9 @@ public class WifiConfiguration implements Parcelable { sbuf.append('*'); } + sbuf.append('\n').append(" SAE Password Id: "); + sbuf.append(this.saePasswordId); + sbuf.append("\nEnterprise config:\n"); sbuf.append(enterpriseConfig); @@ -2363,6 +2373,7 @@ public class WifiConfiguration implements Parcelable { providerFriendlyName = source.providerFriendlyName; isHomeProviderNetwork = source.isHomeProviderNetwork; preSharedKey = source.preSharedKey; + saePasswordId = source.saePasswordId; mNetworkSelectionStatus.copy(source.getNetworkSelectionStatus()); apBand = source.apBand; @@ -2452,6 +2463,7 @@ public class WifiConfiguration implements Parcelable { dest.writeLong(roamingConsortiumId); } dest.writeString(preSharedKey); + dest.writeString(saePasswordId); for (String wepKey : wepKeys) { dest.writeString(wepKey); } @@ -2526,6 +2538,7 @@ public class WifiConfiguration implements Parcelable { config.roamingConsortiumIds[i] = in.readLong(); } config.preSharedKey = in.readString(); + config.saePasswordId = in.readString(); for (int i = 0; i < config.wepKeys.length; i++) { config.wepKeys[i] = in.readString(); } @@ -2596,6 +2609,7 @@ public class WifiConfiguration implements Parcelable { out.writeInt(apBand); out.writeInt(apChannel); BackupUtils.writeString(out, preSharedKey); + BackupUtils.writeString(out, saePasswordId); out.writeInt(getAuthType()); out.writeBoolean(hiddenSSID); return baos.toByteArray(); @@ -2619,6 +2633,7 @@ public class WifiConfiguration implements Parcelable { config.apBand = in.readInt(); config.apChannel = in.readInt(); config.preSharedKey = BackupUtils.readString(in); + config.saePasswordId = BackupUtils.readString(in); config.allowedKeyManagement.set(in.readInt()); if (version >= 3) { config.hiddenSSID = in.readBoolean(); -- cgit v1.2.3 From 4d1699da48a37281f1429287065bda5c60d7ee7b Mon Sep 17 00:00:00 2001 From: Aurimas Liutikas Date: Wed, 28 Aug 2019 13:01:05 -0700 Subject: Add missing nullability annotations. To prepare for enabling MissingNullability Metalava check this CL works on adding missing nullability issues that metalava flags if we tell it to flag new things since API 29. This is not a complete CL, mostly addresses public api and toString/equals for @SystemApi Exempt-From-Owner-Approval: Large scale nullability clean up Bug: 124515653 Test: make -j checkapi Change-Id: I109260842cfc25f06e40694997fcbb4afa02c867 --- wifi/java/android/net/wifi/RttManager.java | 2 ++ wifi/java/android/net/wifi/WifiNetworkConnectionStatistics.java | 4 ++-- wifi/java/android/net/wifi/hotspot2/OsuProvider.java | 4 +++- wifi/java/android/net/wifi/rtt/RangingRequest.java | 3 ++- wifi/java/android/net/wifi/rtt/ResponderConfig.java | 3 ++- 5 files changed, 11 insertions(+), 5 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/RttManager.java b/wifi/java/android/net/wifi/RttManager.java index 6ce21216f753..6a03c73bc3f9 100644 --- a/wifi/java/android/net/wifi/RttManager.java +++ b/wifi/java/android/net/wifi/RttManager.java @@ -211,6 +211,7 @@ public class RttManager { /** Draft 11mc version supported, including major and minor version. e.g, draft 4.3 is 43 */ public int mcVersion; + @NonNull @Override public String toString() { StringBuffer sb = new StringBuffer(); @@ -1130,6 +1131,7 @@ public class RttManager { */ public int preamble; + @NonNull @Override public String toString() { StringBuilder builder = new StringBuilder(); diff --git a/wifi/java/android/net/wifi/WifiNetworkConnectionStatistics.java b/wifi/java/android/net/wifi/WifiNetworkConnectionStatistics.java index 8262a7a36c56..95b2e77c5c1e 100644 --- a/wifi/java/android/net/wifi/WifiNetworkConnectionStatistics.java +++ b/wifi/java/android/net/wifi/WifiNetworkConnectionStatistics.java @@ -16,8 +16,8 @@ package android.net.wifi; +import android.annotation.NonNull; import android.annotation.SystemApi; - import android.os.Parcel; import android.os.Parcelable; @@ -39,7 +39,7 @@ public class WifiNetworkConnectionStatistics implements Parcelable { public WifiNetworkConnectionStatistics() { } - + @NonNull @Override public String toString() { StringBuilder sbuf = new StringBuilder(); diff --git a/wifi/java/android/net/wifi/hotspot2/OsuProvider.java b/wifi/java/android/net/wifi/hotspot2/OsuProvider.java index 57dff9d761cb..a32bd547e1e2 100644 --- a/wifi/java/android/net/wifi/hotspot2/OsuProvider.java +++ b/wifi/java/android/net/wifi/hotspot2/OsuProvider.java @@ -16,6 +16,7 @@ package android.net.wifi.hotspot2; +import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.graphics.drawable.Icon; @@ -219,7 +220,7 @@ public final class OsuProvider implements Parcelable { } @Override - public boolean equals(Object thatObject) { + public boolean equals(@Nullable Object thatObject) { if (this == thatObject) { return true; } @@ -246,6 +247,7 @@ public final class OsuProvider implements Parcelable { mServerUri, mNetworkAccessIdentifier, mMethodList); } + @NonNull @Override public String toString() { return "OsuProvider{mOsuSsid=" + mOsuSsid diff --git a/wifi/java/android/net/wifi/rtt/RangingRequest.java b/wifi/java/android/net/wifi/rtt/RangingRequest.java index 70af03e56262..318efa61a110 100644 --- a/wifi/java/android/net/wifi/rtt/RangingRequest.java +++ b/wifi/java/android/net/wifi/rtt/RangingRequest.java @@ -17,6 +17,7 @@ package android.net.wifi.rtt; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.SystemApi; import android.net.MacAddress; import android.net.wifi.ScanResult; @@ -245,7 +246,7 @@ public final class RangingRequest implements Parcelable { } @Override - public boolean equals(Object o) { + public boolean equals(@Nullable Object o) { if (this == o) { return true; } diff --git a/wifi/java/android/net/wifi/rtt/ResponderConfig.java b/wifi/java/android/net/wifi/rtt/ResponderConfig.java index e6ae48344afc..64dfc3499aaf 100644 --- a/wifi/java/android/net/wifi/rtt/ResponderConfig.java +++ b/wifi/java/android/net/wifi/rtt/ResponderConfig.java @@ -21,6 +21,7 @@ import static android.net.wifi.ScanResult.InformationElement.EID_VHT_CAPABILITIE import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.SystemApi; import android.net.MacAddress; import android.net.wifi.ScanResult; @@ -443,7 +444,7 @@ public final class ResponderConfig implements Parcelable { }; @Override - public boolean equals(Object o) { + public boolean equals(@Nullable Object o) { if (this == o) { return true; } -- cgit v1.2.3 From bc0f7cb100e6d1920f6c866768c5188b8cf69653 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Wed, 28 Aug 2019 07:20:07 -0700 Subject: WifiManager: Ignore void API calls with default values When wifi service is not yet up, we throw a remote exception for API calls which have void return. Change this to only throw a remote exception when the input params have non-default values. This takes care of cases where some other system modules resets wifi params as a part of their initialization sequence (which will already be the value when the wifi service comes up, so the calls are not useful) Bug: 140076130 Bug: 139897982 Test: atest WifiManagerTest Change-Id: If24d5ae52f1d39d2d99a860f3dc6c5f1860fd656 --- wifi/java/android/net/wifi/WifiManager.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 6bf7bfb9b4a1..a37de00ce7de 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -52,12 +52,14 @@ 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; @@ -1821,6 +1823,7 @@ public class WifiManager { try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) { + if (config == null) return; throw new RemoteException("Wifi service is not running"); } if (!iWifiManager.addOrUpdatePasspointConfiguration( @@ -1849,6 +1852,7 @@ public class WifiManager { try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) { + if (TextUtils.isEmpty(fqdn)) return; throw new RemoteException("Wifi service is not running"); } if (!iWifiManager.removePasspointConfiguration( @@ -1899,6 +1903,7 @@ public class WifiManager { try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) { + if (bssid == 0L || TextUtils.isEmpty(fileName)) return; throw new RemoteException("Wifi service is not running"); } iWifiManager.queryPasspointIcon(bssid, fileName); @@ -1928,6 +1933,8 @@ public class WifiManager { * @param holdoff hold off time in milliseconds * @param ess set if the hold off pertains to an ESS rather than a BSS * @hide + * + * TODO (140167680): This needs to be removed, the implementation is empty! */ public void deauthenticateNetwork(long holdoff, boolean ess) { try { @@ -2504,6 +2511,7 @@ public class WifiManager { try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) { + if (TextUtils.isEmpty(country)) return; throw new RemoteException("Wifi service is not running"); } iWifiManager.setCountryCode(country); @@ -2692,6 +2700,7 @@ public class WifiManager { try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) { + if (TextUtils.isEmpty(ifaceName) || mode == IFACE_IP_MODE_UNSPECIFIED) return; throw new RemoteException("Wifi service is not running"); } iWifiManager.updateInterfaceIpState(ifaceName, mode); @@ -3044,6 +3053,7 @@ public class WifiManager { try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) { + if (remoteIPAddress == null || !enable) return; throw new RemoteException("Wifi service is not running"); } iWifiManager.enableTdls(remoteIPAddress.getHostAddress(), enable); @@ -3062,6 +3072,7 @@ public class WifiManager { try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) { + if (TextUtils.isEmpty(remoteMacAddress) || !enable) return; throw new RemoteException("Wifi service is not running"); } iWifiManager.enableTdlsWithMacAddress(remoteMacAddress, enable); @@ -3956,7 +3967,7 @@ public class WifiManager { android.Manifest.permission.NETWORK_STACK }) public void disableEphemeralNetwork(String SSID) { - if (SSID == null) throw new IllegalArgumentException("SSID cannot be null"); + if (TextUtils.isEmpty(SSID)) throw new IllegalArgumentException("SSID cannot be null"); try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) { @@ -4495,6 +4506,7 @@ public class WifiManager { try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) { + if (verbose == 0) return; throw new RemoteException("Wifi service is not running"); } iWifiManager.enableVerboseLogging(verbose); @@ -4581,6 +4593,7 @@ public class WifiManager { try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) { + if (enabled) return; throw new RemoteException("Wifi service is not running"); } iWifiManager.enableWifiConnectivityManager(enabled); @@ -4611,6 +4624,7 @@ public class WifiManager { try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) { + if (ArrayUtils.isEmpty(data)) return; throw new RemoteException("Wifi service is not running"); } iWifiManager.restoreBackupData(data); @@ -4631,6 +4645,7 @@ public class WifiManager { try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) { + if (ArrayUtils.isEmpty(supplicantData) && ArrayUtils.isEmpty(ipConfigData)) return; throw new RemoteException("Wifi service is not running"); } iWifiManager.restoreSupplicantBackupData(supplicantData, ipConfigData); @@ -4937,6 +4952,7 @@ public class WifiManager { try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) { + if (state == DEVICE_MOBILITY_STATE_UNKNOWN) return; throw new RemoteException("Wifi service is not running"); } iWifiManager.setDeviceMobilityState(state); -- cgit v1.2.3 From 79385151525c4d4f3108e4fd906de8f9303c0772 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Thu, 17 Jan 2019 11:40:24 -0800 Subject: ocsp: add OCSP field in WifiEnterpriseConfig Bug: 136720092 Test: atest FrameworksWifiApiTests Test: tested with OCSP supported profile Change-Id: I0095a235792997fda54a2f68af48819caf3deef1 --- .../android/net/wifi/WifiEnterpriseConfig.java | 73 ++++++++++++++++++++++ .../android/net/wifi/WifiEnterpriseConfigTest.java | 34 ++++++++++ 2 files changed, 107 insertions(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java index 9d4b837ce2d1..f8c20111d79b 100644 --- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java +++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java @@ -15,6 +15,7 @@ */ package android.net.wifi; +import android.annotation.IntDef; import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; import android.os.Parcel; @@ -23,6 +24,8 @@ import android.security.Credentials; import android.text.TextUtils; import android.util.Log; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.nio.charset.StandardCharsets; import java.security.PrivateKey; import java.security.cert.X509Certificate; @@ -111,6 +114,48 @@ public class WifiEnterpriseConfig implements Parcelable { /** @hide */ public static final String CA_CERT_ALIAS_DELIMITER = " "; + /** + * Do not use OCSP stapling (TLS certificate status extension) + * @hide + */ + public static final int OCSP_NONE = 0; + + /** + * Try to use OCSP stapling, but not require response + * @hide + */ + public static final int OCSP_REQUEST_CERT_STATUS = 1; + + /** + * Require valid OCSP stapling response + * @hide + */ + public static final int OCSP_REQUIRE_CERT_STATUS = 2; + + /** + * Require valid OCSP stapling response for all not-trusted certificates in the server + * certificate chain + * @hide + */ + public static final int OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS = 3; + + /** @hide */ + @IntDef(prefix = {"OCSP_"}, value = { + OCSP_NONE, + OCSP_REQUEST_CERT_STATUS, + OCSP_REQUIRE_CERT_STATUS, + OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS + }) + @Retention(RetentionPolicy.SOURCE) + public @interface Ocsp { + } + + /** + * Whether to use/require OCSP (Online Certificate Status Protocol) to check server certificate. + * @hide + */ + private @Ocsp int mOcsp = OCSP_NONE; + // Fields to copy verbatim from wpa_supplicant. private static final String[] SUPPLICANT_CONFIG_KEYS = new String[] { IDENTITY_KEY, @@ -185,6 +230,7 @@ public class WifiEnterpriseConfig implements Parcelable { mPhase2Method = source.mPhase2Method; mIsAppInstalledDeviceKeyAndCert = source.mIsAppInstalledDeviceKeyAndCert; mIsAppInstalledCaCert = source.mIsAppInstalledCaCert; + mOcsp = source.mOcsp; } /** @@ -230,6 +276,7 @@ public class WifiEnterpriseConfig implements Parcelable { ParcelUtil.writeCertificates(dest, mClientCertificateChain); dest.writeBoolean(mIsAppInstalledDeviceKeyAndCert); dest.writeBoolean(mIsAppInstalledCaCert); + dest.writeInt(mOcsp); } public static final @android.annotation.NonNull Creator CREATOR = @@ -251,6 +298,7 @@ public class WifiEnterpriseConfig implements Parcelable { enterpriseConfig.mClientCertificateChain = ParcelUtil.readCertificates(in); enterpriseConfig.mIsAppInstalledDeviceKeyAndCert = in.readBoolean(); enterpriseConfig.mIsAppInstalledCaCert = in.readBoolean(); + enterpriseConfig.mOcsp = in.readInt(); return enterpriseConfig; } @@ -1141,6 +1189,7 @@ public class WifiEnterpriseConfig implements Parcelable { if (mPhase2Method > 0 && mPhase2Method < Phase2.strings.length) { sb.append("phase2_method: ").append(Phase2.strings[mPhase2Method]).append("\n"); } + sb.append(" ocsp: ").append(mOcsp).append("\n"); return sb.toString(); } @@ -1190,4 +1239,28 @@ public class WifiEnterpriseConfig implements Parcelable { public boolean isAppInstalledCaCert() { return mIsAppInstalledCaCert; } + + /** + * Set the ocsp type. + * @param ocsp is one {@link ##OCSP_NONE}, {@link #OCSP_REQUEST_CERT_STATUS}, + * {@link #OCSP_REQUIRE_CERT_STATUS} or + * {@link #OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS} + * @hide + */ + public void setOcsp(@Ocsp int ocsp) { + if (ocsp >= OCSP_NONE && ocsp <= OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS) { + mOcsp = ocsp; + } else { + throw new IllegalArgumentException("Invalid OCSP type."); + } + } + + /** + * Get the ocsp type. + * @return ocsp type + * @hide + */ + public @Ocsp int getOcsp() { + return mOcsp; + } } diff --git a/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java b/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java index beed6666f28f..d8db4ceb6e9c 100644 --- a/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java +++ b/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java @@ -23,6 +23,7 @@ import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import android.net.wifi.WifiEnterpriseConfig.Eap; import android.net.wifi.WifiEnterpriseConfig.Phase2; @@ -343,11 +344,13 @@ public class WifiEnterpriseConfigTest { enterpriseConfig.setPassword("*"); enterpriseConfig.setEapMethod(Eap.TTLS); enterpriseConfig.setPhase2Method(Phase2.GTC); + enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS); mEnterpriseConfig = new WifiEnterpriseConfig(); mEnterpriseConfig.copyFromExternal(enterpriseConfig, "*"); assertEquals("TTLS", getSupplicantEapMethod()); assertEquals("\"autheap=GTC\"", getSupplicantPhase2Method()); assertNotEquals("*", mEnterpriseConfig.getPassword()); + assertEquals(enterpriseConfig.getOcsp(), mEnterpriseConfig.getOcsp()); } /** Verfies that parceling a WifiEnterpriseConfig preseves method information. */ @@ -487,4 +490,35 @@ public class WifiEnterpriseConfigTest { assertFalse(mEnterpriseConfig.isAppInstalledDeviceKeyAndCert()); assertTrue(mEnterpriseConfig.isAppInstalledCaCert()); } + + /** Verifies that OCSP value is set correctly. */ + @Test + public void testOcspSetGet() throws Exception { + WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); + + enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_NONE); + assertEquals(WifiEnterpriseConfig.OCSP_NONE, enterpriseConfig.getOcsp()); + + enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS); + assertEquals(WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS, enterpriseConfig.getOcsp()); + + enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_REQUEST_CERT_STATUS); + assertEquals(WifiEnterpriseConfig.OCSP_REQUEST_CERT_STATUS, enterpriseConfig.getOcsp()); + + enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS); + assertEquals(WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS, + enterpriseConfig.getOcsp()); + } + + /** Verifies that an exception is thrown when invalid OCSP is set. */ + @Test + public void testInvalidOcspValue() { + WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); + try { + enterpriseConfig.setOcsp(-1); + fail("Should raise an IllegalArgumentException here."); + } catch (IllegalArgumentException e) { + // expected exception. + } + } } -- cgit v1.2.3 From 999d26c6181747c8cf1151bb0729d4b4a31886da Mon Sep 17 00:00:00 2001 From: Nate Jiang Date: Mon, 9 Sep 2019 16:17:44 -0700 Subject: [NetworkSuggestion] allow apps in-place modify suggestion Changing the comments. Bug: 138447131 Test: atest android.net.wifi Test: atest com.android.server.wifi Change-Id: Ia02033a53ba67f3cf5106a8c4996c3d24a65672a --- wifi/java/android/net/wifi/WifiManager.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index a37de00ce7de..0fa0ec7afd91 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1732,13 +1732,12 @@ public class WifiManager { *

  • When an app is uninstalled, all its suggested networks are discarded. If the device is * currently connected to a suggested network which is being removed then the device will * disconnect from that network.
  • - *
  • No in-place modification of existing suggestions are allowed. Apps are expected to - * remove suggestions using {@link #removeNetworkSuggestions(List)} and then add the modified - * suggestion back using this API.
  • + *
  • In-place modification of existing suggestions are allowed. + * If the provided suggestions {@link WifiNetworkSuggestion#equals(Object)} any previously + * provided suggestions by the app. Previous suggestions will be updated
  • * * @param networkSuggestions List of network suggestions provided by the app. * @return Status code for the operation. One of the STATUS_NETWORK_SUGGESTIONS_ values. - * {@link WifiNetworkSuggestion#equals(Object)} any previously provided suggestions by the app. * @throws {@link SecurityException} if the caller is missing required permissions. */ @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) -- cgit v1.2.3 From 641a6834bac2435934256cc22c2b8c90c38ad7ec Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Mon, 9 Sep 2019 10:53:20 -0700 Subject: WifiManager: Remove async channel usage Changes: a) Migrate existing async channel methods to tracked binder calls. b) Migrate existing async channel responses to tracked binder callbacks. c) Deprecate WifiManager.disable() (Use public WifiManager.disableNetwork() instead). Don't see any external users of this API. d) Removed unnecessary RssiPacketInfo class (only the total pkt count is necessary in the public API, so remove this class and only pass the total count in the callback). Bug: 130039719 Test: atest android.net.wifi Test: Manual tests a) Able to connect to networks from settings. b) Able to remove network from setttings. Change-Id: Ie82a9fce2f9e32e48a2da77477893427863fb460 --- wifi/java/android/net/wifi/IActionListener.aidl | 27 ++ .../android/net/wifi/ITxPacketCountListener.aidl | 27 ++ wifi/java/android/net/wifi/IWifiManager.aidl | 12 +- .../java/android/net/wifi/RssiPacketCountInfo.java | 75 ---- wifi/java/android/net/wifi/WifiManager.java | 385 ++++++++------------- .../com/android/server/wifi/BaseWifiService.java | 28 +- .../src/android/net/wifi/WifiManagerTest.java | 95 +++++ 7 files changed, 337 insertions(+), 312 deletions(-) create mode 100644 wifi/java/android/net/wifi/IActionListener.aidl create mode 100644 wifi/java/android/net/wifi/ITxPacketCountListener.aidl delete mode 100644 wifi/java/android/net/wifi/RssiPacketCountInfo.java (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IActionListener.aidl b/wifi/java/android/net/wifi/IActionListener.aidl new file mode 100644 index 000000000000..faa0901cb087 --- /dev/null +++ b/wifi/java/android/net/wifi/IActionListener.aidl @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi; + +/** + * Interface for generic wifi callbacks. + * @hide + */ +oneway interface IActionListener +{ + void onSuccess(); + void onFailure(int reason); +} diff --git a/wifi/java/android/net/wifi/ITxPacketCountListener.aidl b/wifi/java/android/net/wifi/ITxPacketCountListener.aidl new file mode 100644 index 000000000000..8606ab5afa9c --- /dev/null +++ b/wifi/java/android/net/wifi/ITxPacketCountListener.aidl @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi; + +/** + * Interface for tx packet counter callback. + * @hide + */ +oneway interface ITxPacketCountListener +{ + void onSuccess(int count); + void onFailure(int reason); +} diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 931e5dd7405f..c755c0f00469 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -24,10 +24,12 @@ import android.net.wifi.hotspot2.IProvisioningCallback; import android.net.DhcpInfo; import android.net.Network; +import android.net.wifi.IActionListener; import android.net.wifi.IDppCallback; import android.net.wifi.INetworkRequestMatchCallback; import android.net.wifi.ISoftApCallback; import android.net.wifi.ITrafficStateCallback; +import android.net.wifi.ITxPacketCountListener; import android.net.wifi.IOnWifiUsabilityStatsListener; import android.net.wifi.ScanResult; import android.net.wifi.WifiActivityEnergyInfo; @@ -156,8 +158,6 @@ interface IWifiManager void notifyUserOfApBandConversion(String packageName); - Messenger getWifiServiceMessenger(String packageName); - void enableTdls(String remoteIPAddress, boolean enable); void enableTdlsWithMacAddress(String remoteMacAddress, boolean enable); @@ -220,4 +220,12 @@ interface IWifiManager void stopDppSession(); void updateWifiUsabilityScore(int seqNum, int score, int predictionHorizonSec); + + oneway void connect(in WifiConfiguration config, int netId, in IBinder binder, in IActionListener listener, int callbackIdentifier); + + oneway void save(in WifiConfiguration config, in IBinder binder, in IActionListener listener, int callbackIdentifier); + + oneway void forget(int netId, in IBinder binder, in IActionListener listener, int callbackIdentifier); + + oneway void getTxPacketCount(String packageName, in IBinder binder, in ITxPacketCountListener listener, int callbackIdentifier); } diff --git a/wifi/java/android/net/wifi/RssiPacketCountInfo.java b/wifi/java/android/net/wifi/RssiPacketCountInfo.java deleted file mode 100644 index 4301165308d1..000000000000 --- a/wifi/java/android/net/wifi/RssiPacketCountInfo.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.wifi; - -import android.os.Parcel; -import android.os.Parcelable; - -/** - * Bundle of RSSI and packet count information, for WiFi watchdog - * - * @see WifiWatchdogStateMachine - * - * @hide - */ -public class RssiPacketCountInfo implements Parcelable { - - public int rssi; - - public int txgood; - - public int txbad; - - public int rxgood; - - public RssiPacketCountInfo() { - rssi = txgood = txbad = rxgood = 0; - } - - private RssiPacketCountInfo(Parcel in) { - rssi = in.readInt(); - txgood = in.readInt(); - txbad = in.readInt(); - rxgood = in.readInt(); - } - - @Override - public void writeToParcel(Parcel out, int flags) { - out.writeInt(rssi); - out.writeInt(txgood); - out.writeInt(txbad); - out.writeInt(rxgood); - } - - @Override - public int describeContents() { - return 0; - } - - public static final @android.annotation.NonNull Parcelable.Creator CREATOR = - new Parcelable.Creator() { - @Override - public RssiPacketCountInfo createFromParcel(Parcel in) { - return new RssiPacketCountInfo(in); - } - - @Override - public RssiPacketCountInfo[] newArray(int size) { - return new RssiPacketCountInfo[size]; - } - }; -} diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 0fa0ec7afd91..61cad4827344 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -55,13 +55,10 @@ import android.os.WorkSource; import android.text.TextUtils; import android.util.Log; import android.util.Pair; -import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; -import com.android.internal.util.AsyncChannel; -import com.android.internal.util.Protocol; import com.android.server.net.NetworkPinner; import dalvik.system.CloseGuard; @@ -75,7 +72,6 @@ import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; /** @@ -1128,13 +1124,6 @@ public class WifiManager { IWifiManager mService; private final int mTargetSdkVersion; - private static final int INVALID_KEY = 0; - private int mListenerKey = 1; - private final SparseArray mListenerMap = new SparseArray(); - private final Object mListenerMapLock = new Object(); - - private AsyncChannel mAsyncChannel; - private CountDownLatch mConnected; private Looper mLooper; private boolean mVerboseLoggingEnabled = false; @@ -2644,8 +2633,23 @@ public class WifiManager { * * @hide for CTS test only */ - public void getTxPacketCount(TxPacketCountListener listener) { - getChannel().sendMessage(RSSI_PKTCNT_FETCH, 0, putListener(listener)); + public void getTxPacketCount(@NonNull TxPacketCountListener listener) { + if (listener == null) throw new IllegalArgumentException("listener cannot be null"); + Binder binder = new Binder(); + TxPacketCountListenerProxy listenerProxy = + new TxPacketCountListenerProxy(mLooper, listener); + try { + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.getTxPacketCount(mContext.getOpPackageName(), binder, listenerProxy, + listener.hashCode()); + } catch (RemoteException e) { + listenerProxy.onFailure(ERROR); + } catch (SecurityException e) { + listenerProxy.onFailure(NOT_AUTHORIZED); + } } /** @@ -3080,76 +3084,6 @@ public class WifiManager { } } - /* TODO: deprecate synchronous API and open up the following API */ - - private static final int BASE = Protocol.BASE_WIFI_MANAGER; - - /* Commands to WifiService */ - /** @hide */ - public static final int CONNECT_NETWORK = BASE + 1; - /** @hide */ - public static final int CONNECT_NETWORK_FAILED = BASE + 2; - /** @hide */ - public static final int CONNECT_NETWORK_SUCCEEDED = BASE + 3; - - /** @hide */ - public static final int FORGET_NETWORK = BASE + 4; - /** @hide */ - public static final int FORGET_NETWORK_FAILED = BASE + 5; - /** @hide */ - public static final int FORGET_NETWORK_SUCCEEDED = BASE + 6; - - /** @hide */ - public static final int SAVE_NETWORK = BASE + 7; - /** @hide */ - public static final int SAVE_NETWORK_FAILED = BASE + 8; - /** @hide */ - public static final int SAVE_NETWORK_SUCCEEDED = BASE + 9; - - /** @hide - * @deprecated This is deprecated - */ - public static final int START_WPS = BASE + 10; - /** @hide - * @deprecated This is deprecated - */ - public static final int START_WPS_SUCCEEDED = BASE + 11; - /** @hide - * @deprecated This is deprecated - */ - public static final int WPS_FAILED = BASE + 12; - /** @hide - * @deprecated This is deprecated - */ - public static final int WPS_COMPLETED = BASE + 13; - - /** @hide - * @deprecated This is deprecated - */ - public static final int CANCEL_WPS = BASE + 14; - /** @hide - * @deprecated This is deprecated - */ - public static final int CANCEL_WPS_FAILED = BASE + 15; - /** @hide - * @deprecated This is deprecated - */ - public static final int CANCEL_WPS_SUCCEDED = BASE + 16; - - /** @hide */ - public static final int DISABLE_NETWORK = BASE + 17; - /** @hide */ - public static final int DISABLE_NETWORK_FAILED = BASE + 18; - /** @hide */ - public static final int DISABLE_NETWORK_SUCCEEDED = BASE + 19; - - /** @hide */ - public static final int RSSI_PKTCNT_FETCH = BASE + 20; - /** @hide */ - public static final int RSSI_PKTCNT_FETCH_SUCCEEDED = BASE + 21; - /** @hide */ - public static final int RSSI_PKTCNT_FETCH_FAILED = BASE + 22; - /** * Passed with {@link ActionListener#onFailure}. * Indicates that the operation failed due to an internal error. @@ -3172,6 +3106,11 @@ public class WifiManager { */ public static final int BUSY = 2; + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({ERROR, IN_PROGRESS, BUSY}) + public @interface ActionListenerFailureReason {} + /* WPS specific errors */ /** WPS overlap detected * @deprecated This is deprecated @@ -3216,20 +3155,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 @@ -3273,6 +3205,41 @@ public class WifiManager { public void onFailure(int reason); } + /** + * Callback proxy for TxPacketCountListener objects. + * + * @hide + */ + private class TxPacketCountListenerProxy extends ITxPacketCountListener.Stub { + private final Handler mHandler; + private final TxPacketCountListener mCallback; + + TxPacketCountListenerProxy(Looper looper, TxPacketCountListener callback) { + mHandler = new Handler(looper); + mCallback = callback; + } + + @Override + public void onSuccess(int count) { + if (mVerboseLoggingEnabled) { + Log.v(TAG, "TxPacketCounterProxy: onSuccess: count=" + count); + } + mHandler.post(() -> { + mCallback.onSuccess(count); + }); + } + + @Override + public void onFailure(int reason) { + if (mVerboseLoggingEnabled) { + Log.v(TAG, "TxPacketCounterProxy: onFailure: reason=" + reason); + } + mHandler.post(() -> { + mCallback.onFailure(reason); + }); + } + } + /** * Base class for soft AP callback. Should be extended by applications and set when calling * {@link WifiManager#registerSoftApCallback(SoftApCallback, Handler)}. @@ -3707,125 +3674,61 @@ public class WifiManager { } } - // Ensure that multiple ServiceHandler threads do not interleave message dispatch. - private static final Object sServiceHandlerDispatchLock = new Object(); + /** + * Callback proxy for ActionListener objects. + */ + private class ActionListenerProxy extends IActionListener.Stub { + private final String mActionTag; + private final Handler mHandler; + private final ActionListener mCallback; - private class ServiceHandler extends Handler { - ServiceHandler(Looper looper) { - super(looper); + ActionListenerProxy(String actionTag, Looper looper, ActionListener callback) { + mActionTag = actionTag; + mHandler = new Handler(looper); + mCallback = callback; } @Override - public void handleMessage(Message message) { - synchronized (sServiceHandlerDispatchLock) { - dispatchMessageToListeners(message); + public void onSuccess() { + if (mVerboseLoggingEnabled) { + Log.v(TAG, "ActionListenerProxy:" + mActionTag + ": onSuccess"); } + mHandler.post(() -> { + mCallback.onSuccess(); + }); } - private void dispatchMessageToListeners(Message message) { - Object listener = removeListener(message.arg2); - switch (message.what) { - case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: - if (message.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { - mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); - } else { - Log.e(TAG, "Failed to set up channel connection"); - // This will cause all further async API calls on the WifiManager - // to fail and throw an exception - mAsyncChannel = null; - } - mConnected.countDown(); - break; - case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED: - // Ignore - break; - case AsyncChannel.CMD_CHANNEL_DISCONNECTED: - Log.e(TAG, "Channel connection lost"); - // This will cause all further async API calls on the WifiManager - // to fail and throw an exception - mAsyncChannel = null; - getLooper().quit(); - break; - /* ActionListeners grouped together */ - case WifiManager.CONNECT_NETWORK_FAILED: - case WifiManager.FORGET_NETWORK_FAILED: - case WifiManager.SAVE_NETWORK_FAILED: - case WifiManager.DISABLE_NETWORK_FAILED: - if (listener != null) { - ((ActionListener) listener).onFailure(message.arg1); - } - break; - /* ActionListeners grouped together */ - case WifiManager.CONNECT_NETWORK_SUCCEEDED: - case WifiManager.FORGET_NETWORK_SUCCEEDED: - case WifiManager.SAVE_NETWORK_SUCCEEDED: - case WifiManager.DISABLE_NETWORK_SUCCEEDED: - if (listener != null) { - ((ActionListener) listener).onSuccess(); - } - break; - case WifiManager.RSSI_PKTCNT_FETCH_SUCCEEDED: - if (listener != null) { - RssiPacketCountInfo info = (RssiPacketCountInfo) message.obj; - if (info != null) - ((TxPacketCountListener) listener).onSuccess(info.txgood + info.txbad); - else - ((TxPacketCountListener) listener).onFailure(ERROR); - } - break; - case WifiManager.RSSI_PKTCNT_FETCH_FAILED: - if (listener != null) { - ((TxPacketCountListener) listener).onFailure(message.arg1); - } - break; - default: - //ignore - break; + @Override + public void onFailure(@ActionListenerFailureReason int reason) { + if (mVerboseLoggingEnabled) { + Log.v(TAG, "ActionListenerProxy:" + mActionTag + ": onFailure=" + reason); } + mHandler.post(() -> { + mCallback.onFailure(reason); + }); } } - private int putListener(Object listener) { - if (listener == null) return INVALID_KEY; - int key; - synchronized (mListenerMapLock) { - do { - key = mListenerKey++; - } while (key == INVALID_KEY); - mListenerMap.put(key, listener); - } - return key; - } - - private Object removeListener(int key) { - if (key == INVALID_KEY) return null; - synchronized (mListenerMapLock) { - Object listener = mListenerMap.get(key); - mListenerMap.remove(key); - return listener; + private void connectInternal(@Nullable WifiConfiguration config, int networkId, + @Nullable ActionListener listener) { + ActionListenerProxy listenerProxy = null; + Binder binder = null; + if (listener != null) { + listenerProxy = new ActionListenerProxy("connect", mLooper, listener); + binder = new Binder(); } - } - - private synchronized AsyncChannel getChannel() { - if (mAsyncChannel == null) { - Messenger messenger = getWifiServiceMessenger(); - if (messenger == null) { - throw new IllegalStateException( - "getWifiServiceMessenger() returned null! This is invalid."); - } - - mAsyncChannel = new AsyncChannel(); - mConnected = new CountDownLatch(1); - - Handler handler = new ServiceHandler(mLooper); - mAsyncChannel.connect(mContext, handler, messenger); - try { - mConnected.await(); - } catch (InterruptedException e) { - Log.e(TAG, "interrupted wait at init"); + try { + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); } + iWifiManager.connect(config, networkId, binder, listenerProxy, + listener == null ? 0 : listener.hashCode()); + } catch (RemoteException e) { + if (listenerProxy != null) listenerProxy.onFailure(ERROR); + } catch (SecurityException e) { + if (listenerProxy != null) listenerProxy.onFailure(NOT_AUTHORIZED); } - return mAsyncChannel; } /** @@ -3851,10 +3754,7 @@ public class WifiManager { }) public void connect(@NonNull WifiConfiguration config, @Nullable ActionListener listener) { if (config == null) throw new IllegalArgumentException("config cannot be null"); - // Use INVALID_NETWORK_ID for arg1 when passing a config object - // arg1 is used to pass network id when the network already exists - getChannel().sendMessage(CONNECT_NETWORK, WifiConfiguration.INVALID_NETWORK_ID, - putListener(listener), config); + connectInternal(config, WifiConfiguration.INVALID_NETWORK_ID, listener); } /** @@ -3877,7 +3777,7 @@ public class WifiManager { }) public void connect(int networkId, @Nullable ActionListener listener) { if (networkId < 0) throw new IllegalArgumentException("Network id cannot be negative"); - getChannel().sendMessage(CONNECT_NETWORK, networkId, putListener(listener)); + connectInternal(null, networkId, listener); } /** @@ -3908,7 +3808,24 @@ public class WifiManager { }) public void save(@NonNull WifiConfiguration config, @Nullable ActionListener listener) { if (config == null) throw new IllegalArgumentException("config cannot be null"); - getChannel().sendMessage(SAVE_NETWORK, 0, putListener(listener), config); + ActionListenerProxy listenerProxy = null; + Binder binder = null; + if (listener != null) { + listenerProxy = new ActionListenerProxy("save", mLooper, listener); + binder = new Binder(); + } + try { + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.save(config, binder, listenerProxy, + listener == null ? 0 : listener.hashCode()); + } catch (RemoteException e) { + if (listenerProxy != null) listenerProxy.onFailure(ERROR); + } catch (SecurityException e) { + if (listenerProxy != null) listenerProxy.onFailure(NOT_AUTHORIZED); + } } /** @@ -3932,7 +3849,24 @@ public class WifiManager { }) public void forget(int netId, @Nullable ActionListener listener) { if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative"); - getChannel().sendMessage(FORGET_NETWORK, netId, putListener(listener)); + ActionListenerProxy listenerProxy = null; + Binder binder = null; + if (listener != null) { + listenerProxy = new ActionListenerProxy("forget", mLooper, listener); + binder = new Binder(); + } + try { + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.forget(netId, binder, listenerProxy, + listener == null ? 0 : listener.hashCode()); + } catch (RemoteException e) { + if (listenerProxy != null) listenerProxy.onFailure(ERROR); + } catch (SecurityException e) { + if (listenerProxy != null) listenerProxy.onFailure(NOT_AUTHORIZED); + } } /** @@ -3942,6 +3876,7 @@ public class WifiManager { * @param listener for callbacks on success or failure. Can be null. * @throws IllegalStateException if the WifiManager instance needs to be * initialized again + * @deprecated This API is deprecated. Use {@link #disableNetwork(int)} instead. * @hide */ @SystemApi @@ -3950,9 +3885,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); + } + } } /** @@ -4007,24 +3952,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. @@ -4485,16 +4412,6 @@ public class WifiManager { } } - protected void finalize() throws Throwable { - try { - if (mAsyncChannel != null) { - mAsyncChannel.disconnect(); - } - } finally { - super.finalize(); - } - } - /** * Set wifi verbose log. Called from developer settings. * @hide diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index bc06e7de8502..032a13ec826d 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -21,11 +21,13 @@ package com.android.server.wifi; import android.content.pm.ParceledListSlice; import android.net.DhcpInfo; import android.net.Network; +import android.net.wifi.IActionListener; import android.net.wifi.IDppCallback; import android.net.wifi.INetworkRequestMatchCallback; import android.net.wifi.IOnWifiUsabilityStatsListener; import android.net.wifi.ISoftApCallback; import android.net.wifi.ITrafficStateCallback; +import android.net.wifi.ITxPacketCountListener; import android.net.wifi.IWifiManager; import android.net.wifi.ScanResult; import android.net.wifi.WifiActivityEnergyInfo; @@ -323,7 +325,7 @@ public class BaseWifiService extends IWifiManager.Stub { throw new UnsupportedOperationException(); } - @Override + /** @removed */ public Messenger getWifiServiceMessenger(String packageName) { throw new UnsupportedOperationException(); } @@ -486,4 +488,28 @@ public class BaseWifiService extends IWifiManager.Stub { public void updateWifiUsabilityScore(int seqNum, int score, int predictionHorizonSec) { throw new UnsupportedOperationException(); } + + @Override + public void connect(WifiConfiguration config, int netId, IBinder binder, + IActionListener callback, int callbackIdentifier) { + throw new UnsupportedOperationException(); + } + + @Override + public void save(WifiConfiguration config, IBinder binder, IActionListener callback, + int callbackIdentifier) { + throw new UnsupportedOperationException(); + } + + @Override + public void forget(int netId, IBinder binder, IActionListener callback, + int callbackIdentifier) { + throw new UnsupportedOperationException(); + } + + @Override + public void getTxPacketCount(String packageName, IBinder binder, + ITxPacketCountListener callback, int callbackIdentifier) { + throw new UnsupportedOperationException(); + } } diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index e478f3830c0a..8beee5708f1d 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -64,11 +64,13 @@ import android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback; import android.net.wifi.WifiManager.OnWifiUsabilityStatsListener; import android.net.wifi.WifiManager.SoftApCallback; import android.net.wifi.WifiManager.TrafficStateCallback; +import android.os.Binder; import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.os.Messenger; +import android.os.RemoteException; import android.os.test.TestLooper; import androidx.test.filters.SmallTest; @@ -1646,4 +1648,97 @@ i * Verify that a call to cancel WPS immediately returns a failure. assertTrue(mWifiManager.setWifiEnabled(false)); verify(mWifiService).setWifiEnabled(mContext.getOpPackageName(), false); } + + /** + * Test behavior of {@link WifiManager#connect(int, WifiManager.ActionListener)} + */ + @Test + public void testConnectWithListener() throws Exception { + WifiManager.ActionListener externalListener = mock(WifiManager.ActionListener.class); + mWifiManager.connect(TEST_NETWORK_ID, externalListener); + + ArgumentCaptor binderListenerCaptor = + ArgumentCaptor.forClass(IActionListener.class); + verify(mWifiService).connect(eq(null), eq(TEST_NETWORK_ID), any(Binder.class), + binderListenerCaptor.capture(), anyInt()); + assertNotNull(binderListenerCaptor.getValue()); + + // Trigger on success. + binderListenerCaptor.getValue().onSuccess(); + mLooper.dispatchAll(); + verify(externalListener).onSuccess(); + + // Trigger on failure. + binderListenerCaptor.getValue().onFailure(WifiManager.BUSY); + mLooper.dispatchAll(); + verify(externalListener).onFailure(WifiManager.BUSY); + } + + /** + * Test behavior of {@link WifiManager#connect(int, WifiManager.ActionListener)} + */ + @Test + public void testConnectWithListenerHandleSecurityException() throws Exception { + doThrow(new SecurityException()).when(mWifiService) + .connect(eq(null), anyInt(), any(IBinder.class), + any(IActionListener.class), anyInt()); + WifiManager.ActionListener externalListener = mock(WifiManager.ActionListener.class); + mWifiManager.connect(TEST_NETWORK_ID, externalListener); + + mLooper.dispatchAll(); + verify(externalListener).onFailure(WifiManager.NOT_AUTHORIZED); + } + + /** + * Test behavior of {@link WifiManager#connect(int, WifiManager.ActionListener)} + */ + @Test + public void testConnectWithListenerHandleRemoteException() throws Exception { + doThrow(new RemoteException()).when(mWifiService) + .connect(eq(null), anyInt(), any(IBinder.class), + any(IActionListener.class), anyInt()); + WifiManager.ActionListener externalListener = mock(WifiManager.ActionListener.class); + mWifiManager.connect(TEST_NETWORK_ID, externalListener); + + mLooper.dispatchAll(); + verify(externalListener).onFailure(WifiManager.ERROR); + } + + /** + * Test behavior of {@link WifiManager#connect(int, WifiManager.ActionListener)} + */ + @Test + public void testConnectWithoutListener() throws Exception { + WifiConfiguration configuration = new WifiConfiguration(); + mWifiManager.connect(configuration, null); + + verify(mWifiService).connect(configuration, WifiConfiguration.INVALID_NETWORK_ID, null, + null, 0); + } + + /** + * Test behavior of {@link WifiManager#getTxPacketCount(WifiManager.TxPacketCountListener)} + */ + @Test + public void testGetTxPacketCount() throws Exception { + WifiManager.TxPacketCountListener externalListener = + mock(WifiManager.TxPacketCountListener.class); + mWifiManager.getTxPacketCount(externalListener); + + ArgumentCaptor binderListenerCaptor = + ArgumentCaptor.forClass(ITxPacketCountListener.class); + verify(mWifiService).getTxPacketCount(anyString(), any(Binder.class), + binderListenerCaptor.capture(), anyInt()); + assertNotNull(binderListenerCaptor.getValue()); + + // Trigger on success. + binderListenerCaptor.getValue().onSuccess(6); + mLooper.dispatchAll(); + verify(externalListener).onSuccess(6); + + // Trigger on failure. + binderListenerCaptor.getValue().onFailure(WifiManager.BUSY); + mLooper.dispatchAll(); + verify(externalListener).onFailure(WifiManager.BUSY); + } } -- cgit v1.2.3 From c3b87926fbbfd2164991725553ae8d676e94de0d Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Fri, 13 Sep 2019 10:20:13 -0700 Subject: WifiManager: Remove setCountryCode API Wifi stack will instead call existing public Telephony API/broadcast to get the country code. Bug: 140744935 Test: Manual tests Test: atest android.net.wifi Change-Id: I83be57123630c510e121f49ceadb30644e26c29c --- wifi/java/android/net/wifi/IWifiManager.aidl | 2 -- wifi/java/android/net/wifi/WifiManager.java | 19 ------------------- .../java/com/android/server/wifi/BaseWifiService.java | 2 +- wifi/tests/src/android/net/wifi/WifiManagerTest.java | 19 ------------------- 4 files changed, 1 insertion(+), 41 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index c755c0f00469..a97a5a5ec593 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -108,8 +108,6 @@ interface IWifiManager int getWifiEnabledState(); - void setCountryCode(String country); - String getCountryCode(); boolean isDualBandSupported(); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 61cad4827344..00895e846e82 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -2489,25 +2489,6 @@ public class WifiManager { return false; } - /** - * 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. diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index 032a13ec826d..2e82f4e8c23b 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -205,7 +205,7 @@ public class BaseWifiService extends IWifiManager.Stub { throw new UnsupportedOperationException(); } - @Override + /** @removed */ public void setCountryCode(String country) { throw new UnsupportedOperationException(); } diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 8beee5708f1d..7e7f00281529 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -972,25 +972,6 @@ public class WifiManagerTest { verify(mWifiService).stopWatchLocalOnlyHotspot(); } - /** - * Verify that calls WifiServiceImpl to set country code when no exception happens. - */ - @Test - public void testSetWifiCountryCode() throws Exception { - mWifiManager.setCountryCode(TEST_COUNTRY_CODE); - verify(mWifiService).setCountryCode(TEST_COUNTRY_CODE); - } - - /** - * Verify that WifiManager.setCountryCode() rethrows exceptions if caller does not - * have necessary permissions. - */ - @Test(expected = SecurityException.class) - public void testSetWifiCountryCodeFailedOnSecurityException() throws Exception { - doThrow(new SecurityException()).when(mWifiService).setCountryCode(anyString()); - mWifiManager.setCountryCode(TEST_COUNTRY_CODE); - } - /** * Test that calls to get the current WPS config token return null and do not have any * interactions with WifiServiceImpl. -- cgit v1.2.3 From 49cc6e3af7251ce06f23221b1497490d1083a725 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Wed, 18 Sep 2019 14:49:18 -0700 Subject: WifiScanner: Enhance doc for setScanningEnabled API The existing WifiScanner.setScanningEnabled() API is invoked by ActiveModeWarden after any client iface state changes. Documenting this behavior explicitly (i.e enable needs to be invoked multiple time if there are multiple STA's brought up). Bug: 140111024 Test: None Change-Id: Ie377a9b57119cb7389df60294fc2111ec654fd38 --- wifi/java/android/net/wifi/WifiScanner.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index 66dc992d6dc7..075531ce158e 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -750,7 +750,10 @@ public class WifiScanner { /** * Enable/Disable wifi scanning. - * + * Note: WifiService calls this after any client interface mode changes (i.e. a new interface + * set up or an existing interface torn down) + * If there are >= 1 active client interface, invoke setScanningEnabled(true) + * If there are 0 active client interface, invoke setScanningEnabled(false) * {@hide} */ @RequiresPermission(Manifest.permission.NETWORK_STACK) -- cgit v1.2.3 From 4807c9a3dd4b4f987e6c727a780e90dd6861d95b Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Thu, 19 Sep 2019 11:57:13 -0700 Subject: WifiScanner: Add support to add more results to ScanData Bug: 140111024 Test: atest android.net.wifi Change-Id: I71a7568eb508db61cabdaf6e11b51df01c9eb49b --- wifi/java/android/net/wifi/WifiScanner.java | 57 ++++++++++++---------- .../src/android/net/wifi/WifiScannerTest.java | 34 ++++++++++++- 2 files changed, 63 insertions(+), 28 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index 075531ce158e..50b4bc1e2087 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; @@ -375,19 +376,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 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 results) { mId = id; mFlags = flags; mBucketsScanned = bucketsScanned; @@ -400,11 +409,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 +434,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 +451,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 +466,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 results = new ArrayList<>(); + in.readParcelableList(results, ScanResult.class.getClassLoader()); return new ScanData(id, flags, bucketsScanned, bandScanned, results); } diff --git a/wifi/tests/src/android/net/wifi/WifiScannerTest.java b/wifi/tests/src/android/net/wifi/WifiScannerTest.java index dd05b47fbd4f..ea136d62b202 100644 --- a/wifi/tests/src/android/net/wifi/WifiScannerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiScannerTest.java @@ -22,7 +22,6 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; @@ -445,4 +444,37 @@ public class WifiScannerTest { assertEquals(WifiScanner.CMD_STOP_PNO_SCAN, message.what); } + + @Test + public void testScanDataAddResults() throws Exception { + ScanResult scanResult1 = new ScanResult(); + scanResult1.SSID = TEST_SSID_1; + ScanData scanData = new ScanData(0, 0, new ScanResult[]{scanResult1}); + + ScanResult scanResult2 = new ScanResult(); + scanResult2.SSID = TEST_SSID_2; + scanData.addResults(new ScanResult[]{scanResult2}); + + ScanResult[] consolidatedScanResults = scanData.getResults(); + assertEquals(2, consolidatedScanResults.length); + assertEquals(TEST_SSID_1, consolidatedScanResults[0].SSID); + assertEquals(TEST_SSID_2, consolidatedScanResults[1].SSID); + } + + @Test + public void testScanDataParcel() throws Exception { + ScanResult scanResult1 = new ScanResult(); + scanResult1.SSID = TEST_SSID_1; + ScanData scanData = new ScanData(5, 4, new ScanResult[]{scanResult1}); + + Parcel parcel = Parcel.obtain(); + scanData.writeToParcel(parcel, 0); + parcel.setDataPosition(0); // Rewind data position back to the beginning for read. + ScanData readScanData = ScanData.CREATOR.createFromParcel(parcel); + + assertEquals(scanData.getId(), readScanData.getId()); + assertEquals(scanData.getFlags(), readScanData.getFlags()); + assertEquals(scanData.getResults().length, readScanData.getResults().length); + assertEquals(scanData.getResults()[0].SSID, readScanData.getResults()[0].SSID); + } } -- cgit v1.2.3 From f180b09492e16af8ad76eae1d90aa64e66c23f75 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Mon, 23 Sep 2019 21:46:10 -0700 Subject: WifiScanner: Add missing @hide constants Bug: 140111024 Test: atest com.android.server.wifi Change-Id: I55ebfbbd1c8fbc459cee7d5e831b70b73adebf5d --- wifi/java/android/net/wifi/WifiScanner.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index 50b4bc1e2087..68948cbbe7a9 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -59,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 */ -- cgit v1.2.3 From 44e80de8be0bcad03e32abf66f25a109a6109810 Mon Sep 17 00:00:00 2001 From: xshu Date: Wed, 25 Sep 2019 16:25:06 -0700 Subject: Remove getOrCreateRandomizedMacAddress API Bug: 137799272 Test: unit tests Change-Id: I078d28ed81a84e32aaece839a51590364a974481 --- wifi/java/android/net/wifi/WifiConfiguration.java | 20 --------- .../android/net/wifi/WifiConfigurationTest.java | 49 ++-------------------- 2 files changed, 3 insertions(+), 66 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index eb5a717d2b07..2afb14a12110 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -1055,26 +1055,6 @@ public class WifiConfiguration implements Parcelable { && !MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS).equals(mac); } - /** - * @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 diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java index ba9fc786afe7..6d7e621a9bc2 100644 --- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java @@ -19,7 +19,6 @@ package android.net.wifi; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import android.net.MacAddress; @@ -62,7 +61,8 @@ public class WifiConfigurationTest { config.updateIdentifier = "1234"; config.fromWifiNetworkSpecifier = true; config.fromWifiNetworkSuggestion = true; - MacAddress macBeforeParcel = config.getOrCreateRandomizedMacAddress(); + config.setRandomizedMacAddress(MacAddress.createRandomUnicastAddress()); + MacAddress macBeforeParcel = config.getRandomizedMacAddress(); Parcel parcelW = Parcel.obtain(); config.writeToParcel(parcelW, 0); byte[] bytes = parcelW.marshall(); @@ -75,7 +75,7 @@ public class WifiConfigurationTest { // lacking a useful config.equals, check two fields near the end. assertEquals(cookie, reconfig.getMoTree()); - assertEquals(macBeforeParcel, reconfig.getOrCreateRandomizedMacAddress()); + assertEquals(macBeforeParcel, reconfig.getRandomizedMacAddress()); assertEquals(config.updateIdentifier, reconfig.updateIdentifier); assertFalse(reconfig.trusted); assertTrue(config.fromWifiNetworkSpecifier); @@ -192,19 +192,6 @@ public class WifiConfigurationTest { assertFalse(config.isOpenNetwork()); } - @Test - public void testGetOrCreateRandomizedMacAddress_SavesAndReturnsSameAddress() { - WifiConfiguration config = new WifiConfiguration(); - MacAddress defaultMac = MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS); - assertEquals(defaultMac, config.getRandomizedMacAddress()); - - MacAddress firstMacAddress = config.getOrCreateRandomizedMacAddress(); - MacAddress secondMacAddress = config.getOrCreateRandomizedMacAddress(); - - assertNotEquals(defaultMac, firstMacAddress); - assertEquals(firstMacAddress, secondMacAddress); - } - @Test public void testSetRandomizedMacAddress_ChangesSavedAddress() { WifiConfiguration config = new WifiConfiguration(); @@ -218,36 +205,6 @@ public class WifiConfigurationTest { assertEquals(macToChangeInto, macAfterChange); } - @Test - public void testGetOrCreateRandomizedMacAddress_ReRandomizesInvalidAddress() { - WifiConfiguration config = new WifiConfiguration(); - - MacAddress defaultMac = MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS); - MacAddress macAddressZeroes = MacAddress.ALL_ZEROS_ADDRESS; - MacAddress macAddressMulticast = MacAddress.fromString("03:ff:ff:ff:ff:ff"); - MacAddress macAddressGlobal = MacAddress.fromString("fc:ff:ff:ff:ff:ff"); - - config.setRandomizedMacAddress(null); - MacAddress macAfterChange = config.getOrCreateRandomizedMacAddress(); - assertNotEquals(macAfterChange, null); - - config.setRandomizedMacAddress(defaultMac); - macAfterChange = config.getOrCreateRandomizedMacAddress(); - assertNotEquals(macAfterChange, defaultMac); - - config.setRandomizedMacAddress(macAddressZeroes); - macAfterChange = config.getOrCreateRandomizedMacAddress(); - assertNotEquals(macAfterChange, macAddressZeroes); - - config.setRandomizedMacAddress(macAddressMulticast); - macAfterChange = config.getOrCreateRandomizedMacAddress(); - assertNotEquals(macAfterChange, macAddressMulticast); - - config.setRandomizedMacAddress(macAddressGlobal); - macAfterChange = config.getOrCreateRandomizedMacAddress(); - assertNotEquals(macAfterChange, macAddressGlobal); - } - @Test public void testSetRandomizedMacAddress_DoesNothingWhenNull() { WifiConfiguration config = new WifiConfiguration(); -- cgit v1.2.3 From bbe1a1993ea7b96fc5bd4d3fc69b16aa2fde2ecd Mon Sep 17 00:00:00 2001 From: Hugo Benichi Date: Fri, 27 Sep 2019 13:05:31 +0900 Subject: WiFi: Remove deprecated methods Bug: 122431221 Test: Compiled Change-Id: I66df2979cee05bf283d227a6948f0ffa42767783 --- wifi/java/com/android/server/wifi/BaseWifiService.java | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'wifi') diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index 2e82f4e8c23b..64df694d72a7 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -205,11 +205,6 @@ public class BaseWifiService extends IWifiManager.Stub { throw new UnsupportedOperationException(); } - /** @removed */ - public void setCountryCode(String country) { - throw new UnsupportedOperationException(); - } - @Override public String getCountryCode() { throw new UnsupportedOperationException(); @@ -325,11 +320,6 @@ public class BaseWifiService extends IWifiManager.Stub { throw new UnsupportedOperationException(); } - /** @removed */ - public Messenger getWifiServiceMessenger(String packageName) { - throw new UnsupportedOperationException(); - } - @Override public void enableTdls(String remoteIPAddress, boolean enable) { throw new UnsupportedOperationException(); -- cgit v1.2.3 From c9d4ee112e5441ae01502d597f6661f0feecc363 Mon Sep 17 00:00:00 2001 From: Chen Xu Date: Thu, 26 Sep 2019 16:11:59 -0700 Subject: new telephony annotation class This is a preparatory work for mainline. since Intdef is hidden, so we have to move some annotations (applied in SDK/system API) to a separate annotation class and having other module statically link to it. TODO: include telephony annotation in framework-non-updatable-sources Bug: 140908357 Test: Build Change-Id: I37f8a0624bbf27f264870ee9dbf03d3aaa5cadc1 --- wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'wifi') 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; -- cgit v1.2.3 From 090ea1360442a515d7e8c29a928d0eb76776c447 Mon Sep 17 00:00:00 2001 From: Patrik Fimml Date: Wed, 18 Sep 2019 14:37:27 +0200 Subject: LOHS: use Executor and AIDL interface internally This enables us to use Executor in new external APIs (as recommended). This also migrates the LOHS callbacks to an AIDL interface, which results in cleaner and type-safe code, and allows us to use Executor without an extra layer of indirection. Test: atest android.net.wifi.WifiManagerTest LocalOnlyHotspotRequestInfoTest WifiServiceImplTest android.net.wifi.cts.WifiManagerTest Bug: 132705022 Change-Id: I621062fd3865ca048c022c7ad3520ae4694fc0df --- .../net/wifi/ILocalOnlyHotspotCallback.aidl | 30 +++ wifi/java/android/net/wifi/IWifiManager.aidl | 5 +- wifi/java/android/net/wifi/WifiManager.java | 221 +++++++++------------ .../com/android/server/wifi/BaseWifiService.java | 17 +- .../src/android/net/wifi/WifiManagerTest.java | 127 ++++++------ 5 files changed, 196 insertions(+), 204 deletions(-) create mode 100644 wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl (limited to 'wifi') 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/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index a97a5a5ec593..b7e109463dab 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -26,6 +26,7 @@ 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.ISoftApCallback; import android.net.wifi.ITrafficStateCallback; @@ -138,11 +139,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(); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 00895e846e82..5782f5b1ab31 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -45,10 +45,9 @@ 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; @@ -1127,16 +1126,6 @@ public class WifiManager { 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; @@ -2730,6 +2719,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 @@ -2787,21 +2783,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; @@ -2879,16 +2874,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; @@ -3446,82 +3441,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 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)); } } @@ -3589,69 +3560,57 @@ 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 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; - } + mExecutor = executor; + mObserver = observer; + } - 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 void registered() throws RemoteException { + WifiManager manager = mWifiManager.get(); + if (manager == null) return; + + mExecutor.execute(() -> + mObserver.onRegistered(manager.new LocalOnlyHotspotSubscription())); + } + + @Override + 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)); } - public Messenger getMessenger() { - return mMessenger; + @Override + public void onHotspotStopped() { + WifiManager manager = mWifiManager.get(); + if (manager == null) return; + + mExecutor.execute(() -> mObserver.onStopped()); } - public void registered() throws RemoteException { - Message msg = Message.obtain(); - msg.what = HOTSPOT_OBSERVER_REGISTERED; - mMessenger.send(msg); + @Override + public void onHotspotFailed(int reason) { + // do nothing } } diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index 2e82f4e8c23b..2b055d534f85 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -23,6 +23,7 @@ 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.ISoftApCallback; @@ -285,21 +286,33 @@ 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(); diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 7e7f00281529..885139b99b5f 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -16,9 +16,6 @@ package android.net.wifi; -import static android.net.wifi.WifiManager.HOTSPOT_FAILED; -import static android.net.wifi.WifiManager.HOTSPOT_STARTED; -import static android.net.wifi.WifiManager.HOTSPOT_STOPPED; import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_GENERIC; import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE; import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_NO_CHANNEL; @@ -68,8 +65,6 @@ import android.os.Binder; import android.os.Build; import android.os.Handler; import android.os.IBinder; -import android.os.Message; -import android.os.Messenger; import android.os.RemoteException; import android.os.test.TestLooper; @@ -117,8 +112,6 @@ public class WifiManagerTest { private Handler mHandler; private TestLooper mLooper; private WifiManager mWifiManager; - private Messenger mWifiServiceMessenger; - final ArgumentCaptor mMessengerCaptor = ArgumentCaptor.forClass(Messenger.class); @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); @@ -128,7 +121,6 @@ public class WifiManagerTest { when(mContext.getApplicationInfo()).thenReturn(mApplicationInfo); when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME); - mWifiServiceMessenger = new Messenger(mHandler); mWifiManager = new WifiManager(mContext, mWifiService, mLooper.getLooper()); verify(mWifiService).getVerboseLoggingLevel(); } @@ -178,7 +170,7 @@ public class WifiManagerTest { @Test public void testCreationAndCloseOfLocalOnlyHotspotReservation() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString())).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); @@ -196,7 +188,7 @@ public class WifiManagerTest { public void testLocalOnlyHotspotReservationCallsStopProperlyInTryWithResources() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString())).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); @@ -357,7 +349,7 @@ public class WifiManagerTest { mWifiManager.startLocalOnlyHotspot(callback, mHandler); verify(mWifiService) - .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString()); + .startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString()); } /** @@ -368,7 +360,7 @@ public class WifiManagerTest { public void testStartLocalOnlyHotspotThrowsSecurityException() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); doThrow(new SecurityException()).when(mWifiService) - .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString()); + .startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString()); mWifiManager.startLocalOnlyHotspot(callback, mHandler); } @@ -380,7 +372,7 @@ public class WifiManagerTest { public void testStartLocalOnlyHotspotThrowsIllegalStateException() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); doThrow(new IllegalStateException()).when(mWifiService) - .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString()); + .startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString()); mWifiManager.startLocalOnlyHotspot(callback, mHandler); } @@ -390,12 +382,13 @@ public class WifiManagerTest { @Test public void testCorrectLooperIsUsedForHandler() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mLooper.dispatchAll(); assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason); verify(mContext, never()).getMainLooper(); + verify(mContext, never()).getMainExecutor(); } /** @@ -406,15 +399,15 @@ public class WifiManagerTest { public void testMainLooperIsUsedWhenHandlerNotProvided() throws Exception { // record thread from looper.getThread and check ids. TestLooper altLooper = new TestLooper(); - when(mContext.getMainLooper()).thenReturn(altLooper.getLooper()); + when(mContext.getMainExecutor()).thenReturn(altLooper.getNewExecutor()); TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE); mWifiManager.startLocalOnlyHotspot(callback, null); altLooper.dispatchAll(); assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason); assertEquals(altLooper.getLooper().getThread().getId(), callback.mCallingThreadId); - verify(mContext).getMainLooper(); + verify(mContext).getMainExecutor(); } /** @@ -426,18 +419,17 @@ public class WifiManagerTest { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); TestLooper callbackLooper = new TestLooper(); Handler callbackHandler = new Handler(callbackLooper.getLooper()); - when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(), - any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED); + ArgumentCaptor internalCallback = + ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); + when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString())) + .thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, callbackHandler); callbackLooper.dispatchAll(); mLooper.dispatchAll(); assertFalse(callback.mOnStartedCalled); assertEquals(null, callback.mRes); // now trigger the callback - Message msg = new Message(); - msg.what = HOTSPOT_STARTED; - msg.obj = mApConfig; - mMessengerCaptor.getValue().send(msg); + internalCallback.getValue().onHotspotStarted(mApConfig); mLooper.dispatchAll(); callbackLooper.dispatchAll(); assertTrue(callback.mOnStartedCalled); @@ -453,17 +445,17 @@ public class WifiManagerTest { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); TestLooper callbackLooper = new TestLooper(); Handler callbackHandler = new Handler(callbackLooper.getLooper()); - when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(), - any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED); + ArgumentCaptor internalCallback = + ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); + when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString())) + .thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, callbackHandler); callbackLooper.dispatchAll(); mLooper.dispatchAll(); assertFalse(callback.mOnStartedCalled); assertEquals(null, callback.mRes); // now trigger the callback - Message msg = new Message(); - msg.what = HOTSPOT_STARTED; - mMessengerCaptor.getValue().send(msg); + internalCallback.getValue().onHotspotStarted(null); mLooper.dispatchAll(); callbackLooper.dispatchAll(); assertFalse(callback.mOnStartedCalled); @@ -478,16 +470,16 @@ public class WifiManagerTest { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); TestLooper callbackLooper = new TestLooper(); Handler callbackHandler = new Handler(callbackLooper.getLooper()); - when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(), - any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED); + ArgumentCaptor internalCallback = + ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); + when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString())) + .thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, callbackHandler); callbackLooper.dispatchAll(); mLooper.dispatchAll(); assertFalse(callback.mOnStoppedCalled); // now trigger the callback - Message msg = new Message(); - msg.what = HOTSPOT_STOPPED; - mMessengerCaptor.getValue().send(msg); + internalCallback.getValue().onHotspotStopped(); mLooper.dispatchAll(); callbackLooper.dispatchAll(); assertTrue(callback.mOnStoppedCalled); @@ -501,17 +493,16 @@ public class WifiManagerTest { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); TestLooper callbackLooper = new TestLooper(); Handler callbackHandler = new Handler(callbackLooper.getLooper()); - when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(), - any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED); + ArgumentCaptor internalCallback = + ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); + when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString())) + .thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, callbackHandler); callbackLooper.dispatchAll(); mLooper.dispatchAll(); assertEquals(ERROR_NOT_SET, callback.mFailureReason); // now trigger the callback - Message msg = new Message(); - msg.what = HOTSPOT_FAILED; - msg.arg1 = ERROR_NO_CHANNEL; - mMessengerCaptor.getValue().send(msg); + internalCallback.getValue().onHotspotFailed(ERROR_NO_CHANNEL); mLooper.dispatchAll(); callbackLooper.dispatchAll(); assertEquals(ERROR_NO_CHANNEL, callback.mFailureReason); @@ -523,7 +514,7 @@ public class WifiManagerTest { @Test public void testLocalOnlyHotspotCallbackFullOnIncompatibleMode() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mLooper.dispatchAll(); @@ -539,7 +530,7 @@ public class WifiManagerTest { @Test public void testLocalOnlyHotspotCallbackFullOnTetheringDisallowed() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString())).thenReturn(ERROR_TETHERING_DISALLOWED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mLooper.dispatchAll(); @@ -557,7 +548,7 @@ public class WifiManagerTest { public void testLocalOnlyHotspotCallbackFullOnSecurityException() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); doThrow(new SecurityException()).when(mWifiService) - .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString()); + .startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString()); try { mWifiManager.startLocalOnlyHotspot(callback, mHandler); } catch (SecurityException e) { @@ -577,7 +568,7 @@ public class WifiManagerTest { @Test public void testLocalOnlyHotspotCallbackFullOnNoChannelError() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString())).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mLooper.dispatchAll(); @@ -593,7 +584,7 @@ public class WifiManagerTest { @Test public void testCancelLocalOnlyHotspotRequestCallsStopOnWifiService() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString())).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mWifiManager.cancelLocalOnlyHotspotRequest(); @@ -615,7 +606,7 @@ public class WifiManagerTest { @Test public void testCallbackAfterLocalOnlyHotspotWasCancelled() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString())).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mWifiManager.cancelLocalOnlyHotspotRequest(); @@ -634,7 +625,7 @@ public class WifiManagerTest { @Test public void testCancelAfterLocalOnlyHotspotCallbackTriggered() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mLooper.dispatchAll(); @@ -654,7 +645,7 @@ public class WifiManagerTest { TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver(); mWifiManager.watchLocalOnlyHotspot(observer, mHandler); - verify(mWifiService).startWatchLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)); + verify(mWifiService).startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class)); } /** @@ -665,7 +656,7 @@ public class WifiManagerTest { public void testStartWatchLocalOnlyHotspotThrowsSecurityException() throws Exception { TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver(); doThrow(new SecurityException()).when(mWifiService) - .startWatchLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)); + .startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class)); mWifiManager.watchLocalOnlyHotspot(observer, mHandler); } @@ -677,7 +668,7 @@ public class WifiManagerTest { public void testStartWatchLocalOnlyHotspotThrowsIllegalStateException() throws Exception { TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver(); doThrow(new IllegalStateException()).when(mWifiService) - .startWatchLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)); + .startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class)); mWifiManager.watchLocalOnlyHotspot(observer, mHandler); } @@ -822,6 +813,7 @@ public class WifiManagerTest { verify(mWifiService).registerSoftApCallback(any(IBinder.class), any(ISoftApCallback.Stub.class), anyInt()); verify(mContext, never()).getMainLooper(); + verify(mContext, never()).getMainExecutor(); } /** @@ -834,6 +826,7 @@ public class WifiManagerTest { mLooper.dispatchAll(); assertTrue(observer.mOnRegistered); verify(mContext, never()).getMainLooper(); + verify(mContext, never()).getMainExecutor(); } /** @@ -844,13 +837,13 @@ public class WifiManagerTest { public void testMainLooperIsUsedWhenHandlerNotProvidedForObserver() throws Exception { // record thread from looper.getThread and check ids. TestLooper altLooper = new TestLooper(); - when(mContext.getMainLooper()).thenReturn(altLooper.getLooper()); + when(mContext.getMainExecutor()).thenReturn(altLooper.getNewExecutor()); TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver(); mWifiManager.watchLocalOnlyHotspot(observer, null); altLooper.dispatchAll(); assertTrue(observer.mOnRegistered); assertEquals(altLooper.getLooper().getThread().getId(), observer.mCallingThreadId); - verify(mContext).getMainLooper(); + verify(mContext).getMainExecutor(); } /** @@ -865,8 +858,7 @@ public class WifiManagerTest { assertFalse(observer.mOnRegistered); assertEquals(null, observer.mSub); mWifiManager.watchLocalOnlyHotspot(observer, observerHandler); - verify(mWifiService).startWatchLocalOnlyHotspot(mMessengerCaptor.capture(), - any(IBinder.class)); + verify(mWifiService).startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class)); // now trigger the callback observerLooper.dispatchAll(); mLooper.dispatchAll(); @@ -884,16 +876,14 @@ public class WifiManagerTest { TestLooper observerLooper = new TestLooper(); Handler observerHandler = new Handler(observerLooper.getLooper()); mWifiManager.watchLocalOnlyHotspot(observer, observerHandler); - verify(mWifiService).startWatchLocalOnlyHotspot(mMessengerCaptor.capture(), - any(IBinder.class)); + ArgumentCaptor internalCallback = + ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); + verify(mWifiService).startWatchLocalOnlyHotspot(internalCallback.capture()); observerLooper.dispatchAll(); mLooper.dispatchAll(); assertFalse(observer.mOnStartedCalled); // now trigger the callback - Message msg = new Message(); - msg.what = HOTSPOT_STARTED; - msg.obj = mApConfig; - mMessengerCaptor.getValue().send(msg); + internalCallback.getValue().onHotspotStarted(mApConfig); mLooper.dispatchAll(); observerLooper.dispatchAll(); assertTrue(observer.mOnStartedCalled); @@ -910,15 +900,14 @@ public class WifiManagerTest { TestLooper observerLooper = new TestLooper(); Handler observerHandler = new Handler(observerLooper.getLooper()); mWifiManager.watchLocalOnlyHotspot(observer, observerHandler); - verify(mWifiService).startWatchLocalOnlyHotspot(mMessengerCaptor.capture(), - any(IBinder.class)); + ArgumentCaptor internalCallback = + ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); + verify(mWifiService).startWatchLocalOnlyHotspot(internalCallback.capture()); observerLooper.dispatchAll(); mLooper.dispatchAll(); assertFalse(observer.mOnStartedCalled); // now trigger the callback - Message msg = new Message(); - msg.what = HOTSPOT_STARTED; - mMessengerCaptor.getValue().send(msg); + internalCallback.getValue().onHotspotStarted(null); mLooper.dispatchAll(); observerLooper.dispatchAll(); assertFalse(observer.mOnStartedCalled); @@ -936,15 +925,14 @@ public class WifiManagerTest { TestLooper observerLooper = new TestLooper(); Handler observerHandler = new Handler(observerLooper.getLooper()); mWifiManager.watchLocalOnlyHotspot(observer, observerHandler); - verify(mWifiService).startWatchLocalOnlyHotspot(mMessengerCaptor.capture(), - any(IBinder.class)); + ArgumentCaptor internalCallback = + ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); + verify(mWifiService).startWatchLocalOnlyHotspot(internalCallback.capture()); observerLooper.dispatchAll(); mLooper.dispatchAll(); assertFalse(observer.mOnStoppedCalled); // now trigger the callback - Message msg = new Message(); - msg.what = HOTSPOT_STOPPED; - mMessengerCaptor.getValue().send(msg); + internalCallback.getValue().onHotspotStopped(); mLooper.dispatchAll(); observerLooper.dispatchAll(); assertTrue(observer.mOnStoppedCalled); @@ -1173,6 +1161,7 @@ i * Verify that a call to cancel WPS immediately returns a failure. Handler altHandler = new Handler(altLooper.getLooper()); mWifiManager.registerTrafficStateCallback(mTrafficStateCallback, altHandler); verify(mContext, never()).getMainLooper(); + verify(mContext, never()).getMainExecutor(); verify(mWifiService).registerTrafficStateCallback( any(IBinder.class), callbackCaptor.capture(), anyInt()); -- cgit v1.2.3 From 1575e5d30cf49eb509eba9964d874fbe22a87a21 Mon Sep 17 00:00:00 2001 From: xshu Date: Tue, 1 Oct 2019 15:53:57 -0700 Subject: [MAC rand] Repurpose existing field Repurposing an old field to suit the new design of throttling MAC address changes based on DHCP lease duration. Bug: 141950243 Test: unit tests Change-Id: Ide71816895eb088f728105d1f675a6823490423f --- wifi/java/android/net/wifi/WifiConfiguration.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 2afb14a12110..05a6a39167b6 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -1038,10 +1038,10 @@ public class WifiConfiguration implements Parcelable { /** * @hide - * The wall clock time of when |mRandomizedMacAddress| last changed. - * Used to determine when we should re-randomize in aggressive mode. + * The wall clock time of when |mRandomizedMacAddress| should be re-randomized in aggressive + * randomization mode. */ - public long randomizedMacLastModifiedTimeMs = 0; + public long randomizedMacExpirationTimeMs = 0; /** * @hide @@ -1902,8 +1902,9 @@ public class WifiConfiguration implements Parcelable { } sbuf.append(" macRandomizationSetting: ").append(macRandomizationSetting).append("\n"); sbuf.append(" mRandomizedMacAddress: ").append(mRandomizedMacAddress).append("\n"); - sbuf.append(" randomizedMacLastModifiedTimeMs: ").append(randomizedMacLastModifiedTimeMs) - .append("\n"); + sbuf.append(" randomizedMacExpirationTimeMs: ") + .append(randomizedMacExpirationTimeMs == 0 ? "" + : TimeUtils.logTimeOfDay(randomizedMacExpirationTimeMs)).append("\n"); sbuf.append(" KeyMgmt:"); for (int k = 0; k < this.allowedKeyManagement.size(); k++) { if (this.allowedKeyManagement.get(k)) { @@ -2429,7 +2430,7 @@ public class WifiConfiguration implements Parcelable { recentFailure.setAssociationStatus(source.recentFailure.getAssociationStatus()); mRandomizedMacAddress = source.mRandomizedMacAddress; macRandomizationSetting = source.macRandomizationSetting; - randomizedMacLastModifiedTimeMs = source.randomizedMacLastModifiedTimeMs; + randomizedMacExpirationTimeMs = source.randomizedMacExpirationTimeMs; requirePMF = source.requirePMF; updateIdentifier = source.updateIdentifier; } @@ -2504,7 +2505,7 @@ public class WifiConfiguration implements Parcelable { dest.writeParcelable(mRandomizedMacAddress, flags); dest.writeInt(macRandomizationSetting); dest.writeInt(osu ? 1 : 0); - dest.writeLong(randomizedMacLastModifiedTimeMs); + dest.writeLong(randomizedMacExpirationTimeMs); } /** Implement the Parcelable interface {@hide} */ @@ -2579,7 +2580,7 @@ public class WifiConfiguration implements Parcelable { config.mRandomizedMacAddress = in.readParcelable(null); config.macRandomizationSetting = in.readInt(); config.osu = in.readInt() != 0; - config.randomizedMacLastModifiedTimeMs = in.readLong(); + config.randomizedMacExpirationTimeMs = in.readLong(); return config; } -- cgit v1.2.3 From a100fb48414d1b831a234dc3a45cc82ffb81726d Mon Sep 17 00:00:00 2001 From: Nate Jiang Date: Mon, 9 Sep 2019 15:33:17 -0700 Subject: [NetworkSuggestion] add public API to support passpoint in suggestion Allow apps suggest passpoint network in NetworkSuggestionAPI Bug: 141378137 Test: atest android.net.wifi Test: atest com.android.server.wifi Change-Id: Ibca75b0de758e3dfa78b7939851c8dda2eb3d696 --- .../android/net/wifi/WifiNetworkSuggestion.java | 132 +++++++++--- .../net/wifi/WifiNetworkSuggestionTest.java | 222 +++++++++++++++++++-- .../wifi/hotspot2/PasspointConfigurationTest.java | 174 ++-------------- .../net/wifi/hotspot2/PasspointTestUtils.java | 163 +++++++++++++++ 4 files changed, 490 insertions(+), 201 deletions(-) create mode 100644 wifi/tests/src/android/net/wifi/hotspot2/PasspointTestUtils.java (limited to 'wifi') 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; @@ -79,6 +80,10 @@ public final class WifiNetworkSuggestion implements Parcelable { * certificates and other settings associated with the SuiteB networks. */ 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; @@ -233,6 +239,24 @@ public final class WifiNetworkSuggestion implements Parcelable { return this; } + /** + * 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. *

    @@ -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 { *

    * * 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: * *
    {@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 suggestionsList =
              *      new ArrayList { {
              *          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(),
    @@ -447,6 +505,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/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
    index 4dfa96b8c606..699008905f0a 100644
    --- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
    +++ b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
    @@ -19,6 +19,8 @@ package android.net.wifi;
     import static org.junit.Assert.*;
     
     import android.net.MacAddress;
    +import android.net.wifi.hotspot2.PasspointConfiguration;
    +import android.net.wifi.hotspot2.PasspointTestUtils;
     import android.os.Parcel;
     import android.os.Process;
     
    @@ -39,6 +41,7 @@ public class WifiNetworkSuggestionTest {
         private static final String TEST_BSSID = "12:12:12:12:12:12";
         private static final String TEST_SSID_1 = "\"Test1234\"";
         private static final String TEST_PRESHARED_KEY = "Test123";
    +    private static final String TEST_FQDN = "fqdn";
     
         /**
          * Validate correctness of WifiNetworkSuggestion object created by
    @@ -185,6 +188,25 @@ public class WifiNetworkSuggestionTest {
             // here.
         }
     
    +    /**
    +     * Validate correctness of WifiNetworkSuggestion object created by
    +     * {@link WifiNetworkSuggestion.Builder#build()} for Passpoint network which requires
    +     *  app interaction and metered.
    +     */
    +    @Test
    +    public void testWifiNetworkSuggestionBuilderForPasspointNetworkWithReqAppInteractionMetered() {
    +        PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
    +        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
    +                .setPasspointConfig(passpointConfiguration)
    +                .setIsAppInteractionRequired(true)
    +                .setIsMetered(true)
    +                .build();
    +        assertEquals(TEST_FQDN, suggestion.wifiConfiguration.FQDN);
    +        assertTrue(suggestion.isAppInteractionRequired);
    +        assertEquals(suggestion.wifiConfiguration.meteredOverride,
    +                WifiConfiguration.METERED_OVERRIDE_METERED);
    +    }
    +
         /**
          * Ensure {@link WifiNetworkSuggestion.Builder#setSsid(String)} throws an exception
          * when the string is not Unicode.
    @@ -208,6 +230,18 @@ public class WifiNetworkSuggestionTest {
                     .build();
         }
     
    +    /**
    +     * Ensure {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)}}
    +     * throws an exception when the PasspointConfiguration is not valid.
    +     */
    +    @Test(expected = IllegalArgumentException.class)
    +    public void testWifiNetworkSuggestionBuilderSetPasspointConfigWithNonValid() {
    +        PasspointConfiguration passpointConfiguration = new PasspointConfiguration();
    +        new WifiNetworkSuggestion.Builder()
    +                .setPasspointConfig(passpointConfiguration)
    +                .build();
    +    }
    +
         /**
          * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
          * when {@link WifiNetworkSuggestion.Builder#setSsid(String)} is not set.
    @@ -310,6 +344,91 @@ public class WifiNetworkSuggestionTest {
                     .build();
         }
     
    +    /**
    +     * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
    +     * when both {@link WifiNetworkSuggestion.Builder#setSsid(String)} and
    +     * {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)} are invoked.
    +     */
    +    @Test(expected = IllegalStateException.class)
    +    public void testWifiNetworkSuggestionBuilderWithBothSsidAndPasspointConfig() {
    +        PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
    +        new WifiNetworkSuggestion.Builder()
    +                .setSsid(TEST_SSID)
    +                .setPasspointConfig(passpointConfiguration)
    +                .build();
    +    }
    +
    +    /**
    +     * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
    +     * when both {@link WifiNetworkSuggestion.Builder#setWpa2Passphrase(String)} and
    +     * {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)} are invoked.
    +     */
    +    @Test(expected = IllegalStateException.class)
    +    public void testWifiNetworkSuggestionBuilderWithBothWpa2PassphraseAndPasspointConfig() {
    +        PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
    +        new WifiNetworkSuggestion.Builder()
    +                .setWpa2Passphrase(TEST_PRESHARED_KEY)
    +                .setPasspointConfig(passpointConfiguration)
    +                .build();
    +    }
    +
    +    /**
    +     * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
    +     * when both {@link WifiNetworkSuggestion.Builder#setWpa3Passphrase(String)} and
    +     * {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)} are invoked.
    +     */
    +    @Test(expected = IllegalStateException.class)
    +    public void testWifiNetworkSuggestionBuilderWithBothWpa3PassphraseAndPasspointConfig() {
    +        PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
    +        new WifiNetworkSuggestion.Builder()
    +                .setWpa3Passphrase(TEST_PRESHARED_KEY)
    +                .setPasspointConfig(passpointConfiguration)
    +                .build();
    +    }
    +
    +    /**
    +     * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
    +     * when both {@link WifiNetworkSuggestion.Builder#setWpa3EnterpriseConfig(WifiEnterpriseConfig)}
    +     * and {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)} are
    +     * invoked.
    +     */
    +    @Test(expected = IllegalStateException.class)
    +    public void testWifiNetworkSuggestionBuilderWithBothEnterpriseAndPasspointConfig() {
    +        PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
    +        new WifiNetworkSuggestion.Builder()
    +                .setWpa3EnterpriseConfig(new WifiEnterpriseConfig())
    +                .setPasspointConfig(passpointConfiguration)
    +                .build();
    +    }
    +
    +    /**
    +     * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
    +     * when both {@link WifiNetworkSuggestion.Builder#setIsEnhancedOpen(boolean)} and
    +     * {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)} are invoked.
    +     */
    +    @Test(expected = IllegalStateException.class)
    +    public void testWifiNetworkSuggestionBuilderWithBothEnhancedOpenAndPasspointConfig() {
    +        PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
    +        new WifiNetworkSuggestion.Builder()
    +                .setIsEnhancedOpen(true)
    +                .setPasspointConfig(passpointConfiguration)
    +                .build();
    +    }
    +
    +    /**
    +     * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
    +     * when both {@link WifiNetworkSuggestion.Builder#setIsHiddenSsid(boolean)} and
    +     * {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)} are invoked.
    +     */
    +    @Test(expected = IllegalStateException.class)
    +    public void testWifiNetworkSuggestionBuilderWithBothHiddenSsidAndPasspointConfig() {
    +        PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
    +        new WifiNetworkSuggestion.Builder()
    +                .setIsHiddenSsid(true)
    +                .setPasspointConfig(passpointConfiguration)
    +                .build();
    +    }
    +
         /**
          * Check that parcel marshalling/unmarshalling works
          */
    @@ -319,8 +438,8 @@ public class WifiNetworkSuggestionTest {
             configuration.SSID = TEST_SSID;
             configuration.BSSID = TEST_BSSID;
             configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
    -        WifiNetworkSuggestion suggestion =
    -                new WifiNetworkSuggestion(configuration, false, true, TEST_UID, TEST_PACKAGE_NAME);
    +        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion(
    +                configuration, null, false, true, TEST_UID, TEST_PACKAGE_NAME);
     
             Parcel parcelW = Parcel.obtain();
             suggestion.writeToParcel(parcelW, 0);
    @@ -337,6 +456,39 @@ public class WifiNetworkSuggestionTest {
             // SSID + keyMgmt + same UID). |isAppInteractionRequired| & |isUserInteractionRequired| are
             // not considered for equality and hence needs to be checked for explicitly below.
             assertEquals(suggestion, parcelSuggestion);
    +        assertEquals(suggestion.hashCode(), parcelSuggestion.hashCode());
    +        assertEquals(suggestion.isAppInteractionRequired,
    +                parcelSuggestion.isAppInteractionRequired);
    +        assertEquals(suggestion.isUserInteractionRequired,
    +                parcelSuggestion.isUserInteractionRequired);
    +    }
    +
    +    /**
    +     * Check that parcel marshalling/unmarshalling works
    +     */
    +    @Test
    +    public void testPasspointNetworkSuggestionParcel() {
    +        PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
    +        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
    +                .setPasspointConfig(passpointConfiguration)
    +                .build();
    +
    +        Parcel parcelW = Parcel.obtain();
    +        suggestion.writeToParcel(parcelW, 0);
    +        byte[] bytes = parcelW.marshall();
    +        parcelW.recycle();
    +
    +        Parcel parcelR = Parcel.obtain();
    +        parcelR.unmarshall(bytes, 0, bytes.length);
    +        parcelR.setDataPosition(0);
    +        WifiNetworkSuggestion parcelSuggestion =
    +                WifiNetworkSuggestion.CREATOR.createFromParcel(parcelR);
    +
    +        // Two suggestion objects are considered equal if they point to the same network (i.e same
    +        // SSID + keyMgmt + same UID). |isAppInteractionRequired| & |isUserInteractionRequired| are
    +        // not considered for equality and hence needs to be checked for explicitly below.
    +        assertEquals(suggestion, parcelSuggestion);
    +        assertEquals(suggestion.hashCode(), parcelSuggestion.hashCode());
             assertEquals(suggestion.isAppInteractionRequired,
                     parcelSuggestion.isAppInteractionRequired);
             assertEquals(suggestion.isUserInteractionRequired,
    @@ -354,7 +506,7 @@ public class WifiNetworkSuggestionTest {
             configuration.BSSID = TEST_BSSID;
             configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
             WifiNetworkSuggestion suggestion =
    -                new WifiNetworkSuggestion(configuration, true, false, TEST_UID,
    +                new WifiNetworkSuggestion(configuration, null, true, false, TEST_UID,
                             TEST_PACKAGE_NAME);
     
             WifiConfiguration configuration1 = new WifiConfiguration();
    @@ -362,10 +514,11 @@ public class WifiNetworkSuggestionTest {
             configuration1.BSSID = TEST_BSSID;
             configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
             WifiNetworkSuggestion suggestion1 =
    -                new WifiNetworkSuggestion(configuration1, false, true, TEST_UID,
    +                new WifiNetworkSuggestion(configuration1, null, false, true, TEST_UID,
                             TEST_PACKAGE_NAME);
     
             assertEquals(suggestion, suggestion1);
    +        assertEquals(suggestion.hashCode(), suggestion1.hashCode());
         }
     
         /**
    @@ -378,14 +531,14 @@ public class WifiNetworkSuggestionTest {
             configuration.SSID = TEST_SSID;
             configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
             WifiNetworkSuggestion suggestion =
    -                new WifiNetworkSuggestion(configuration, false, false, TEST_UID,
    +                new WifiNetworkSuggestion(configuration, null, false, false, TEST_UID,
                             TEST_PACKAGE_NAME);
     
             WifiConfiguration configuration1 = new WifiConfiguration();
             configuration1.SSID = TEST_SSID_1;
             configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
             WifiNetworkSuggestion suggestion1 =
    -                new WifiNetworkSuggestion(configuration1, false, false, TEST_UID,
    +                new WifiNetworkSuggestion(configuration1, null, false, false, TEST_UID,
                             TEST_PACKAGE_NAME);
     
             assertNotEquals(suggestion, suggestion1);
    @@ -402,14 +555,14 @@ public class WifiNetworkSuggestionTest {
             configuration.BSSID = TEST_BSSID;
             configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
             WifiNetworkSuggestion suggestion =
    -                new WifiNetworkSuggestion(configuration, false, false, TEST_UID,
    +                new WifiNetworkSuggestion(configuration, null,  false, false, TEST_UID,
                             TEST_PACKAGE_NAME);
     
             WifiConfiguration configuration1 = new WifiConfiguration();
             configuration1.SSID = TEST_SSID;
             configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
             WifiNetworkSuggestion suggestion1 =
    -                new WifiNetworkSuggestion(configuration1, false, false, TEST_UID,
    +                new WifiNetworkSuggestion(configuration1, null, false, false, TEST_UID,
                             TEST_PACKAGE_NAME);
     
             assertNotEquals(suggestion, suggestion1);
    @@ -425,14 +578,14 @@ public class WifiNetworkSuggestionTest {
             configuration.SSID = TEST_SSID;
             configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
             WifiNetworkSuggestion suggestion =
    -                new WifiNetworkSuggestion(configuration, false, false, TEST_UID,
    +                new WifiNetworkSuggestion(configuration, null, false, false, TEST_UID,
                             TEST_PACKAGE_NAME);
     
             WifiConfiguration configuration1 = new WifiConfiguration();
             configuration1.SSID = TEST_SSID;
             configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
             WifiNetworkSuggestion suggestion1 =
    -                new WifiNetworkSuggestion(configuration1, false, false, TEST_UID,
    +                new WifiNetworkSuggestion(configuration1, null, false, false, TEST_UID,
                             TEST_PACKAGE_NAME);
     
             assertNotEquals(suggestion, suggestion1);
    @@ -448,11 +601,11 @@ public class WifiNetworkSuggestionTest {
             configuration.SSID = TEST_SSID;
             configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
             WifiNetworkSuggestion suggestion =
    -                new WifiNetworkSuggestion(configuration, false, false, TEST_UID,
    +                new WifiNetworkSuggestion(configuration, null, false, false, TEST_UID,
                             TEST_PACKAGE_NAME);
     
             WifiNetworkSuggestion suggestion1 =
    -                new WifiNetworkSuggestion(configuration, false, false, TEST_UID_OTHER,
    +                new WifiNetworkSuggestion(configuration, null, false, false, TEST_UID_OTHER,
                             TEST_PACKAGE_NAME);
     
             assertNotEquals(suggestion, suggestion1);
    @@ -467,13 +620,48 @@ public class WifiNetworkSuggestionTest {
             WifiConfiguration configuration = new WifiConfiguration();
             configuration.SSID = TEST_SSID;
             configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
    -        WifiNetworkSuggestion suggestion =
    -                new WifiNetworkSuggestion(configuration, false, false, TEST_UID, TEST_PACKAGE_NAME);
    +        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion(
    +                configuration, null, false, false, TEST_UID, TEST_PACKAGE_NAME);
     
    -        WifiNetworkSuggestion suggestion1 =
    -                new WifiNetworkSuggestion(configuration, false, false, TEST_UID,
    -                        TEST_PACKAGE_NAME_OTHER);
    +        WifiNetworkSuggestion suggestion1 = new WifiNetworkSuggestion(
    +                configuration, null, false, false, TEST_UID, TEST_PACKAGE_NAME_OTHER);
    +
    +        assertNotEquals(suggestion, suggestion1);
    +    }
    +    /**
    +     * Check NetworkSuggestion equals returns {@code true} for 2 Passpoint network suggestions with
    +     * same FQDN.
    +     */
    +    @Test
    +    public void testPasspointNetworkSuggestionEqualsSameWithSameFQDN() {
    +        PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
    +        PasspointConfiguration passpointConfiguration1 = PasspointTestUtils.createConfig();
    +        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
    +                .setPasspointConfig(passpointConfiguration)
    +                .build();
    +        WifiNetworkSuggestion suggestion1 = new WifiNetworkSuggestion.Builder()
    +                .setPasspointConfig(passpointConfiguration1)
    +                .build();
    +        assertEquals(suggestion, suggestion1);
    +        assertEquals(suggestion.hashCode(), suggestion1.hashCode());
    +    }
     
    +    /**
    +     * Check NetworkSuggestion equals returns {@code false} for 2 Passpoint network suggestions with
    +     * different FQDN.
    +     */
    +    @Test
    +    public void testPasspointNetworkSuggestionNotEqualsSameWithDifferentFQDN() {
    +        PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
    +        PasspointConfiguration passpointConfiguration1 = PasspointTestUtils.createConfig();
    +        passpointConfiguration1.getHomeSp().setFqdn(TEST_FQDN + 1);
    +
    +        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
    +                .setPasspointConfig(passpointConfiguration)
    +                .build();
    +        WifiNetworkSuggestion suggestion1 = new WifiNetworkSuggestion.Builder()
    +                .setPasspointConfig(passpointConfiguration1)
    +                .build();
             assertNotEquals(suggestion, suggestion1);
         }
     }
    diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
    index 88740d850643..c3b074eaee5a 100644
    --- a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
    +++ b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
    @@ -19,23 +19,15 @@ package android.net.wifi.hotspot2;
     import static org.junit.Assert.assertFalse;
     import static org.junit.Assert.assertTrue;
     
    -import android.net.wifi.EAPConstants;
    -import android.net.wifi.hotspot2.pps.Credential;
    -import android.net.wifi.hotspot2.pps.HomeSp;
    -import android.net.wifi.hotspot2.pps.Policy;
    -import android.net.wifi.hotspot2.pps.UpdateParameter;
     import android.os.Parcel;
    -import android.util.Base64;
     
     import androidx.test.filters.SmallTest;
     
     import org.junit.Test;
     
     import java.nio.charset.StandardCharsets;
    -import java.util.ArrayList;
     import java.util.Arrays;
     import java.util.HashMap;
    -import java.util.List;
     import java.util.Map;
     
     /**
    @@ -46,136 +38,6 @@ public class PasspointConfigurationTest {
         private static final int MAX_URL_BYTES = 1023;
         private static final int CERTIFICATE_FINGERPRINT_BYTES = 32;
     
    -    /**
    -     * Utility function for creating a {@link android.net.wifi.hotspot2.pps.HomeSP}.
    -     *
    -     * @return {@link android.net.wifi.hotspot2.pps.HomeSP}
    -     */
    -    private static HomeSp createHomeSp() {
    -        HomeSp homeSp = new HomeSp();
    -        homeSp.setFqdn("fqdn");
    -        homeSp.setFriendlyName("friendly name");
    -        homeSp.setRoamingConsortiumOis(new long[] {0x55, 0x66});
    -        return homeSp;
    -    }
    -
    -    /**
    -     * Utility function for creating a {@link android.net.wifi.hotspot2.pps.Credential}.
    -     *
    -     * @return {@link android.net.wifi.hotspot2.pps.Credential}
    -     */
    -    private static Credential createCredential() {
    -        Credential cred = new Credential();
    -        cred.setRealm("realm");
    -        cred.setUserCredential(null);
    -        cred.setCertCredential(null);
    -        cred.setSimCredential(new Credential.SimCredential());
    -        cred.getSimCredential().setImsi("1234*");
    -        cred.getSimCredential().setEapType(EAPConstants.EAP_SIM);
    -        cred.setCaCertificate(null);
    -        cred.setClientCertificateChain(null);
    -        cred.setClientPrivateKey(null);
    -        return cred;
    -    }
    -
    -    /**
    -     * Helper function for creating a {@link Policy} for testing.
    -     *
    -     * @return {@link Policy}
    -     */
    -    private static Policy createPolicy() {
    -        Policy policy = new Policy();
    -        policy.setMinHomeDownlinkBandwidth(123);
    -        policy.setMinHomeUplinkBandwidth(345);
    -        policy.setMinRoamingDownlinkBandwidth(567);
    -        policy.setMinRoamingUplinkBandwidth(789);
    -        policy.setMaximumBssLoadValue(12);
    -        policy.setExcludedSsidList(new String[] {"ssid1", "ssid2"});
    -        HashMap requiredProtoPortMap = new HashMap<>();
    -        requiredProtoPortMap.put(12, "23,342,123");
    -        requiredProtoPortMap.put(23, "789,372,1235");
    -        policy.setRequiredProtoPortMap(requiredProtoPortMap);
    -
    -        List preferredRoamingPartnerList = new ArrayList<>();
    -        Policy.RoamingPartner partner1 = new Policy.RoamingPartner();
    -        partner1.setFqdn("partner1.com");
    -        partner1.setFqdnExactMatch(true);
    -        partner1.setPriority(12);
    -        partner1.setCountries("us,jp");
    -        Policy.RoamingPartner partner2 = new Policy.RoamingPartner();
    -        partner2.setFqdn("partner2.com");
    -        partner2.setFqdnExactMatch(false);
    -        partner2.setPriority(42);
    -        partner2.setCountries("ca,fr");
    -        preferredRoamingPartnerList.add(partner1);
    -        preferredRoamingPartnerList.add(partner2);
    -        policy.setPreferredRoamingPartnerList(preferredRoamingPartnerList);
    -
    -        UpdateParameter policyUpdate = new UpdateParameter();
    -        policyUpdate.setUpdateIntervalInMinutes(1712);
    -        policyUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_OMADM);
    -        policyUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_HOMESP);
    -        policyUpdate.setServerUri("policy.update.com");
    -        policyUpdate.setUsername("username");
    -        policyUpdate.setBase64EncodedPassword(
    -                Base64.encodeToString("password".getBytes(), Base64.DEFAULT));
    -        policyUpdate.setTrustRootCertUrl("trust.cert.com");
    -        policyUpdate.setTrustRootCertSha256Fingerprint(
    -                new byte[CERTIFICATE_FINGERPRINT_BYTES]);
    -        policy.setPolicyUpdate(policyUpdate);
    -
    -        return policy;
    -    }
    -
    -    private static UpdateParameter createSubscriptionUpdate() {
    -        UpdateParameter subUpdate = new UpdateParameter();
    -        subUpdate.setUpdateIntervalInMinutes(9021);
    -        subUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_SSP);
    -        subUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER);
    -        subUpdate.setServerUri("subscription.update.com");
    -        subUpdate.setUsername("subUsername");
    -        subUpdate.setBase64EncodedPassword(
    -                Base64.encodeToString("subPassword".getBytes(), Base64.DEFAULT));
    -        subUpdate.setTrustRootCertUrl("subscription.trust.cert.com");
    -        subUpdate.setTrustRootCertSha256Fingerprint(new byte[CERTIFICATE_FINGERPRINT_BYTES]);
    -        return subUpdate;
    -    }
    -    /**
    -     * Helper function for creating a {@link PasspointConfiguration} for testing.
    -     *
    -     * @return {@link PasspointConfiguration}
    -     */
    -    private static PasspointConfiguration createConfig() {
    -        PasspointConfiguration config = new PasspointConfiguration();
    -        config.setUpdateIdentifier(1234);
    -        config.setHomeSp(createHomeSp());
    -        config.setAaaServerTrustedNames(
    -                new String[] {"trusted.fqdn.com", "another-trusted.fqdn.com"});
    -        config.setCredential(createCredential());
    -        config.setPolicy(createPolicy());
    -        config.setSubscriptionUpdate(createSubscriptionUpdate());
    -        Map trustRootCertList = new HashMap<>();
    -        trustRootCertList.put("trustRoot.cert1.com",
    -                new byte[CERTIFICATE_FINGERPRINT_BYTES]);
    -        trustRootCertList.put("trustRoot.cert2.com",
    -                new byte[CERTIFICATE_FINGERPRINT_BYTES]);
    -        config.setTrustRootCertList(trustRootCertList);
    -        config.setUpdateIdentifier(1);
    -        config.setCredentialPriority(120);
    -        config.setSubscriptionCreationTimeInMillis(231200);
    -        config.setSubscriptionExpirationTimeInMillis(2134232);
    -        config.setSubscriptionType("Gold");
    -        config.setUsageLimitUsageTimePeriodInMinutes(3600);
    -        config.setUsageLimitStartTimeInMillis(124214213);
    -        config.setUsageLimitDataLimit(14121);
    -        config.setUsageLimitTimeLimitInMinutes(78912);
    -        Map friendlyNames = new HashMap<>();
    -        friendlyNames.put("en", "ServiceName1");
    -        friendlyNames.put("kr", "ServiceName2");
    -        config.setServiceFriendlyNames(friendlyNames);
    -        return config;
    -    }
    -
         /**
          * Verify parcel write and read consistency for the given configuration.
          *
    @@ -209,7 +71,7 @@ public class PasspointConfigurationTest {
          */
         @Test
         public void verifyParcelWithFullConfiguration() throws Exception {
    -        verifyParcel(createConfig());
    +        verifyParcel(PasspointTestUtils.createConfig());
         }
     
         /**
    @@ -219,7 +81,7 @@ public class PasspointConfigurationTest {
          */
         @Test
         public void verifyParcelWithoutServiceNames() throws Exception {
    -        PasspointConfiguration config = createConfig();
    +        PasspointConfiguration config = PasspointTestUtils.createConfig();
             config.setServiceFriendlyNames(null);
             verifyParcel(config);
         }
    @@ -231,7 +93,7 @@ public class PasspointConfigurationTest {
          */
         @Test
         public void verifyParcelWithoutHomeSP() throws Exception {
    -        PasspointConfiguration config = createConfig();
    +        PasspointConfiguration config = PasspointTestUtils.createConfig();
             config.setHomeSp(null);
             verifyParcel(config);
         }
    @@ -243,7 +105,7 @@ public class PasspointConfigurationTest {
          */
         @Test
         public void verifyParcelWithoutCredential() throws Exception {
    -        PasspointConfiguration config = createConfig();
    +        PasspointConfiguration config = PasspointTestUtils.createConfig();
             config.setCredential(null);
             verifyParcel(config);
         }
    @@ -255,7 +117,7 @@ public class PasspointConfigurationTest {
          */
         @Test
         public void verifyParcelWithoutPolicy() throws Exception {
    -        PasspointConfiguration config = createConfig();
    +        PasspointConfiguration config = PasspointTestUtils.createConfig();
             config.setPolicy(null);
             verifyParcel(config);
         }
    @@ -267,7 +129,7 @@ public class PasspointConfigurationTest {
          */
         @Test
         public void verifyParcelWithoutSubscriptionUpdate() throws Exception {
    -        PasspointConfiguration config = createConfig();
    +        PasspointConfiguration config = PasspointTestUtils.createConfig();
             config.setSubscriptionUpdate(null);
             verifyParcel(config);
         }
    @@ -280,7 +142,7 @@ public class PasspointConfigurationTest {
          */
         @Test
         public void verifyParcelWithoutTrustRootCertList() throws Exception {
    -        PasspointConfiguration config = createConfig();
    +        PasspointConfiguration config = PasspointTestUtils.createConfig();
             config.setTrustRootCertList(null);
             verifyParcel(config);
         }
    @@ -293,7 +155,7 @@ public class PasspointConfigurationTest {
          */
         @Test
         public void verifyParcelWithoutAaaServerTrustedNames() throws Exception {
    -        PasspointConfiguration config = createConfig();
    +        PasspointConfiguration config = PasspointTestUtils.createConfig();
             config.setAaaServerTrustedNames(null);
             verifyParcel(config);
         }
    @@ -318,7 +180,7 @@ public class PasspointConfigurationTest {
          */
         @Test
         public void validateFullConfig() throws Exception {
    -        PasspointConfiguration config = createConfig();
    +        PasspointConfiguration config = PasspointTestUtils.createConfig();
     
             assertTrue(config.validate());
             assertTrue(config.validateForR2());
    @@ -332,7 +194,7 @@ public class PasspointConfigurationTest {
          */
         @Test
         public void validateFullConfigWithoutUpdateIdentifier() throws Exception {
    -        PasspointConfiguration config = createConfig();
    +        PasspointConfiguration config = PasspointTestUtils.createConfig();
             config.setUpdateIdentifier(Integer.MIN_VALUE);
     
             assertTrue(config.validate());
    @@ -346,7 +208,7 @@ public class PasspointConfigurationTest {
          */
         @Test
         public void validateConfigWithoutCredential() throws Exception {
    -        PasspointConfiguration config = createConfig();
    +        PasspointConfiguration config = PasspointTestUtils.createConfig();
             config.setCredential(null);
     
             assertFalse(config.validate());
    @@ -360,7 +222,7 @@ public class PasspointConfigurationTest {
          */
         @Test
         public void validateConfigWithoutHomeSp() throws Exception {
    -        PasspointConfiguration config = createConfig();
    +        PasspointConfiguration config = PasspointTestUtils.createConfig();
             config.setHomeSp(null);
     
             assertFalse(config.validate());
    @@ -375,7 +237,7 @@ public class PasspointConfigurationTest {
          */
         @Test
         public void validateConfigWithoutPolicy() throws Exception {
    -        PasspointConfiguration config = createConfig();
    +        PasspointConfiguration config = PasspointTestUtils.createConfig();
             config.setPolicy(null);
     
             assertTrue(config.validate());
    @@ -390,7 +252,7 @@ public class PasspointConfigurationTest {
          */
         @Test
         public void validateConfigWithoutSubscriptionUpdate() throws Exception {
    -        PasspointConfiguration config = createConfig();
    +        PasspointConfiguration config = PasspointTestUtils.createConfig();
             config.setSubscriptionUpdate(null);
     
             assertTrue(config.validate());
    @@ -405,7 +267,7 @@ public class PasspointConfigurationTest {
          */
         @Test
         public void validateConfigWithoutAaaServerTrustedNames() throws Exception {
    -        PasspointConfiguration config = createConfig();
    +        PasspointConfiguration config = PasspointTestUtils.createConfig();
             config.setAaaServerTrustedNames(null);
     
             assertTrue(config.validate());
    @@ -420,7 +282,7 @@ public class PasspointConfigurationTest {
          */
         @Test
         public void validateConfigWithInvalidTrustRootCertUrl() throws Exception {
    -        PasspointConfiguration config = createConfig();
    +        PasspointConfiguration config = PasspointTestUtils.createConfig();
             byte[] rawUrlBytes = new byte[MAX_URL_BYTES + 1];
             Map trustRootCertList = new HashMap<>();
             Arrays.fill(rawUrlBytes, (byte) 'a');
    @@ -445,7 +307,7 @@ public class PasspointConfigurationTest {
          */
         @Test
         public void validateConfigWithInvalidTrustRootCertFingerprint() throws Exception {
    -        PasspointConfiguration config = createConfig();
    +        PasspointConfiguration config = PasspointTestUtils.createConfig();
             Map trustRootCertList = new HashMap<>();
             trustRootCertList.put("test.cert.com", new byte[CERTIFICATE_FINGERPRINT_BYTES + 1]);
             config.setTrustRootCertList(trustRootCertList);
    @@ -482,7 +344,7 @@ public class PasspointConfigurationTest {
          */
         @Test
         public void validateCopyConstructorWithValidSource() throws Exception {
    -        PasspointConfiguration sourceConfig = createConfig();
    +        PasspointConfiguration sourceConfig = PasspointTestUtils.createConfig();
             PasspointConfiguration copyConfig = new PasspointConfiguration(sourceConfig);
             assertTrue(copyConfig.equals(sourceConfig));
         }
    diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointTestUtils.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointTestUtils.java
    new file mode 100644
    index 000000000000..adf74ebe36e5
    --- /dev/null
    +++ b/wifi/tests/src/android/net/wifi/hotspot2/PasspointTestUtils.java
    @@ -0,0 +1,163 @@
    +/*
    + * 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.hotspot2;
    +
    +import android.net.wifi.EAPConstants;
    +import android.net.wifi.hotspot2.pps.Credential;
    +import android.net.wifi.hotspot2.pps.HomeSp;
    +import android.net.wifi.hotspot2.pps.Policy;
    +import android.net.wifi.hotspot2.pps.UpdateParameter;
    +import android.util.Base64;
    +
    +import java.util.ArrayList;
    +import java.util.HashMap;
    +import java.util.List;
    +import java.util.Map;
    +
    +public class PasspointTestUtils {
    +    private static final int CERTIFICATE_FINGERPRINT_BYTES = 32;
    +
    +    /**
    +     * Utility function for creating a {@link android.net.wifi.hotspot2.pps.HomeSP}.
    +     *
    +     * @return {@link android.net.wifi.hotspot2.pps.HomeSP}
    +     */
    +    private static HomeSp createHomeSp() {
    +        HomeSp homeSp = new HomeSp();
    +        homeSp.setFqdn("fqdn");
    +        homeSp.setFriendlyName("friendly name");
    +        homeSp.setRoamingConsortiumOis(new long[] {0x55, 0x66});
    +        return homeSp;
    +    }
    +
    +    /**
    +     * Utility function for creating a {@link android.net.wifi.hotspot2.pps.Credential}.
    +     *
    +     * @return {@link android.net.wifi.hotspot2.pps.Credential}
    +     */
    +    private static Credential createCredential() {
    +        Credential cred = new Credential();
    +        cred.setRealm("realm");
    +        cred.setUserCredential(null);
    +        cred.setCertCredential(null);
    +        cred.setSimCredential(new Credential.SimCredential());
    +        cred.getSimCredential().setImsi("1234*");
    +        cred.getSimCredential().setEapType(EAPConstants.EAP_SIM);
    +        cred.setCaCertificate(null);
    +        cred.setClientCertificateChain(null);
    +        cred.setClientPrivateKey(null);
    +        return cred;
    +    }
    +
    +    /**
    +     * Helper function for creating a {@link Policy} for testing.
    +     *
    +     * @return {@link Policy}
    +     */
    +    private static Policy createPolicy() {
    +        Policy policy = new Policy();
    +        policy.setMinHomeDownlinkBandwidth(123);
    +        policy.setMinHomeUplinkBandwidth(345);
    +        policy.setMinRoamingDownlinkBandwidth(567);
    +        policy.setMinRoamingUplinkBandwidth(789);
    +        policy.setMaximumBssLoadValue(12);
    +        policy.setExcludedSsidList(new String[] {"ssid1", "ssid2"});
    +        HashMap requiredProtoPortMap = new HashMap<>();
    +        requiredProtoPortMap.put(12, "23,342,123");
    +        requiredProtoPortMap.put(23, "789,372,1235");
    +        policy.setRequiredProtoPortMap(requiredProtoPortMap);
    +
    +        List preferredRoamingPartnerList = new ArrayList<>();
    +        Policy.RoamingPartner partner1 = new Policy.RoamingPartner();
    +        partner1.setFqdn("partner1.com");
    +        partner1.setFqdnExactMatch(true);
    +        partner1.setPriority(12);
    +        partner1.setCountries("us,jp");
    +        Policy.RoamingPartner partner2 = new Policy.RoamingPartner();
    +        partner2.setFqdn("partner2.com");
    +        partner2.setFqdnExactMatch(false);
    +        partner2.setPriority(42);
    +        partner2.setCountries("ca,fr");
    +        preferredRoamingPartnerList.add(partner1);
    +        preferredRoamingPartnerList.add(partner2);
    +        policy.setPreferredRoamingPartnerList(preferredRoamingPartnerList);
    +
    +        UpdateParameter policyUpdate = new UpdateParameter();
    +        policyUpdate.setUpdateIntervalInMinutes(1712);
    +        policyUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_OMADM);
    +        policyUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_HOMESP);
    +        policyUpdate.setServerUri("policy.update.com");
    +        policyUpdate.setUsername("username");
    +        policyUpdate.setBase64EncodedPassword(
    +                Base64.encodeToString("password".getBytes(), Base64.DEFAULT));
    +        policyUpdate.setTrustRootCertUrl("trust.cert.com");
    +        policyUpdate.setTrustRootCertSha256Fingerprint(
    +                new byte[CERTIFICATE_FINGERPRINT_BYTES]);
    +        policy.setPolicyUpdate(policyUpdate);
    +
    +        return policy;
    +    }
    +
    +    private static UpdateParameter createSubscriptionUpdate() {
    +        UpdateParameter subUpdate = new UpdateParameter();
    +        subUpdate.setUpdateIntervalInMinutes(9021);
    +        subUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_SSP);
    +        subUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER);
    +        subUpdate.setServerUri("subscription.update.com");
    +        subUpdate.setUsername("subUsername");
    +        subUpdate.setBase64EncodedPassword(
    +                Base64.encodeToString("subPassword".getBytes(), Base64.DEFAULT));
    +        subUpdate.setTrustRootCertUrl("subscription.trust.cert.com");
    +        subUpdate.setTrustRootCertSha256Fingerprint(new byte[CERTIFICATE_FINGERPRINT_BYTES]);
    +        return subUpdate;
    +    }
    +    /**
    +     * Helper function for creating a {@link PasspointConfiguration} for testing.
    +     *
    +     * @return {@link PasspointConfiguration}
    +     */
    +    public static PasspointConfiguration createConfig() {
    +        PasspointConfiguration config = new PasspointConfiguration();
    +        config.setUpdateIdentifier(1234);
    +        config.setHomeSp(createHomeSp());
    +        config.setAaaServerTrustedNames(
    +                new String[] {"trusted.fqdn.com", "another-trusted.fqdn.com"});
    +        config.setCredential(createCredential());
    +        config.setPolicy(createPolicy());
    +        config.setSubscriptionUpdate(createSubscriptionUpdate());
    +        Map trustRootCertList = new HashMap<>();
    +        trustRootCertList.put("trustRoot.cert1.com",
    +                new byte[CERTIFICATE_FINGERPRINT_BYTES]);
    +        trustRootCertList.put("trustRoot.cert2.com",
    +                new byte[CERTIFICATE_FINGERPRINT_BYTES]);
    +        config.setTrustRootCertList(trustRootCertList);
    +        config.setUpdateIdentifier(1);
    +        config.setCredentialPriority(120);
    +        config.setSubscriptionCreationTimeInMillis(231200);
    +        config.setSubscriptionExpirationTimeInMillis(2134232);
    +        config.setSubscriptionType("Gold");
    +        config.setUsageLimitUsageTimePeriodInMinutes(3600);
    +        config.setUsageLimitStartTimeInMillis(124214213);
    +        config.setUsageLimitDataLimit(14121);
    +        config.setUsageLimitTimeLimitInMinutes(78912);
    +        Map friendlyNames = new HashMap<>();
    +        friendlyNames.put("en", "ServiceName1");
    +        friendlyNames.put("kr", "ServiceName2");
    +        config.setServiceFriendlyNames(friendlyNames);
    +        return config;
    +    }
    +}
    -- 
    cgit v1.2.3
    
    
    From ee434e819482cc48baec1b3fa3bcd11f26434e10 Mon Sep 17 00:00:00 2001
    From: "Nate(Qiang) Jiang" 
    Date: Wed, 9 Oct 2019 16:47:39 -0700
    Subject: [WifiManager] add public API to register callback on scan result
    
    Bug: 142680108
    Test: atest android.net.wifi
    Test: atest com.android.server.wifi
    
    Change-Id: I370a972c166242d31d21672c9d8023258664968a
    ---
     .../android/net/wifi/IScanResultsListener.aidl     | 27 +++++++
     wifi/java/android/net/wifi/IWifiManager.aidl       |  5 ++
     wifi/java/android/net/wifi/WifiManager.java        | 86 ++++++++++++++++++++++
     .../com/android/server/wifi/BaseWifiService.java   | 12 +++
     .../src/android/net/wifi/WifiManagerTest.java      | 68 ++++++++++++++++-
     5 files changed, 196 insertions(+), 2 deletions(-)
     create mode 100644 wifi/java/android/net/wifi/IScanResultsListener.aidl
    
    (limited to 'wifi')
    
    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/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
    index b7e109463dab..13377390fc04 100644
    --- a/wifi/java/android/net/wifi/IWifiManager.aidl
    +++ b/wifi/java/android/net/wifi/IWifiManager.aidl
    @@ -28,6 +28,7 @@ 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;
    @@ -227,4 +228,8 @@ interface IWifiManager
         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);
     }
    diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
    index 5496e83811f8..dd9ee3b4d793 100644
    --- a/wifi/java/android/net/wifi/WifiManager.java
    +++ b/wifi/java/android/net/wifi/WifiManager.java
    @@ -5104,4 +5104,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)}
    +     * 

    + * Applications should have the + * {@link android.Manifest.permission#ACCESS_WIFI_STATE} permission. Callers + * without the permission will trigger a {@link java.lang.SecurityException}. + *

    + * + * @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/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index 4ca2a16252d6..94fb5ae4d61c 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -26,6 +26,7 @@ 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; @@ -515,4 +516,15 @@ public class BaseWifiService extends IWifiManager.Stub { 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(); + } } diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 885139b99b5f..f8a0c8f5fab8 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -59,6 +59,7 @@ import android.net.wifi.WifiManager.LocalOnlyHotspotSubscription; import android.net.wifi.WifiManager.NetworkRequestMatchCallback; import android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback; import android.net.wifi.WifiManager.OnWifiUsabilityStatsListener; +import android.net.wifi.WifiManager.ScanResultsListener; import android.net.wifi.WifiManager.SoftApCallback; import android.net.wifi.WifiManager.TrafficStateCallback; import android.os.Binder; @@ -102,13 +103,14 @@ public class WifiManagerTest { android.net.wifi.IWifiManager mWifiService; @Mock ApplicationInfo mApplicationInfo; @Mock WifiConfiguration mApConfig; - @Mock IBinder mAppBinder; @Mock SoftApCallback mSoftApCallback; @Mock TrafficStateCallback mTrafficStateCallback; @Mock NetworkRequestMatchCallback mNetworkRequestMatchCallback; @Mock OnWifiUsabilityStatsListener mOnWifiUsabilityStatsListener; + @Mock ScanResultsListener mScanResultListener; + @Mock Executor mCallbackExecutor; + @Mock Executor mExecutor; - private Executor mExecutor; private Handler mHandler; private TestLooper mLooper; private WifiManager mWifiManager; @@ -1711,4 +1713,66 @@ i * Verify that a call to cancel WPS immediately returns a failure. mLooper.dispatchAll(); verify(externalListener).onFailure(WifiManager.BUSY); } + + /** + * Verify an IllegalArgumentException is thrown if listener is not provided. + */ + @Test(expected = IllegalArgumentException.class) + public void testAddScanResultsListenerWithNullListener() throws Exception { + mWifiManager.addScanResultsListener(mCallbackExecutor, null); + } + + /** + * Verify an IllegalArgumentException is thrown if executor is not provided. + */ + @Test(expected = IllegalArgumentException.class) + public void testAddScanResultsListenerWithNullExecutor() throws Exception { + mWifiManager.addScanResultsListener(null, mScanResultListener); + } + + /** + * Verify client provided listener is being called to the right listener. + */ + @Test + public void testAddScanResultsListenerAndReceiveEvent() throws Exception { + ArgumentCaptor callbackCaptor = + ArgumentCaptor.forClass(IScanResultsListener.Stub.class); + Executor executor = new SynchronousExecutor(); + mWifiManager.addScanResultsListener(executor, mScanResultListener); + verify(mWifiService).registerScanResultsListener(any(IBinder.class), + callbackCaptor.capture(), anyInt()); + callbackCaptor.getValue().onScanResultsAvailable(); + verify(mScanResultListener).onScanResultsAvailable(); + } + + /** + * Verify client provided listener is being called on the right executor. + */ + @Test + public void testAddScanResultsListenerWithTheTargetExecutor() throws Exception { + ArgumentCaptor callbackCaptor = + ArgumentCaptor.forClass(IScanResultsListener.Stub.class); + mWifiManager.addScanResultsListener(mExecutor, mScanResultListener); + verify(mWifiService).registerScanResultsListener(any(IBinder.class), + callbackCaptor.capture(), anyInt()); + callbackCaptor.getValue().onScanResultsAvailable(); + verify(mExecutor).execute(any(Runnable.class)); + } + + /** + * Verify client removeScanResultsListener. + */ + @Test + public void testRemoveScanResultsListener() throws Exception { + mWifiManager.removeScanResultsListener(mScanResultListener); + verify(mWifiService).unregisterScanResultsListener(anyInt()); + } + + /** + * Verify client removeScanResultsListener with null listener will cause an exception. + */ + @Test(expected = IllegalArgumentException.class) + public void testRemoveScanResultsListenerWithNullListener() throws Exception { + mWifiManager.removeScanResultsListener(null); + } } -- cgit v1.2.3 From dd6e10977ebc1db809f4c832f4cfd15d5850bfce Mon Sep 17 00:00:00 2001 From: David Su Date: Fri, 11 Oct 2019 18:59:41 +0000 Subject: Promote @hide APIs to @SystemApi for tethering Bug: 142372871 Test: compiles Change-Id: I91f143cdc23c6dce8921931a591298ee0c1a1c00 --- wifi/java/android/net/wifi/WifiManager.java | 41 ++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 9 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 5496e83811f8..769e306fa9cc 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; @@ -533,7 +534,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 @@ -541,7 +544,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 = { @@ -647,6 +651,7 @@ public class WifiManager { * * @hide */ + @SystemApi public static final int IFACE_IP_MODE_UNSPECIFIED = -1; /** @@ -656,6 +661,7 @@ public class WifiManager { * * @hide */ + @SystemApi public static final int IFACE_IP_MODE_CONFIGURATION_ERROR = 0; /** @@ -665,6 +671,7 @@ public class WifiManager { * * @hide */ + @SystemApi public static final int IFACE_IP_MODE_TETHERED = 1; /** @@ -674,6 +681,7 @@ public class WifiManager { * * @hide */ + @SystemApi public static final int IFACE_IP_MODE_LOCAL_ONLY = 2; /** @@ -2661,16 +2669,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) { @@ -2693,6 +2706,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(); @@ -2710,6 +2728,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(); -- cgit v1.2.3 From 7aad3c84ed96afee5d092727ff86587489c5e0e3 Mon Sep 17 00:00:00 2001 From: Ahmed ElArabawy Date: Wed, 28 Aug 2019 17:47:28 -0700 Subject: Wifi: Settings to have access to Wifi technology This CL adds to WifiInfo structure information about the Wifi technology. This makes it available to Settings app to use to present in user interface. Bug: 138634524 Bug: 140168755 Test: atest com.android.wifi.server Change-Id: I8aae8e8928462be7729c85fc15e0e7bdd97c1e6e --- wifi/java/android/net/wifi/WifiInfo.java | 66 ++++++++++++++++++++++- wifi/tests/src/android/net/wifi/WifiInfoTest.java | 3 ++ 2 files changed, 68 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java index 0b557942c87b..62ba95dc806b 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 { @@ -95,6 +98,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. */ @@ -286,6 +330,7 @@ public class WifiInfo implements Parcelable { txSuccessRate = source.txSuccessRate; rxSuccessRate = source.rxSuccessRate; score = source.score; + mWifiTechnology = source.mWifiTechnology; } } @@ -373,6 +418,22 @@ public class WifiInfo implements Parcelable { mRssi = rssi; } + /** + * 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. @@ -679,6 +740,7 @@ public class WifiInfo implements Parcelable { .append(", MAC: ").append(mMacAddress == null ? none : mMacAddress) .append(", Supplicant state: ") .append(mSupplicantState == null ? none : mSupplicantState) + .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) @@ -734,6 +796,7 @@ public class WifiInfo implements Parcelable { dest.writeString(mNetworkSuggestionOrSpecifierPackageName); dest.writeString(mFqdn); dest.writeString(mProviderFriendlyName); + dest.writeInt(mWifiTechnology); } /** Implement the Parcelable interface {@hide} */ @@ -775,6 +838,7 @@ public class WifiInfo implements Parcelable { info.mNetworkSuggestionOrSpecifierPackageName = in.readString(); info.mFqdn = in.readString(); info.mProviderFriendlyName = in.readString(); + info.mWifiTechnology = in.readInt(); return info; } diff --git a/wifi/tests/src/android/net/wifi/WifiInfoTest.java b/wifi/tests/src/android/net/wifi/WifiInfoTest.java index 0ce5d66cf4f7..ea08ea8e8333 100644 --- a/wifi/tests/src/android/net/wifi/WifiInfoTest.java +++ b/wifi/tests/src/android/net/wifi/WifiInfoTest.java @@ -38,6 +38,7 @@ public class WifiInfoTest { private static final String TEST_PACKAGE_NAME = "com.test.example"; private static final String TEST_FQDN = "test.com"; private static final String TEST_PROVIDER_NAME = "test"; + private static final int TEST_WIFI_TECHNOLOGY = WifiInfo.WIFI_TECHNOLOGY_11AC; /** * Verify parcel write/read with WifiInfo. @@ -54,6 +55,7 @@ public class WifiInfoTest { writeWifiInfo.setFQDN(TEST_FQDN); writeWifiInfo.setProviderFriendlyName(TEST_PROVIDER_NAME); writeWifiInfo.setNetworkSuggestionOrSpecifierPackageName(TEST_PACKAGE_NAME); + writeWifiInfo.setWifiTechnology(TEST_WIFI_TECHNOLOGY); Parcel parcel = Parcel.obtain(); writeWifiInfo.writeToParcel(parcel, 0); @@ -72,5 +74,6 @@ public class WifiInfoTest { assertEquals(TEST_PACKAGE_NAME, readWifiInfo.getNetworkSuggestionOrSpecifierPackageName()); assertEquals(TEST_FQDN, readWifiInfo.getPasspointFqdn()); assertEquals(TEST_PROVIDER_NAME, readWifiInfo.getPasspointProviderFriendlyName()); + assertEquals(TEST_WIFI_TECHNOLOGY, readWifiInfo.getWifiTechnology()); } } -- cgit v1.2.3 From 511ed1f6accc9e593ae3959da6dd59eb65779f12 Mon Sep 17 00:00:00 2001 From: David Su Date: Mon, 21 Oct 2019 13:29:00 -0700 Subject: Fix checkNotNull(a, b) usages checkNotNull(a, b) does not check nullness of b, instead b is the error message. Fix these usages. Bug: 143084514 Test: compiles Change-Id: Icd9e9a213141ad50be888b3afd17a69fe3215282 --- wifi/java/android/net/wifi/WifiNetworkSpecifier.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'wifi') 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; } -- cgit v1.2.3 From 10740295281cf37e4854405814433f51237bd514 Mon Sep 17 00:00:00 2001 From: Quang Luong Date: Mon, 14 Oct 2019 17:29:46 -0700 Subject: Add @SystemApi allowAutojoin(int, boolean) to WifiManager WifiManager.allowAutojoin(int, boolean) lets a user toggle whether a saved network should be allowed to be auto-joined. This "allowAutojoin" bit is stored within the WifiConfiguration of a saved network. Bug: 139199957 Test: atest FrameworksWifiApiTests Change-Id: Ia8650abb59dc53a010accc44bd7b6e28facce992 --- wifi/java/android/net/wifi/IWifiManager.aidl | 2 ++ wifi/java/android/net/wifi/WifiConfiguration.java | 12 +++++++++++ wifi/java/android/net/wifi/WifiManager.java | 23 ++++++++++++++++++++++ .../com/android/server/wifi/BaseWifiService.java | 5 +++++ .../src/android/net/wifi/WifiManagerTest.java | 10 ++++++++++ 5 files changed, 52 insertions(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index b7e109463dab..2cdd74c7180a 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -93,6 +93,8 @@ interface IWifiManager boolean disableNetwork(int netId, String packageName); + void allowAutojoin(int netId, boolean choice); + boolean startScan(String packageName); List getScanResults(String callingPackage); diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 2afb14a12110..3bedddc8ec7d 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -735,6 +735,14 @@ public class WifiConfiguration implements Parcelable { */ public int userApproved = USER_UNSPECIFIED; + /** + * @hide + * Auto-join is allowed by user for this network. + * Default true. + */ + @SystemApi + public boolean allowAutojoin = true; + /** The Below RSSI thresholds are used to configure AutoJoin * - GOOD/LOW/BAD thresholds are used so as to calculate link score * - UNWANTED_SOFT are used by the blacklisting logic so as to handle @@ -2022,6 +2030,7 @@ public class WifiConfiguration implements Parcelable { if (updateIdentifier != null) sbuf.append(" updateIdentifier=" + updateIdentifier); sbuf.append(" lcuid=" + lastConnectUid); sbuf.append(" userApproved=" + userApprovedAsString(userApproved)); + sbuf.append(" allowAutojoin=" + allowAutojoin); sbuf.append(" noInternetAccessExpected=" + noInternetAccessExpected); sbuf.append(" "); @@ -2421,6 +2430,7 @@ public class WifiConfiguration implements Parcelable { numScorerOverrideAndSwitchedNetwork = source.numScorerOverrideAndSwitchedNetwork; numAssociation = source.numAssociation; userApproved = source.userApproved; + allowAutojoin = source.allowAutojoin; numNoInternetAccessReports = source.numNoInternetAccessReports; noInternetAccessExpected = source.noInternetAccessExpected; creationTime = source.creationTime; @@ -2496,6 +2506,7 @@ public class WifiConfiguration implements Parcelable { dest.writeInt(numScorerOverrideAndSwitchedNetwork); dest.writeInt(numAssociation); dest.writeInt(userApproved); + dest.writeBoolean(allowAutojoin); dest.writeInt(numNoInternetAccessReports); dest.writeInt(noInternetAccessExpected ? 1 : 0); dest.writeInt(shared ? 1 : 0); @@ -2571,6 +2582,7 @@ public class WifiConfiguration implements Parcelable { config.numScorerOverrideAndSwitchedNetwork = in.readInt(); config.numAssociation = in.readInt(); config.userApproved = in.readInt(); + config.allowAutojoin = in.readBoolean(); config.numNoInternetAccessReports = in.readInt(); config.noInternetAccessExpected = in.readInt() != 0; config.shared = in.readInt() != 0; diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 5496e83811f8..9e675401fc04 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -3841,6 +3841,29 @@ public class WifiManager { } } + /** + * Sets the user choice for allowing auto-join to a network. + * The updated choice will be made available through the updated config supplied by the + * CONFIGURED_NETWORKS_CHANGED broadcast. + * + * @param netId the id of the network to allow/disallow autojoin for. + * @param choice true to allow autojoin, false to disallow autojoin + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) + public void allowAutojoin(int netId, boolean choice) { + try { + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.allowAutojoin(netId, choice); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Disable ephemeral Network * diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index 4ca2a16252d6..02ca74ac4886 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -166,6 +166,11 @@ public class BaseWifiService extends IWifiManager.Stub { throw new UnsupportedOperationException(); } + @Override + public void allowAutojoin(int netId, boolean choice) { + throw new UnsupportedOperationException(); + } + @Override public boolean startScan(String packageName) { throw new UnsupportedOperationException(); diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 885139b99b5f..e3764e5d2f3c 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -1486,6 +1486,16 @@ i * Verify that a call to cancel WPS immediately returns a failure. verify(mWifiService).disableNetwork(TEST_NETWORK_ID, mContext.getOpPackageName()); } + /** + * Test behavior of {@link WifiManager#allowAutojoin(int, boolean)} + * @throws Exception + */ + @Test + public void testAllowAutojoin() throws Exception { + mWifiManager.allowAutojoin(1, true); + verify(mWifiService).allowAutojoin(eq(1), eq(true)); + } + /** * Test behavior of {@link WifiManager#disconnect()} * @throws Exception -- cgit v1.2.3 From 5e1280017a98b5424c0dd364c31714de331a3121 Mon Sep 17 00:00:00 2001 From: David Su Date: Mon, 21 Oct 2019 14:31:53 -0700 Subject: Make WifiScanner#getAvailableChannels() @SystemApi While here removed some redundant comments. Bug: 129008573 Test: atest FrameworksWifiApiTests Change-Id: Id6ca5cf4547ff7321805ad671b9e25dab9953cd3 --- wifi/java/android/net/wifi/IWifiScanner.aidl | 2 +- wifi/java/android/net/wifi/WifiScanner.java | 53 ++++++++++++++++++++-------- 2 files changed, 39 insertions(+), 16 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IWifiScanner.aidl b/wifi/java/android/net/wifi/IWifiScanner.aidl index 398493439bbe..114c7320bc3a 100644 --- a/wifi/java/android/net/wifi/IWifiScanner.aidl +++ b/wifi/java/android/net/wifi/IWifiScanner.aidl @@ -26,5 +26,5 @@ interface IWifiScanner { Messenger getMessenger(); - Bundle getAvailableChannels(int band); + Bundle getAvailableChannels(int band, String packageName); } diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index 68948cbbe7a9..21189a411d94 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -17,7 +17,9 @@ package android.net.wifi; import android.Manifest; +import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.annotation.SystemApi; @@ -39,6 +41,8 @@ import com.android.internal.util.AsyncChannel; import com.android.internal.util.Preconditions; import com.android.internal.util.Protocol; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -51,26 +55,38 @@ import java.util.List; @SystemService(Context.WIFI_SCANNING_SERVICE) public class WifiScanner { - /** no band specified; use channel list instead */ - public static final int WIFI_BAND_UNSPECIFIED = 0; /* not specified */ + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"WIFI_BAND_"}, value = { + WIFI_BAND_UNSPECIFIED, + WIFI_BAND_24_GHZ, + WIFI_BAND_5_GHZ, + WIFI_BAND_BOTH, + WIFI_BAND_5_GHZ_DFS_ONLY, + WIFI_BAND_24_GHZ_WITH_5GHZ_DFS, + WIFI_BAND_5_GHZ_WITH_DFS, + WIFI_BAND_BOTH_WITH_DFS}) + public @interface WifiBand {} + /** no band specified; use channel list instead */ + public static final int WIFI_BAND_UNSPECIFIED = 0; /** 2.4 GHz band */ - public static final int WIFI_BAND_24_GHZ = 1; /* 2.4 GHz band */ + public static final int WIFI_BAND_24_GHZ = 1; /** 5 GHz band excluding DFS channels */ - public static final int WIFI_BAND_5_GHZ = 2; /* 5 GHz band without DFS channels */ + public static final int WIFI_BAND_5_GHZ = 2; + /** Both 2.4 GHz band and 5 GHz band; no DFS channels */ + public static final int WIFI_BAND_BOTH = 3; /** DFS channels from 5 GHz band only */ - public static final int WIFI_BAND_5_GHZ_DFS_ONLY = 4; /* 5 GHz band DFS channels */ + public static final int WIFI_BAND_5_GHZ_DFS_ONLY = 4; /** * 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 */ + public static final int WIFI_BAND_5_GHZ_WITH_DFS = 6; /** 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 */ + public static final int WIFI_BAND_BOTH_WITH_DFS = 7; /** * Max band value * @hide @@ -78,9 +94,9 @@ public class WifiScanner { public static final int WIFI_BAND_MAX = 8; /** Minimum supported scanning period */ - public static final int MIN_SCAN_PERIOD_MS = 1000; /* minimum supported period */ + public static final int MIN_SCAN_PERIOD_MS = 1000; /** Maximum supported scanning period */ - public static final int MAX_SCAN_PERIOD_MS = 1024000; /* maximum supported period */ + public static final int MAX_SCAN_PERIOD_MS = 1024000; /** No Error */ public static final int REASON_SUCCEEDED = 0; @@ -109,13 +125,20 @@ public class WifiScanner { } /** - * gives you all the possible channels; channel is specified as an - * integer with frequency in MHz i.e. channel 1 is 2412 + * Returns a list of all the possible channels for the given band(s). + * + * @param band one of the WifiScanner#WIFI_BAND_* constants, e.g. {@link #WIFI_BAND_24_GHZ} + * @return a list of all the frequencies, in MHz, for the given band(s) e.g. channel 1 is + * 2412, or null if an error occurred. + * * @hide */ - public List getAvailableChannels(int band) { + @SystemApi + @Nullable + @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) + public List getAvailableChannels(@WifiBand int band) { try { - Bundle bundle = mService.getAvailableChannels(band); + Bundle bundle = mService.getAvailableChannels(band, mContext.getOpPackageName()); return bundle.getIntegerArrayList(GET_AVAILABLE_CHANNELS_EXTRA); } catch (RemoteException e) { return null; -- cgit v1.2.3 From 06f9041220174cf88f684411d040f275d5f22657 Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Tue, 22 Oct 2019 12:13:31 -0700 Subject: [Passpoint] Add API to indicate OSU profile and expiration Add an API to indicate if a profile was provisioned by an OSU (subscription) server. This is necessary for the settings app to handle profile expiration date use cases, which are different between R1 (non-OSU) cases and R2 cases. Make the getSubscriptionExpirationTimeInMillis API public. Bug: 141474717 Test: atest PasspointConfigurationTest Test: atest ConfigParserTest Test: Complete OSU registration, verify API returns true Test: Install R1 profile, verify API returns false Change-Id: I788108f973a47716c5d7c9353eafedd5fb06cb8e --- .../android/net/wifi/hotspot2/ConfigParser.java | 6 ++ .../net/wifi/hotspot2/PasspointConfiguration.java | 18 ++++- .../hsr1/HSR1ProfileWithUpdateIdentifier.base64 | 88 ++++++++++++++++++++++ .../net/wifi/hotspot2/ConfigParserTest.java | 20 +++++ .../wifi/hotspot2/PasspointConfigurationTest.java | 17 ++++- .../net/wifi/hotspot2/PasspointTestUtils.java | 13 +++- 6 files changed, 156 insertions(+), 6 deletions(-) create mode 100644 wifi/tests/assets/hsr1/HSR1ProfileWithUpdateIdentifier.base64 (limited to 'wifi') 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/tests/assets/hsr1/HSR1ProfileWithUpdateIdentifier.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithUpdateIdentifier.base64 new file mode 100644 index 000000000000..f4d2abb08e36 --- /dev/null +++ b/wifi/tests/assets/hsr1/HSR1ProfileWithUpdateIdentifier.base64 @@ -0,0 +1,88 @@ +TUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5 +PXtib3VuZGFyeX07IGNoYXJzZXQ9VVRGLTgKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogYmFz +ZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXBhc3Nwb2ludC1w +cm9maWxlOyBjaGFyc2V0PVVURi04CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2NAoK +UEUxbmJYUlVjbVZsSUhodGJHNXpQU0p6ZVc1amJXdzZaRzFrWkdZeExqSWlQZ29nSUR4V1pYSkVW +RVErTVM0eVBDOVdaWEpFVkVRKwpDaUFnUEU1dlpHVStDaUFnSUNBOFRtOWtaVTVoYldVK1VHVnlV +SEp2ZG1sa1pYSlRkV0p6WTNKcGNIUnBiMjQ4TDA1dlpHVk9ZVzFsClBnb2dJQ0FnUEZKVVVISnZj +R1Z5ZEdsbGN6NEtJQ0FnSUNBZ1BGUjVjR1UrQ2lBZ0lDQWdJQ0FnUEVSRVJrNWhiV1UrZFhKdU9u +ZG0KWVRwdGJ6cG9iM1J6Y0c5ME1tUnZkREF0Y0dWeWNISnZkbWxrWlhKemRXSnpZM0pwY0hScGIy +NDZNUzR3UEM5RVJFWk9ZVzFsUGdvZwpJQ0FnSUNBOEwxUjVjR1UrQ2lBZ0lDQThMMUpVVUhKdmNH +VnlkR2xsY3o0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoCmJXVStWWEJrWVhSbFNX +UmxiblJwWm1sbGNqd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lEeFdZV3gxWlQ0eE1qTTBQQzlXWVd4 +MVpUNEsKSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoYldV +K2FUQXdNVHd2VG05a1pVNWhiV1UrQ2lBZwpJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJS +bFRtRnRaVDVJYjIxbFUxQThMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJRHhPCmIyUmxQZ29nSUNB +Z0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGtaeWFXVnVaR3g1VG1GdFpUd3ZUbTlrWlU1aGJXVStDaUFn +SUNBZ0lDQWcKSUNBOFZtRnNkV1UrUTJWdWRIVnllU0JJYjNWelpUd3ZWbUZzZFdVK0NpQWdJQ0Fn +SUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUR4TwpiMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZP +WVcxbFBrWlJSRTQ4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ1BGWmhiSFZsClBtMXBOaTVq +Ynk1MWF6d3ZWbUZzZFdVK0NpQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxQ +Z29nSUNBZ0lDQWcKSUNBZ1BFNXZaR1ZPWVcxbFBsSnZZVzFwYm1kRGIyNXpiM0owYVhWdFQwazhM +MDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEZaaApiSFZsUGpFeE1qSXpNeXcwTkRVMU5qWThM +MVpoYkhWbFBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnUEM5T2IyUmxQZ29nCklDQWdJ +Q0E4VG05a1pUNEtJQ0FnSUNBZ0lDQThUbTlrWlU1aGJXVStRM0psWkdWdWRHbGhiRHd2VG05a1pV +NWhiV1UrQ2lBZ0lDQWcKSUNBZ1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVTVoYldVK1Vt +VmhiRzA4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZwpQRlpoYkhWbFBuTm9ZV3RsYmk1emRH +bHljbVZrTG1OdmJUd3ZWbUZzZFdVK0NpQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnCklE +eE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBsVnpaWEp1WVcxbFVHRnpjM2R2Y21R +OEwwNXZaR1ZPWVcxbFBnb2cKSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4 +T2IyUmxUbUZ0WlQ1VmMyVnlibUZ0WlR3dlRtOWtaVTVoYldVKwpDaUFnSUNBZ0lDQWdJQ0FnSUR4 +V1lXeDFaVDVxWVcxbGN6d3ZWbUZzZFdVK0NpQWdJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0Fn +CklDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxCaGMzTjNiM0pr +UEM5T2IyUmxUbUZ0WlQ0S0lDQWcKSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQbGx0T1hWYVJFRjNUbmM5 +UFR3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0FnSUNBOEwwNXZaR1UrQ2lBZwpJQ0FnSUNBZ0lDQThUbTlr +WlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWxQa1ZCVUUxbGRHaHZaRHd2VG05a1pVNWhi +V1UrCkNpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0FnSUR4T2IyUmxU +bUZ0WlQ1RlFWQlVlWEJsUEM5T2IyUmwKVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnSUNBOFZtRnNk +V1UrTWpFOEwxWmhiSFZsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThMMDV2WkdVKwpDaUFnSUNBZ0lDQWdJ +Q0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeE9iMlJsVG1GdFpUNUpibTVsY2sxbGRH +aHZaRHd2ClRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQazFUTFVOSVFW +QXRWakk4TDFaaGJIVmxQZ29nSUNBZ0lDQWcKSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ0lD +QThMMDV2WkdVK0NpQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUR4TwpiMlJsUGdvZ0lD +QWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBrUnBaMmwwWVd4RFpYSjBhV1pwWTJGMFpUd3ZUbTlrWlU1 +aGJXVStDaUFnCklDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcx +bFBrTmxjblJwWm1sallYUmxWSGx3WlR3dlRtOWsKWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUR4 +V1lXeDFaVDU0TlRBNWRqTThMMVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdQQzlPYjJSbApQZ29nSUNB +Z0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0WlQ1RFpYSjBVMGhC +TWpVMlJtbHVaMlZ5CmNISnBiblE4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZz +ZFdVK01XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXgKWmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4 +WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaand2Vm1Gc2RXVStDaUFnSUNBZwpJQ0Fn +SUNBOEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJSbFBnb2dJ +Q0FnSUNBZ0lDQWdQRTV2ClpHVk9ZVzFsUGxOSlRUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJ +Q0E4VG05a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEU1dlpHVk8KWVcxbFBrbE5VMGs4TDA1dlpHVk9Z +VzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzZFdVK2FXMXphVHd2Vm1Gc2RXVStDaUFnSUNBZwpJ +Q0FnSUNBOEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BF +NXZaR1ZPWVcxbFBrVkJVRlI1CmNHVThMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBOFZt +RnNkV1UrTWpROEwxWmhiSFZsUGdvZ0lDQWdJQ0FnSUNBZ1BDOU8KYjJSbFBnb2dJQ0FnSUNBZ0lE +d3ZUbTlrWlQ0S0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ1BDOU9iMlJsUGdvZ0lEd3ZUbTlrWlQ0 +SwpQQzlOWjIxMFZISmxaVDRLCgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlv +bi94LXg1MDktY2EtY2VydApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKCkxTMHRM +UzFDUlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVJMUkVORFFXaERaMEYzU1VKQlow +bEtRVWxNYkVaa2QzcE0KVm5WeVRVRXdSME5UY1VkVFNXSXpSRkZGUWtOM1ZVRk5Ra2w0UlVSQlQw +Sm5UbFlLUWtGTlZFSXdWa0pWUTBKRVVWUkZkMGhvWTA1TgpWRmwzVFZSRmVVMVVSVEZOUkVVeFYy +aGpUazFxV1hkTlZFRTFUVlJGTVUxRVJURlhha0ZUVFZKQmR3cEVaMWxFVmxGUlJFVjNaRVpSClZr +Rm5VVEJGZUUxSlNVSkpha0ZPUW1kcmNXaHJhVWM1ZHpCQ1FWRkZSa0ZCVDBOQlVUaEJUVWxKUWtO +blMwTkJVVVZCQ25wdVFWQlYKZWpJMlRYTmhaVFIzY3pRelkzcFNOREV2U2pKUmRISlRTVnBWUzIx +V1ZYTldkVzFFWWxsSWNsQk9kbFJZUzFOTldFRmpaWGRQVWtSUgpXVmdLVW5GMlNIWndiamhEYzJO +Q01TdHZSMWhhZGtoM2VHbzBlbFl3VjB0dlN6SjZaVmhyWVhVemRtTjViRE5JU1V0MWNFcG1jVEpV +ClJVRkRaV1pXYW1vd2RBcEtWeXRZTXpWUVIxZHdPUzlJTlhwSlZVNVdUbFpxVXpkVmJYTTRORWwy +UzJoU1FqZzFNVEpRUWpsVmVVaGgKWjFoWlZsZzFSMWR3UVdOV2NIbG1jbXhTQ2taSk9WRmthR2dy +VUdKck1IVjVhM1JrWW1ZdlEyUm1aMGhQYjJWaWNsUjBkMUpzYWswdwpiMFIwV0NzeVEzWTJhakIz +UWtzM2FFUTRjRkIyWmpFcmRYa0tSM3BqZW1sblFWVXZORXQzTjJWYWNYbGtaamxDS3pWU2RYQlNL +MGxhCmFYQllOREY0UldsSmNrdFNkM0ZwTlRFM1YxZDZXR05xWVVjeVkwNWlaalExTVFwNGNFZzFV +RzVXTTJreGRIRXdOR3BOUjFGVmVrWjMKU1VSQlVVRkNielJIUVUxSU5IZElVVmxFVmxJd1QwSkNX +VVZHU1hkWU5IWnpPRUpwUW1OVFkyOWtDalZ1YjFwSVVrMDRSVFFyYVUxRgpTVWRCTVZWa1NYZFJO +MDFFYlVGR1NYZFlOSFp6T0VKcFFtTlRZMjlrTlc1dldraFNUVGhGTkN0cGIxSmhhMFpFUVZNS1RW +SkJkMFJuCldVUldVVkZFUlhka1JsRldRV2RSTUVWNFoyZHJRV2QxVlZZelJFMTBWelp6ZDBSQldV +UldVakJVUWtGVmQwRjNSVUl2ZWtGTVFtZE8KVmdwSVVUaEZRa0ZOUTBGUldYZEVVVmxLUzI5YVNX +aDJZMDVCVVVWTVFsRkJSR2RuUlVKQlJtWlJjVTlVUVRkU2RqZExLMngxVVRkdwpibUZ6TkVKWmQw +aEZDamxIUlZBdmRXOW9kalpMVDNrd1ZFZFJSbUp5VWxScVJtOU1WazVDT1VKYU1YbHRUVVJhTUM5 +VVNYZEpWV00zCmQyazNZVGgwTlcxRmNWbElNVFV6ZDFjS1lWZHZiMmxUYW5sTVRHaDFTVFJ6VG5K +T1EwOTBhWE5rUW5FeWNqSk5SbGgwTm1nd2JVRlIKV1U5UWRqaFNPRXMzTDJablUzaEhSbkY2YUhs +T2JXMVdUQW94Y1VKS2JHUjRNelJUY0hkelZFRk1VVlpRWWpSb1IzZEtlbHBtY2pGUQpZM0JGVVhn +MmVFMXVWR3c0ZUVWWFdrVXpUWE01T1hWaFZYaGlVWEZKZDFKMUNreG5RVTlyVGtOdFdUSnRPRGxX +YUhwaFNFb3hkVlk0Ck5VRmtUUzkwUkN0WmMyMXNibTVxZERsTVVrTmxhbUpDYVhCcVNVZHFUMWh5 +WnpGS1VDdHNlRllLYlhWTk5IWklLMUF2Yld4dGVITlEKVUhvd1pEWTFZaXRGUjIxS1duQnZUR3RQ +TDNSa1RrNTJRMWw2YWtwd1ZFVlhjRVZ6VHpaT1RXaExXVzg5Q2kwdExTMHRSVTVFSUVORgpVbFJK +UmtsRFFWUkZMUzB0TFMwSwotLXtib3VuZGFyeX0tLQo= \ No newline at end of file diff --git a/wifi/tests/src/android/net/wifi/hotspot2/ConfigParserTest.java b/wifi/tests/src/android/net/wifi/hotspot2/ConfigParserTest.java index d9a1d9afff61..c815d7519c4c 100644 --- a/wifi/tests/src/android/net/wifi/hotspot2/ConfigParserTest.java +++ b/wifi/tests/src/android/net/wifi/hotspot2/ConfigParserTest.java @@ -54,6 +54,8 @@ public class ConfigParserTest { "assets/hsr1/HSR1ProfileWithInvalidContentType.base64"; private static final String PASSPOINT_INSTALLATION_FILE_WITHOUT_PROFILE = "assets/hsr1/HSR1ProfileWithoutProfile.base64"; + private static final String PASSPOINT_INSTALLATION_FILE_WITH_UPDATE_ID = + "assets/hsr1/HSR1ProfileWithUpdateIdentifier.base64"; /** * Read the content of the given resource file into a String. @@ -201,4 +203,22 @@ public class ConfigParserTest { assertNull(ConfigParser.parsePasspointConfig( "application/x-wifi-config", configStr.getBytes())); } + + /** + * Verify a valid installation file is parsed successfully with the matching contents, and that + * Update identifier is cleared. + * + * @throws Exception + */ + @Test + public void parseConfigFileWithUpdateIdentifier() throws Exception { + String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_UPDATE_ID); + PasspointConfiguration expectedConfig = generateConfigurationFromProfile(); + PasspointConfiguration actualConfig = + ConfigParser.parsePasspointConfig( + "application/x-wifi-config", configStr.getBytes()); + // Expected configuration does not contain an update identifier + assertTrue(actualConfig.equals(expectedConfig)); + } + } \ No newline at end of file diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java index c3b074eaee5a..f501b16d2c79 100644 --- a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java @@ -183,7 +183,7 @@ public class PasspointConfigurationTest { PasspointConfiguration config = PasspointTestUtils.createConfig(); assertTrue(config.validate()); - assertTrue(config.validateForR2()); + assertFalse(config.isOsuProvisioned()); } /** @@ -241,7 +241,6 @@ public class PasspointConfigurationTest { config.setPolicy(null); assertTrue(config.validate()); - assertTrue(config.validateForR2()); } /** @@ -271,7 +270,6 @@ public class PasspointConfigurationTest { config.setAaaServerTrustedNames(null); assertTrue(config.validate()); - assertTrue(config.validateForR2()); } /** @@ -348,4 +346,17 @@ public class PasspointConfigurationTest { PasspointConfiguration copyConfig = new PasspointConfiguration(sourceConfig); assertTrue(copyConfig.equals(sourceConfig)); } + + /** + * Verify that a configuration containing all fields is valid for R2. + * + * @throws Exception + */ + @Test + public void validateFullR2Config() throws Exception { + PasspointConfiguration config = PasspointTestUtils.createR2Config(); + assertTrue(config.validate()); + assertTrue(config.validateForR2()); + assertTrue(config.isOsuProvisioned()); + } } diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointTestUtils.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointTestUtils.java index adf74ebe36e5..8d55acb87f15 100644 --- a/wifi/tests/src/android/net/wifi/hotspot2/PasspointTestUtils.java +++ b/wifi/tests/src/android/net/wifi/hotspot2/PasspointTestUtils.java @@ -132,7 +132,6 @@ public class PasspointTestUtils { */ public static PasspointConfiguration createConfig() { PasspointConfiguration config = new PasspointConfiguration(); - config.setUpdateIdentifier(1234); config.setHomeSp(createHomeSp()); config.setAaaServerTrustedNames( new String[] {"trusted.fqdn.com", "another-trusted.fqdn.com"}); @@ -145,7 +144,6 @@ public class PasspointTestUtils { trustRootCertList.put("trustRoot.cert2.com", new byte[CERTIFICATE_FINGERPRINT_BYTES]); config.setTrustRootCertList(trustRootCertList); - config.setUpdateIdentifier(1); config.setCredentialPriority(120); config.setSubscriptionCreationTimeInMillis(231200); config.setSubscriptionExpirationTimeInMillis(2134232); @@ -160,4 +158,15 @@ public class PasspointTestUtils { config.setServiceFriendlyNames(friendlyNames); return config; } + + /** + * Helper function for creating an R2 {@link PasspointConfiguration} for testing. + * + * @return {@link PasspointConfiguration} + */ + public static PasspointConfiguration createR2Config() { + PasspointConfiguration config = createConfig(); + config.setUpdateIdentifier(1234); + return config; + } } -- cgit v1.2.3 From 7899942cd74e1ce0637e5c3fdaa99146611e651e Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Wed, 23 Oct 2019 15:35:03 -0700 Subject: [Passpoint] Clean up all test assets for ConfigParserTest unit test Clean up all test assets for ConfigParserTest unit test, and use generic example values. Bug: 143239550 Test: atest ConfigParserTest Change-Id: I52b4011c86ebbb780c40265fb46ea0290442572c --- .../tests/assets/hsr1/HSR1ProfileWithCACert.base64 | 142 ++++++++--------- wifi/tests/assets/hsr1/HSR1ProfileWithCACert.conf | 62 ++++---- .../hsr1/HSR1ProfileWithInvalidContentType.base64 | 171 +++++++++++---------- .../hsr1/HSR1ProfileWithMissingBoundary.base64 | 171 +++++++++++---------- .../hsr1/HSR1ProfileWithNonBase64Part.base64 | 171 +++++++++++---------- .../hsr1/HSR1ProfileWithUpdateIdentifier.base64 | 144 ++++++++--------- wifi/tests/assets/hsr1/README.txt | 3 +- .../net/wifi/hotspot2/ConfigParserTest.java | 15 +- 8 files changed, 441 insertions(+), 438 deletions(-) (limited to 'wifi') diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.base64 index 56919c25de46..760c8395e659 100644 --- a/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.base64 +++ b/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.base64 @@ -12,75 +12,75 @@ VnlkR2xsY3o0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoCmJXVSthVEF3TVR3dlRt OWtaVTVoYldVK0NpQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJSbFRtRnRaVDVJYjIx bFUxQTgKTDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1 dlpHVk9ZVzFsUGtaeWFXVnVaR3g1VG1GdApaVHd2VG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNB -OFZtRnNkV1UrUTJWdWRIVnllU0JJYjNWelpUd3ZWbUZzZFdVK0NpQWdJQ0FnCklDQWdQQzlPYjJS -bFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBrWlJSRTQ4 -TDA1dlpHVk8KWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBtMXBOaTVqYnk1MWF6d3ZWbUZz -ZFdVK0NpQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZwpJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0Fn -SUNBZ1BFNXZaR1ZPWVcxbFBsSnZZVzFwYm1kRGIyNXpiM0owYVhWdFQwazhMMDV2ClpHVk9ZVzFs -UGdvZ0lDQWdJQ0FnSUNBZ1BGWmhiSFZsUGpFeE1qSXpNeXcwTkRVMU5qWThMMVpoYkhWbFBnb2dJ -Q0FnSUNBZ0lEd3YKVG05a1pUNEtJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0E4VG05a1pUNEtJ -Q0FnSUNBZ0lDQThUbTlrWlU1aGJXVStRM0psWkdWdQpkR2xoYkR3dlRtOWtaVTVoYldVK0NpQWdJ -Q0FnSUNBZ1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVTVoYldVK1VtVmhiRzA4CkwwNXZa -R1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBuTm9ZV3RsYmk1emRHbHljbVZrTG1OdmJU -d3ZWbUZzZFdVK0NpQWcKSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lD -QWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBsVnpaWEp1WVcxbApVR0Z6YzNkdmNtUThMMDV2WkdWT1lX -MWxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0ClpU -NVZjMlZ5Ym1GdFpUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUR4V1lXeDFaVDVxWVcx -bGN6d3ZWbUZzZFdVK0NpQWcKSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05 -a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxCaApjM04zYjNKa1BDOU9iMlJsVG1G -dFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQbGx0T1hWYVJFRjNUbmM5UFR3dlZtRnNkV1Ur -CkNpQWdJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0Fn -SUNBZ0lDQWdQRTV2WkdWT1lXMWwKUGtWQlVFMWxkR2h2WkR3dlRtOWtaVTVoYldVK0NpQWdJQ0Fn -SUNBZ0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0FnSUR4TwpiMlJsVG1GdFpUNUZRVkJV -ZVhCbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnSUNBOFZtRnNkV1UrTWpFOEwxWmhi -SFZsClBnb2dJQ0FnSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmxQ -Z29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeE8KYjJSbFRtRnRaVDVKYm01bGNrMWxkR2h2WkR3dlRtOWta -VTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQazFUTFVOSQpRVkF0VmpJOEwxWmhi -SFZsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThMMDV2WkdVK0Np -QWdJQ0FnCklDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BF -NXZaR1ZPWVcxbFBrUnBaMmwwWVd4RFpYSjAKYVdacFkyRjBaVHd2VG05a1pVNWhiV1UrQ2lBZ0lD -QWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbApQa05sY25ScFpt -bGpZWFJsVkhsd1pUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUR4V1lXeDFaVDU0TlRB -NWRqTThMMVpoCmJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1 -dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNURaWEowVTBoQk1qVTJSbWx1WjJW -eWNISnBiblE4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzZFdVKwpNV1l4WmpG +OFZtRnNkV1UrUlhoaGJYQnNaU0JPWlhSM2IzSnJQQzlXWVd4MVpUNEtJQ0FnCklDQWdJQ0E4TDA1 +dlpHVStDaUFnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlU1aGJXVStSbEZF +VGp3dlRtOWsKWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4Vm1Gc2RXVSthRzkwYzNCdmRDNWxlR0Z0 +Y0d4bExtNWxkRHd2Vm1Gc2RXVStDaUFnSUNBZwpJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJRHhP +YjJSbFBnb2dJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWxQbEp2WVcxcGJtZERiMjV6CmIzSjBhWFZ0 +VDBrOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBqRXhNakl6TXl3ME5EVTFO +alk4TDFaaGJIVmwKUGdvZ0lDQWdJQ0FnSUR3dlRtOWtaVDRLSUNBZ0lDQWdQQzlPYjJSbFBnb2dJ +Q0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0E4VG05awpaVTVoYldVK1EzSmxaR1Z1ZEdsaGJEd3ZU +bTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrClpVNWhi +V1UrVW1WaGJHMDhMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQbVY0WVcxd2JH +VXVZMjl0UEM5V1lXeDEKWlQ0S0lDQWdJQ0FnSUNBOEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnUEU1dlpH +VStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrVlhObApjbTVoYldWUVlYTnpkMjl5WkR3dlRt +OWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQRTV2ClpH +Vk9ZVzFsUGxWelpYSnVZVzFsUEM5T2IyUmxUbUZ0WlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQRlpoYkhW +bFBuVnpaWEk4TDFaaGJIVmwKUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNB +Z1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE9iMlJsVG1GdApaVDVRWVhOemQyOXlaRHd2VG05 +a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1alIwWjZZek5rZG1OdFVUMDhMMVpo +CmJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFn +SUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNUZRVkJOWlhSb2IyUThMMDV2WkdWT1lXMWxQZ29n +SUNBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZwpJQ0E4VG05a1pVNWhiV1Ur +UlVGUVZIbHdaVHd2VG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBqSXhQ +QzlXCllXeDFaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThU +bTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWcKSUNBOFRtOWtaVTVoYldVK1NXNXVaWEpOWlhSb2IyUThM +MDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1TgpVeTFEU0VGUUxWWXlQ +QzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2Iy +UmxQZ29nCklDQWdJQ0FnSUR3dlRtOWtaVDRLSUNBZ0lDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lD +QWdJRHhPYjJSbFRtRnRaVDVFYVdkcGRHRnMKUTJWeWRHbG1hV05oZEdVOEwwNXZaR1ZPWVcxbFBn +b2dJQ0FnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbApUbUZ0WlQ1RFpY +SjBhV1pwWTJGMFpWUjVjR1U4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzZFdV +K2VEVXdPWFl6ClBDOVdZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNB +Z0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ0lDQTgKVG05a1pVNWhiV1UrUTJWeWRGTklRVEkxTmta +cGJtZGxjbkJ5YVc1MFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaApiSFZsUGpG bU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZt -TVdZeFpqRm1NV1l4ClpqRm1NV1l4Wmp3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0FnSUNBOEwwNXZaR1Ur -Q2lBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWcKSUR4T2IyUmxQZ29nSUNBZ0lDQWdJQ0Fn -UEU1dlpHVk9ZVzFsUGxOSlRUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4VG05awpaVDRL -SUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBrbE5VMGs4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJ -Q0FnSUNBZ0lDQThWbUZzCmRXVSthVzF6YVR3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0FnSUNBOEwwNXZa -R1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWcKSUNBZ0lDQWdQRTV2WkdWT1lXMWxQ -a1ZCVUZSNWNHVThMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBOFZtRnNkV1UrTWpROApM -MVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lD -QWdJQ0FnUEM5T2IyUmxQZ29nCklDQWdQQzlPYjJSbFBnb2dJRHd2VG05a1pUNEtQQzlOWjIxMFZI -SmxaVDRLCgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXg1MDktY2Et -Y2VydApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKCkxTMHRMUzFDUlVkSlRpQkRS -VkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVJMUkVORFFXaERaMEYzU1VKQlowbEtRVWxNYkVaa2Qz -cE0KVm5WeVRVRXdSME5UY1VkVFNXSXpSRkZGUWtOM1ZVRk5Ra2w0UlVSQlQwSm5UbFlLUWtGTlZF -SXdWa0pWUTBKRVVWUkZkMGhvWTA1TgpWRmwzVFZSRmVVMVVSVEZOUkVVeFYyaGpUazFxV1hkTlZF -RTFUVlJGTVUxRVJURlhha0ZUVFZKQmR3cEVaMWxFVmxGUlJFVjNaRVpSClZrRm5VVEJGZUUxSlNV -Skpha0ZPUW1kcmNXaHJhVWM1ZHpCQ1FWRkZSa0ZCVDBOQlVUaEJUVWxKUWtOblMwTkJVVVZCQ25w -dVFWQlYKZWpJMlRYTmhaVFIzY3pRelkzcFNOREV2U2pKUmRISlRTVnBWUzIxV1ZYTldkVzFFWWxs -SWNsQk9kbFJZUzFOTldFRmpaWGRQVWtSUgpXVmdLVW5GMlNIWndiamhEYzJOQ01TdHZSMWhhZGto -M2VHbzBlbFl3VjB0dlN6SjZaVmhyWVhVemRtTjViRE5JU1V0MWNFcG1jVEpVClJVRkRaV1pXYW1v -d2RBcEtWeXRZTXpWUVIxZHdPUzlJTlhwSlZVNVdUbFpxVXpkVmJYTTRORWwyUzJoU1FqZzFNVEpR -UWpsVmVVaGgKWjFoWlZsZzFSMWR3UVdOV2NIbG1jbXhTQ2taSk9WRmthR2dyVUdKck1IVjVhM1Jr -WW1ZdlEyUm1aMGhQYjJWaWNsUjBkMUpzYWswdwpiMFIwV0NzeVEzWTJhakIzUWtzM2FFUTRjRkIy -WmpFcmRYa0tSM3BqZW1sblFWVXZORXQzTjJWYWNYbGtaamxDS3pWU2RYQlNLMGxhCmFYQllOREY0 -UldsSmNrdFNkM0ZwTlRFM1YxZDZXR05xWVVjeVkwNWlaalExTVFwNGNFZzFVRzVXTTJreGRIRXdO -R3BOUjFGVmVrWjMKU1VSQlVVRkNielJIUVUxSU5IZElVVmxFVmxJd1QwSkNXVVZHU1hkWU5IWnpP -RUpwUW1OVFkyOWtDalZ1YjFwSVVrMDRSVFFyYVUxRgpTVWRCTVZWa1NYZFJOMDFFYlVGR1NYZFlO -SFp6T0VKcFFtTlRZMjlrTlc1dldraFNUVGhGTkN0cGIxSmhhMFpFUVZNS1RWSkJkMFJuCldVUldV -VkZFUlhka1JsRldRV2RSTUVWNFoyZHJRV2QxVlZZelJFMTBWelp6ZDBSQldVUldVakJVUWtGVmQw -RjNSVUl2ZWtGTVFtZE8KVmdwSVVUaEZRa0ZOUTBGUldYZEVVVmxLUzI5YVNXaDJZMDVCVVVWTVFs -RkJSR2RuUlVKQlJtWlJjVTlVUVRkU2RqZExLMngxVVRkdwpibUZ6TkVKWmQwaEZDamxIUlZBdmRX -OW9kalpMVDNrd1ZFZFJSbUp5VWxScVJtOU1WazVDT1VKYU1YbHRUVVJhTUM5VVNYZEpWV00zCmQy -azNZVGgwTlcxRmNWbElNVFV6ZDFjS1lWZHZiMmxUYW5sTVRHaDFTVFJ6VG5KT1EwOTBhWE5rUW5F -eWNqSk5SbGgwTm1nd2JVRlIKV1U5UWRqaFNPRXMzTDJablUzaEhSbkY2YUhsT2JXMVdUQW94Y1VK -S2JHUjRNelJUY0hkelZFRk1VVlpRWWpSb1IzZEtlbHBtY2pGUQpZM0JGVVhnMmVFMXVWR3c0ZUVW -WFdrVXpUWE01T1hWaFZYaGlVWEZKZDFKMUNreG5RVTlyVGtOdFdUSnRPRGxXYUhwaFNFb3hkVlk0 -Ck5VRmtUUzkwUkN0WmMyMXNibTVxZERsTVVrTmxhbUpDYVhCcVNVZHFUMWh5WnpGS1VDdHNlRllL -YlhWTk5IWklLMUF2Yld4dGVITlEKVUhvd1pEWTFZaXRGUjIxS1duQnZUR3RQTDNSa1RrNTJRMWw2 -YWtwd1ZFVlhjRVZ6VHpaT1RXaExXVzg5Q2kwdExTMHRSVTVFSUVORgpVbFJKUmtsRFFWUkZMUzB0 -TFMwSwotLXtib3VuZGFyeX0tLQo= +TVdZeFpqRm1NV1l4ClpqRm1NV1l4WmpGbU1XWThMMVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdQQzlP +YjJSbFBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWcKSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0Fn +SUNBZ0lEeE9iMlJsVG1GdFpUNVRTVTA4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZwpQRTV2 +WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFRtRnRaVDVKVFZOSlBDOU9iMlJsVG1GdFpUNEtJ +Q0FnSUNBZ0lDQWdJQ0FnClBGWmhiSFZsUGpFeU16UTFOaW84TDFaaGJIVmxQZ29nSUNBZ0lDQWdJ +Q0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVSsKQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE9i +MlJsVG1GdFpUNUZRVkJVZVhCbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaApi +SFZsUGpJelBDOVdZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNBOEww +NXZaR1UrQ2lBZ0lDQWdJRHd2ClRtOWtaVDRLSUNBZ0lEd3ZUbTlrWlQ0S0lDQThMMDV2WkdVK0Nq +d3ZUV2R0ZEZSeVpXVSsKCi0te2JvdW5kYXJ5fQpDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL3gt +eDUwOS1jYS1jZXJ0CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2NAoKTFMwdExTMUNS +VWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVUkxSRU5EUVdoRFowRjNTVUpCWjBsS1FV +bE1iRVprZDNwTQpWblZ5VFVFd1IwTlRjVWRUU1dJelJGRkZRa04zVlVGTlFrbDRSVVJCVDBKblRs +WUtRa0ZOVkVJd1ZrSlZRMEpFVVZSRmQwaG9ZMDVOClZGbDNUVlJGZVUxVVJURk5SRVV4VjJoalRr +MXFXWGROVkVFMVRWUkZNVTFFUlRGWGFrRlRUVkpCZHdwRVoxbEVWbEZSUkVWM1pFWlIKVmtGblVU +QkZlRTFKU1VKSmFrRk9RbWRyY1docmFVYzVkekJDUVZGRlJrRkJUME5CVVRoQlRVbEpRa05uUzBO +QlVVVkJDbnB1UVZCVgplakkyVFhOaFpUUjNjelF6WTNwU05ERXZTakpSZEhKVFNWcFZTMjFXVlhO +V2RXMUVZbGxJY2xCT2RsUllTMU5OV0VGalpYZFBVa1JSCldWZ0tVbkYyU0had2JqaERjMk5DTVN0 +dlIxaGFka2gzZUdvMGVsWXdWMHR2U3pKNlpWaHJZWFV6ZG1ONWJETklTVXQxY0VwbWNUSlUKUlVG +RFpXWldhbW93ZEFwS1Z5dFlNelZRUjFkd09TOUlOWHBKVlU1V1RsWnFVemRWYlhNNE5FbDJTMmhT +UWpnMU1USlFRamxWZVVoaApaMWhaVmxnMVIxZHdRV05XY0hsbWNteFNDa1pKT1ZGa2FHZ3JVR0py +TUhWNWEzUmtZbVl2UTJSbVowaFBiMlZpY2xSMGQxSnNhazB3CmIwUjBXQ3N5UTNZMmFqQjNRa3Mz +YUVRNGNGQjJaakVyZFhrS1IzcGplbWxuUVZVdk5FdDNOMlZhY1hsa1pqbENLelZTZFhCU0swbGEK +YVhCWU5ERjRSV2xKY2t0U2QzRnBOVEUzVjFkNldHTnFZVWN5WTA1aVpqUTFNUXA0Y0VnMVVHNVdN +Mmt4ZEhFd05HcE5SMUZWZWtaMwpTVVJCVVVGQ2J6UkhRVTFJTkhkSVVWbEVWbEl3VDBKQ1dVVkdT +WGRZTkhaek9FSnBRbU5UWTI5a0NqVnViMXBJVWswNFJUUXJhVTFGClNVZEJNVlZrU1hkUk4wMUVi +VUZHU1hkWU5IWnpPRUpwUW1OVFkyOWtOVzV2V2toU1RUaEZOQ3RwYjFKaGEwWkVRVk1LVFZKQmQw +Um4KV1VSV1VWRkVSWGRrUmxGV1FXZFJNRVY0WjJkclFXZDFWVll6UkUxMFZ6WnpkMFJCV1VSV1Vq +QlVRa0ZWZDBGM1JVSXZla0ZNUW1kTwpWZ3BJVVRoRlFrRk5RMEZSV1hkRVVWbEtTMjlhU1doMlkw +NUJVVVZNUWxGQlJHZG5SVUpCUm1aUmNVOVVRVGRTZGpkTEsyeDFVVGR3CmJtRnpORUpaZDBoRkNq +bEhSVkF2ZFc5b2RqWkxUM2t3VkVkUlJtSnlVbFJxUm05TVZrNUNPVUphTVhsdFRVUmFNQzlVU1hk +SlZXTTMKZDJrM1lUaDBOVzFGY1ZsSU1UVXpkMWNLWVZkdmIybFRhbmxNVEdoMVNUUnpUbkpPUTA5 +MGFYTmtRbkV5Y2pKTlJsaDBObWd3YlVGUgpXVTlRZGpoU09FczNMMlpuVTNoSFJuRjZhSGxPYlcx +V1RBb3hjVUpLYkdSNE16UlRjSGR6VkVGTVVWWlFZalJvUjNkS2VscG1jakZRClkzQkZVWGcyZUUx +dVZHdzRlRVZYV2tVelRYTTVPWFZoVlhoaVVYRkpkMUoxQ2t4blFVOXJUa050V1RKdE9EbFdhSHBo +U0VveGRWWTQKTlVGa1RTOTBSQ3RaYzIxc2JtNXFkRGxNVWtObGFtSkNhWEJxU1VkcVQxaHlaekZL +VUN0c2VGWUtiWFZOTkhaSUsxQXZiV3h0ZUhOUQpVSG93WkRZMVlpdEZSMjFLV25CdlRHdFBMM1Jr +VGs1MlExbDZha3B3VkVWWGNFVnpUelpPVFdoTFdXODlDaTB0TFMwdFJVNUVJRU5GClVsUkpSa2xE +UVZSRkxTMHRMUzBLCi0te2JvdW5kYXJ5fS0tCg== \ No newline at end of file diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.conf b/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.conf index a44b54222589..5b4e4cb947cd 100644 --- a/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.conf +++ b/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.conf @@ -13,38 +13,38 @@ YTptbzpob3RzcG90MmRvdDAtcGVycHJvdmlkZXJzdWJzY3JpcHRpb246MS4wPC9EREZOYW1lPgog ICAgICA8L1R5cGU+CiAgICA8L1JUUHJvcGVydGllcz4KICAgIDxOb2RlPgogICAgICA8Tm9kZU5h bWU+aTAwMTwvTm9kZU5hbWU+CiAgICAgIDxOb2RlPgogICAgICAgIDxOb2RlTmFtZT5Ib21lU1A8 L05vZGVOYW1lPgogICAgICAgIDxOb2RlPgogICAgICAgICAgPE5vZGVOYW1lPkZyaWVuZGx5TmFt -ZTwvTm9kZU5hbWU+CiAgICAgICAgICA8VmFsdWU+Q2VudHVyeSBIb3VzZTwvVmFsdWU+CiAgICAg -ICAgPC9Ob2RlPgogICAgICAgIDxOb2RlPgogICAgICAgICAgPE5vZGVOYW1lPkZRRE48L05vZGVO -YW1lPgogICAgICAgICAgPFZhbHVlPm1pNi5jby51azwvVmFsdWU+CiAgICAgICAgPC9Ob2RlPgog -ICAgICAgIDxOb2RlPgogICAgICAgICAgPE5vZGVOYW1lPlJvYW1pbmdDb25zb3J0aXVtT0k8L05v -ZGVOYW1lPgogICAgICAgICAgPFZhbHVlPjExMjIzMyw0NDU1NjY8L1ZhbHVlPgogICAgICAgIDwv -Tm9kZT4KICAgICAgPC9Ob2RlPgogICAgICA8Tm9kZT4KICAgICAgICA8Tm9kZU5hbWU+Q3JlZGVu -dGlhbDwvTm9kZU5hbWU+CiAgICAgICAgPE5vZGU+CiAgICAgICAgICA8Tm9kZU5hbWU+UmVhbG08 -L05vZGVOYW1lPgogICAgICAgICAgPFZhbHVlPnNoYWtlbi5zdGlycmVkLmNvbTwvVmFsdWU+CiAg -ICAgICAgPC9Ob2RlPgogICAgICAgIDxOb2RlPgogICAgICAgICAgPE5vZGVOYW1lPlVzZXJuYW1l -UGFzc3dvcmQ8L05vZGVOYW1lPgogICAgICAgICAgPE5vZGU+CiAgICAgICAgICAgIDxOb2RlTmFt -ZT5Vc2VybmFtZTwvTm9kZU5hbWU+CiAgICAgICAgICAgIDxWYWx1ZT5qYW1lczwvVmFsdWU+CiAg -ICAgICAgICA8L05vZGU+CiAgICAgICAgICA8Tm9kZT4KICAgICAgICAgICAgPE5vZGVOYW1lPlBh -c3N3b3JkPC9Ob2RlTmFtZT4KICAgICAgICAgICAgPFZhbHVlPlltOXVaREF3Tnc9PTwvVmFsdWU+ -CiAgICAgICAgICA8L05vZGU+CiAgICAgICAgICA8Tm9kZT4KICAgICAgICAgICAgPE5vZGVOYW1l -PkVBUE1ldGhvZDwvTm9kZU5hbWU+CiAgICAgICAgICAgIDxOb2RlPgogICAgICAgICAgICAgIDxO -b2RlTmFtZT5FQVBUeXBlPC9Ob2RlTmFtZT4KICAgICAgICAgICAgICA8VmFsdWU+MjE8L1ZhbHVl -PgogICAgICAgICAgICA8L05vZGU+CiAgICAgICAgICAgIDxOb2RlPgogICAgICAgICAgICAgIDxO -b2RlTmFtZT5Jbm5lck1ldGhvZDwvTm9kZU5hbWU+CiAgICAgICAgICAgICAgPFZhbHVlPk1TLUNI -QVAtVjI8L1ZhbHVlPgogICAgICAgICAgICA8L05vZGU+CiAgICAgICAgICA8L05vZGU+CiAgICAg -ICAgPC9Ob2RlPgogICAgICAgIDxOb2RlPgogICAgICAgICAgPE5vZGVOYW1lPkRpZ2l0YWxDZXJ0 -aWZpY2F0ZTwvTm9kZU5hbWU+CiAgICAgICAgICA8Tm9kZT4KICAgICAgICAgICAgPE5vZGVOYW1l -PkNlcnRpZmljYXRlVHlwZTwvTm9kZU5hbWU+CiAgICAgICAgICAgIDxWYWx1ZT54NTA5djM8L1Zh +ZTwvTm9kZU5hbWU+CiAgICAgICAgICA8VmFsdWU+RXhhbXBsZSBOZXR3b3JrPC9WYWx1ZT4KICAg +ICAgICA8L05vZGU+CiAgICAgICAgPE5vZGU+CiAgICAgICAgICA8Tm9kZU5hbWU+RlFETjwvTm9k +ZU5hbWU+CiAgICAgICAgICA8VmFsdWU+aG90c3BvdC5leGFtcGxlLm5ldDwvVmFsdWU+CiAgICAg +ICAgPC9Ob2RlPgogICAgICAgIDxOb2RlPgogICAgICAgICAgPE5vZGVOYW1lPlJvYW1pbmdDb25z +b3J0aXVtT0k8L05vZGVOYW1lPgogICAgICAgICAgPFZhbHVlPjExMjIzMyw0NDU1NjY8L1ZhbHVl +PgogICAgICAgIDwvTm9kZT4KICAgICAgPC9Ob2RlPgogICAgICA8Tm9kZT4KICAgICAgICA8Tm9k +ZU5hbWU+Q3JlZGVudGlhbDwvTm9kZU5hbWU+CiAgICAgICAgPE5vZGU+CiAgICAgICAgICA8Tm9k +ZU5hbWU+UmVhbG08L05vZGVOYW1lPgogICAgICAgICAgPFZhbHVlPmV4YW1wbGUuY29tPC9WYWx1 +ZT4KICAgICAgICA8L05vZGU+CiAgICAgICAgPE5vZGU+CiAgICAgICAgICA8Tm9kZU5hbWU+VXNl +cm5hbWVQYXNzd29yZDwvTm9kZU5hbWU+CiAgICAgICAgICA8Tm9kZT4KICAgICAgICAgICAgPE5v +ZGVOYW1lPlVzZXJuYW1lPC9Ob2RlTmFtZT4KICAgICAgICAgICAgPFZhbHVlPnVzZXI8L1ZhbHVl +PgogICAgICAgICAgPC9Ob2RlPgogICAgICAgICAgPE5vZGU+CiAgICAgICAgICAgIDxOb2RlTmFt +ZT5QYXNzd29yZDwvTm9kZU5hbWU+CiAgICAgICAgICAgIDxWYWx1ZT5jR0Z6YzNkdmNtUT08L1Zh bHVlPgogICAgICAgICAgPC9Ob2RlPgogICAgICAgICAgPE5vZGU+CiAgICAgICAgICAgIDxOb2Rl -TmFtZT5DZXJ0U0hBMjU2RmluZ2VycHJpbnQ8L05vZGVOYW1lPgogICAgICAgICAgICA8VmFsdWU+ -MWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYx -ZjFmMWYxZjwvVmFsdWU+CiAgICAgICAgICA8L05vZGU+CiAgICAgICAgPC9Ob2RlPgogICAgICAg -IDxOb2RlPgogICAgICAgICAgPE5vZGVOYW1lPlNJTTwvTm9kZU5hbWU+CiAgICAgICAgICA8Tm9k -ZT4KICAgICAgICAgICAgPE5vZGVOYW1lPklNU0k8L05vZGVOYW1lPgogICAgICAgICAgICA8VmFs -dWU+aW1zaTwvVmFsdWU+CiAgICAgICAgICA8L05vZGU+CiAgICAgICAgICA8Tm9kZT4KICAgICAg -ICAgICAgPE5vZGVOYW1lPkVBUFR5cGU8L05vZGVOYW1lPgogICAgICAgICAgICA8VmFsdWU+MjQ8 -L1ZhbHVlPgogICAgICAgICAgPC9Ob2RlPgogICAgICAgIDwvTm9kZT4KICAgICAgPC9Ob2RlPgog -ICAgPC9Ob2RlPgogIDwvTm9kZT4KPC9NZ210VHJlZT4K +TmFtZT5FQVBNZXRob2Q8L05vZGVOYW1lPgogICAgICAgICAgICA8Tm9kZT4KICAgICAgICAgICAg +ICA8Tm9kZU5hbWU+RUFQVHlwZTwvTm9kZU5hbWU+CiAgICAgICAgICAgICAgPFZhbHVlPjIxPC9W +YWx1ZT4KICAgICAgICAgICAgPC9Ob2RlPgogICAgICAgICAgICA8Tm9kZT4KICAgICAgICAgICAg +ICA8Tm9kZU5hbWU+SW5uZXJNZXRob2Q8L05vZGVOYW1lPgogICAgICAgICAgICAgIDxWYWx1ZT5N +Uy1DSEFQLVYyPC9WYWx1ZT4KICAgICAgICAgICAgPC9Ob2RlPgogICAgICAgICAgPC9Ob2RlPgog +ICAgICAgIDwvTm9kZT4KICAgICAgICA8Tm9kZT4KICAgICAgICAgIDxOb2RlTmFtZT5EaWdpdGFs +Q2VydGlmaWNhdGU8L05vZGVOYW1lPgogICAgICAgICAgPE5vZGU+CiAgICAgICAgICAgIDxOb2Rl +TmFtZT5DZXJ0aWZpY2F0ZVR5cGU8L05vZGVOYW1lPgogICAgICAgICAgICA8VmFsdWU+eDUwOXYz +PC9WYWx1ZT4KICAgICAgICAgIDwvTm9kZT4KICAgICAgICAgIDxOb2RlPgogICAgICAgICAgICA8 +Tm9kZU5hbWU+Q2VydFNIQTI1NkZpbmdlcnByaW50PC9Ob2RlTmFtZT4KICAgICAgICAgICAgPFZh +bHVlPjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYx +ZjFmMWYxZjFmMWY8L1ZhbHVlPgogICAgICAgICAgPC9Ob2RlPgogICAgICAgIDwvTm9kZT4KICAg +ICAgICA8Tm9kZT4KICAgICAgICAgIDxOb2RlTmFtZT5TSU08L05vZGVOYW1lPgogICAgICAgICAg +PE5vZGU+CiAgICAgICAgICAgIDxOb2RlTmFtZT5JTVNJPC9Ob2RlTmFtZT4KICAgICAgICAgICAg +PFZhbHVlPjEyMzQ1Nio8L1ZhbHVlPgogICAgICAgICAgPC9Ob2RlPgogICAgICAgICAgPE5vZGU+ +CiAgICAgICAgICAgIDxOb2RlTmFtZT5FQVBUeXBlPC9Ob2RlTmFtZT4KICAgICAgICAgICAgPFZh +bHVlPjIzPC9WYWx1ZT4KICAgICAgICAgIDwvTm9kZT4KICAgICAgICA8L05vZGU+CiAgICAgIDwv +Tm9kZT4KICAgIDwvTm9kZT4KICA8L05vZGU+CjwvTWdtdFRyZWU+ --{boundary} Content-Type: application/x-x509-ca-cert diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithInvalidContentType.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithInvalidContentType.base64 index 906bfb397464..2775a9f419f9 100644 --- a/wifi/tests/assets/hsr1/HSR1ProfileWithInvalidContentType.base64 +++ b/wifi/tests/assets/hsr1/HSR1ProfileWithInvalidContentType.base64 @@ -1,85 +1,86 @@ -Q29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5PXtib3VuZGFyeX0KQ29udGVu -dC1UcmFuc2Zlci1FbmNvZGluZzogYmFzZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBh -cHBsaWNhdGlvbi9wYXNzcG9pbnQtcHJvZmlsZQpDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBi -YXNlNjQKClBFMW5iWFJVY21WbElIaHRiRzV6UFNKemVXNWpiV3c2Wkcxa1pHWXhMaklpUGdvZ0lE -eFdaWEpFVkVRK01TNHlQQzlXWlhKRVZFUSsKQ2lBZ1BFNXZaR1UrQ2lBZ0lDQThUbTlrWlU1aGJX -VStVR1Z5VUhKdmRtbGtaWEpUZFdKelkzSnBjSFJwYjI0OEwwNXZaR1ZPWVcxbApQZ29nSUNBZ1BG -SlVVSEp2Y0dWeWRHbGxjejRLSUNBZ0lDQWdQRlI1Y0dVK0NpQWdJQ0FnSUNBZ1BFUkVSazVoYldV -K2RYSnVPbmRtCllUcHRienBvYjNSemNHOTBNbVJ2ZERBdGNHVnljSEp2ZG1sa1pYSnpkV0p6WTNK -cGNIUnBiMjQ2TVM0d1BDOUVSRVpPWVcxbFBnb2cKSUNBZ0lDQThMMVI1Y0dVK0NpQWdJQ0E4TDFK -VVVISnZjR1Z5ZEdsbGN6NEtJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQThUbTlrWlU1aApiV1UrYVRB -d01Ud3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0 -WlQ1SWIyMWxVMUE4CkwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0Fn -SUNBZ1BFNXZaR1ZPWVcxbFBrWnlhV1Z1Wkd4NVRtRnQKWlR3dlRtOWtaVTVoYldVK0NpQWdJQ0Fn -SUNBZ0lDQThWbUZzZFdVK1EyVnVkSFZ5ZVNCSWIzVnpaVHd2Vm1Gc2RXVStDaUFnSUNBZwpJQ0Fn -UEM5T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWxQ -a1pSUkU0OEwwNXZaR1ZPCllXMWxQZ29nSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQbTFwTmk1amJ5NTFh -end2Vm1Gc2RXVStDaUFnSUNBZ0lDQWdQQzlPYjJSbFBnb2cKSUNBZ0lDQWdJRHhPYjJSbFBnb2dJ -Q0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWxQbEp2WVcxcGJtZERiMjV6YjNKMGFYVnRUMGs4TDA1dgpa -R1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBqRXhNakl6TXl3ME5EVTFOalk4TDFaaGJI -VmxQZ29nSUNBZ0lDQWdJRHd2ClRtOWtaVDRLSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBOFRt -OWtaVDRLSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrUTNKbFpHVnUKZEdsaGJEd3ZUbTlrWlU1aGJX -VStDaUFnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlU1aGJXVStVbVZoYkcw -OApMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQbk5vWVd0bGJpNXpkR2x5Y21W -a0xtTnZiVHd2Vm1Gc2RXVStDaUFnCklDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJS -bFBnb2dJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWxQbFZ6WlhKdVlXMWwKVUdGemMzZHZjbVE4TDA1 -dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE9iMlJs -VG1GdApaVDVWYzJWeWJtRnRaVHd2VG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gx -WlQ1cVlXMWxjend2Vm1Gc2RXVStDaUFnCklDQWdJQ0FnSUNBOEwwNXZaR1UrQ2lBZ0lDQWdJQ0Fn -SUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBsQmgKYzNOM2IzSmtQQzlP -YjJSbFRtRnRaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BGWmhiSFZsUGxsdE9YVmFSRUYzVG5jOVBUd3ZW -bUZzZFdVKwpDaUFnSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pUNEtJ -Q0FnSUNBZ0lDQWdJQ0FnUEU1dlpHVk9ZVzFsClBrVkJVRTFsZEdodlpEd3ZUbTlrWlU1aGJXVStD -aUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeE8KYjJSbFRtRnRa -VDVGUVZCVWVYQmxQQzlPYjJSbFRtRnRaVDRLSUNBZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzZFdVK01q -RThMMVpoYkhWbApQZ29nSUNBZ0lDQWdJQ0FnSUNBOEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lE -eE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ0lDQWdJRHhPCmIyUmxUbUZ0WlQ1SmJtNWxjazFsZEdodlpE -d3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUNBZ1BGWmhiSFZsUGsxVExVTkkKUVZBdFZq -SThMMVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4TDA1 -dlpHVStDaUFnSUNBZwpJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNB -Z0lDQWdQRTV2WkdWT1lXMWxQa1JwWjJsMFlXeERaWEowCmFXWnBZMkYwWlR3dlRtOWtaVTVoYldV -K0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWwKUGtO -bGNuUnBabWxqWVhSbFZIbHdaVHd2VG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gx -WlQ1NE5UQTVkak04TDFaaApiSFZsUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0Fn -SUNBZ1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE9iMlJsClRtRnRaVDVEWlhKMFUwaEJNalUy -Um1sdVoyVnlVSEpwYm5ROEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4Vm1Gc2RXVSsK -TVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1N -V1l4WmpGbU1XWXhaakZtTVdZeApaakZtTVdZeFpqd3ZWbUZzZFdVK0NpQWdJQ0FnSUNBZ0lDQThM -MDV2WkdVK0NpQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnCklEeE9iMlJsUGdvZ0lDQWdJ -Q0FnSUNBZ1BFNXZaR1ZPWVcxbFBsTkpUVHd2VG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBOFRt -OWsKWlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWxQa2xOVTBrOEwwNXZaR1ZPWVcxbFBn -b2dJQ0FnSUNBZ0lDQWdJQ0E4Vm1GcwpkV1UrYVcxemFUd3ZWbUZzZFdVK0NpQWdJQ0FnSUNBZ0lD -QThMMDV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnCklDQWdJQ0FnUEU1dlpH -Vk9ZVzFsUGtWQlVGUjVjR1U4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzZFdV -K01qUTgKTDFaaGJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJRHd2VG05 -a1pUNEtJQ0FnSUNBZ1BDOU9iMlJsUGdvZwpJQ0FnUEM5T2IyUmxQZ29nSUR3dlRtOWtaVDRLUEM5 -TloyMTBWSEpsWlQ0SwoKLS17Ym91bmRhcnl9CkNvbnRlbnQtVHlwZTogYXBwbGljYXRpb24veC14 -NTA5LWNhLWNlcnQKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogYmFzZTY0CgpMUzB0TFMxQ1JV -ZEpUaUJEUlZKVVNVWkpRMEZVUlMwdExTMHRDazFKU1VSTFJFTkRRV2hEWjBGM1NVSkJaMGxLUVVs -TWJFWmtkM3BNClZuVnlUVUV3UjBOVGNVZFRTV0l6UkZGRlFrTjNWVUZOUWtsNFJVUkJUMEpuVGxZ -S1FrRk5WRUl3VmtKVlEwSkVVVlJGZDBob1kwNU4KVkZsM1RWUkZlVTFVUlRGTlJFVXhWMmhqVGsx -cVdYZE5WRUUxVFZSRk1VMUVSVEZYYWtGVFRWSkJkd3BFWjFsRVZsRlJSRVYzWkVaUgpWa0ZuVVRC -RmVFMUpTVUpKYWtGT1FtZHJjV2hyYVVjNWR6QkNRVkZGUmtGQlQwTkJVVGhCVFVsSlFrTm5TME5C -VVVWQkNucHVRVkJWCmVqSTJUWE5oWlRSM2N6UXpZM3BTTkRFdlNqSlJkSEpUU1ZwVlMyMVdWWE5X -ZFcxRVlsbEljbEJPZGxSWVMxTk5XRUZqWlhkUFVrUlIKV1ZnS1VuRjJTSFp3YmpoRGMyTkNNU3R2 -UjFoYWRraDNlR28wZWxZd1YwdHZTeko2WlZocllYVXpkbU41YkROSVNVdDFjRXBtY1RKVQpSVUZE -WldaV2Ftb3dkQXBLVnl0WU16VlFSMWR3T1M5SU5YcEpWVTVXVGxacVV6ZFZiWE00TkVsMlMyaFNR -amcxTVRKUVFqbFZlVWhoCloxaFpWbGcxUjFkd1FXTldjSGxtY214U0NrWkpPVkZrYUdnclVHSnJN -SFY1YTNSa1ltWXZRMlJtWjBoUGIyVmljbFIwZDFKc2FrMHcKYjBSMFdDc3lRM1kyYWpCM1FrczNh -RVE0Y0ZCMlpqRXJkWGtLUjNwamVtbG5RVlV2TkV0M04yVmFjWGxrWmpsQ0t6VlNkWEJTSzBsYQph -WEJZTkRGNFJXbEpja3RTZDNGcE5URTNWMWQ2V0dOcVlVY3lZMDVpWmpRMU1RcDRjRWcxVUc1V00y -a3hkSEV3TkdwTlIxRlZla1ozClNVUkJVVUZDYnpSSFFVMUlOSGRJVVZsRVZsSXdUMEpDV1VWR1NY -ZFlOSFp6T0VKcFFtTlRZMjlrQ2pWdWIxcElVazA0UlRRcmFVMUYKU1VkQk1WVmtTWGRSTjAxRWJV -RkdTWGRZTkhaek9FSnBRbU5UWTI5a05XNXZXa2hTVFRoRk5DdHBiMUpoYTBaRVFWTUtUVkpCZDBS -bgpXVVJXVVZGRVJYZGtSbEZXUVdkUk1FVjRaMmRyUVdkMVZWWXpSRTEwVnpaemQwUkJXVVJXVWpC -VVFrRlZkMEYzUlVJdmVrRk1RbWRPClZncElVVGhGUWtGTlEwRlJXWGRFVVZsS1MyOWFTV2gyWTA1 -QlVVVk1RbEZCUkdkblJVSkJSbVpSY1U5VVFUZFNkamRMSzJ4MVVUZHcKYm1Gek5FSlpkMGhGQ2ps -SFJWQXZkVzlvZGpaTFQza3dWRWRSUm1KeVVsUnFSbTlNVms1Q09VSmFNWGx0VFVSYU1DOVVTWGRK -VldNMwpkMmszWVRoME5XMUZjVmxJTVRVemQxY0tZVmR2YjJsVGFubE1UR2gxU1RSelRuSk9RMDkw -YVhOa1FuRXljakpOUmxoME5tZ3diVUZSCldVOVFkamhTT0VzM0wyWm5VM2hIUm5GNmFIbE9iVzFX -VEFveGNVSktiR1I0TXpSVGNIZHpWRUZNVVZaUVlqUm9SM2RLZWxwbWNqRlEKWTNCRlVYZzJlRTF1 -Vkd3NGVFVlhXa1V6VFhNNU9YVmhWWGhpVVhGSmQxSjFDa3huUVU5clRrTnRXVEp0T0RsV2FIcGhT -RW94ZFZZNApOVUZrVFM5MFJDdFpjMjFzYm01cWREbE1Va05sYW1KQ2FYQnFTVWRxVDFoeVp6RktV -Q3RzZUZZS2JYVk5OSFpJSzFBdmJXeHRlSE5RClVIb3daRFkxWWl0RlIyMUtXbkJ2VEd0UEwzUmtU -azUyUTFsNmFrcHdWRVZYY0VWelR6Wk9UV2hMV1c4OUNpMHRMUzB0UlU1RUlFTkYKVWxSSlJrbERR -VlJGTFMwdExTMEsKLS17Ym91bmRhcnl9LS0K +TUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5 +PXtib3VuZGFyeX07IGNoYXJzZXQ9VVRGLTgKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogYmFz +ZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9wYXNzcG9pbnQtcHJv +ZmlsZTsgY2hhcnNldD1VVEYtOApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKClBF +MW5iWFJVY21WbElIaHRiRzV6UFNKemVXNWpiV3c2Wkcxa1pHWXhMaklpUGdvZ0lEeFdaWEpFVkVR +K01TNHlQQzlXWlhKRVZFUSsKQ2lBZ1BFNXZaR1UrQ2lBZ0lDQThUbTlrWlU1aGJXVStVR1Z5VUhK +dmRtbGtaWEpUZFdKelkzSnBjSFJwYjI0OEwwNXZaR1ZPWVcxbApQZ29nSUNBZ1BGSlVVSEp2Y0dW +eWRHbGxjejRLSUNBZ0lDQWdQRlI1Y0dVK0NpQWdJQ0FnSUNBZ1BFUkVSazVoYldVK2RYSnVPbmRt +CllUcHRienBvYjNSemNHOTBNbVJ2ZERBdGNHVnljSEp2ZG1sa1pYSnpkV0p6WTNKcGNIUnBiMjQ2 +TVM0d1BDOUVSRVpPWVcxbFBnb2cKSUNBZ0lDQThMMVI1Y0dVK0NpQWdJQ0E4TDFKVVVISnZjR1Z5 +ZEdsbGN6NEtJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQThUbTlrWlU1aApiV1UrYVRBd01Ud3ZUbTlr +WlU1aGJXVStDaUFnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0WlQ1SWIyMWxV +MUE4CkwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZa +R1ZPWVcxbFBrWnlhV1Z1Wkd4NVRtRnQKWlR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQThW +bUZzZFdVK1JYaGhiWEJzWlNCT1pYUjNiM0pyUEM5V1lXeDFaVDRLSUNBZwpJQ0FnSUNBOEwwNXZa +R1UrQ2lBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrUmxGRVRq +d3ZUbTlrClpVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBOFZtRnNkV1UrYUc5MGMzQnZkQzVsZUdGdGNH +eGxMbTVsZER3dlZtRnNkV1UrQ2lBZ0lDQWcKSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUR4T2Iy +UmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxKdllXMXBibWREYjI1egpiM0owYVhWdFQw +azhMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQakV4TWpJek15dzBORFUxTmpZ +OEwxWmhiSFZsClBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNB +Z0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBOFRtOWsKWlU1aGJXVStRM0psWkdWdWRHbGhiRHd2VG05 +a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05awpaVTVoYldV +K1VtVmhiRzA4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ1BGWmhiSFZsUG1WNFlXMXdiR1V1 +WTI5dFBDOVdZV3gxClpUNEtJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ1BFNXZaR1Ur +Q2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVTVoYldVK1ZYTmwKY201aGJXVlFZWE56ZDI5eVpEd3ZUbTlr +WlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEU1dgpaR1ZP +WVcxbFBsVnpaWEp1WVcxbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQ +blZ6WlhJOEwxWmhiSFZsClBnb2dJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdQ +RTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFRtRnQKWlQ1UVlYTnpkMjl5WkR3dlRtOWta +VTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhXWVd4MVpUNWpSMFo2WXpOa2RtTnRVVDA4TDFaaApi +SFZsUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1UrQ2lBZ0lD +QWdJQ0FnSUNBZ0lEeE9iMlJsClRtRnRaVDVGUVZCTlpYUm9iMlE4TDA1dlpHVk9ZVzFsUGdvZ0lD +QWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWcKSUNBOFRtOWtaVTVoYldVK1JV +RlFWSGx3WlR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQakl4UEM5 +VwpZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4VG05 +a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnCklDQThUbTlrWlU1aGJXVStTVzV1WlhKTlpYUm9iMlE4TDA1 +dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQWdJRHhXWVd4MVpUNU4KVXkxRFNFRlFMVll5UEM5 +V1lXeDFaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJs +UGdvZwpJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0Fn +SUR4T2IyUmxUbUZ0WlQ1RWFXZHBkR0ZzClEyVnlkR2xtYVdOaGRHVThMMDV2WkdWT1lXMWxQZ29n +SUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNURaWEow +YVdacFkyRjBaVlI1Y0dVOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4Vm1Gc2RXVStl +RFV3T1hZegpQQzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUNBZ0lDQWdJ +RHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4ClRtOWtaVTVoYldVK1EyVnlkRk5JUVRJMU5rWnBi +bWRsY25CeWFXNTBQQzlPYjJSbFRtRnRaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BGWmgKYkhWbFBqRm1N +V1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1X +WXhaakZtTVdZeApaakZtTVdZeFpqRm1NV1k4TDFaaGJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2Iy +UmxQZ29nSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnCklDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lD +QWdJRHhPYjJSbFRtRnRaVDVUU1UwOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWcKUEU1dlpH +VStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0WlQ1SlRWTkpQQzlPYjJSbFRtRnRaVDRLSUNB +Z0lDQWdJQ0FnSUNBZwpQRlpoYkhWbFBqRXlNelExTmlvOEwxWmhiSFZsUGdvZ0lDQWdJQ0FnSUNB +Z1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1UrCkNpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJS +bFRtRnRaVDVGUVZCVWVYQmxQQzlPYjJSbFRtRnRaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BGWmgKYkhW +bFBqSXpQQzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUNBZ0lDQThMMDV2 +WkdVK0NpQWdJQ0FnSUR3dgpUbTlrWlQ0S0lDQWdJRHd2VG05a1pUNEtJQ0E4TDA1dlpHVStDand2 +VFdkdGRGUnlaV1UrCgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXg1 +MDktY2EtY2VydApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKCkxTMHRMUzFDUlVk +SlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVJMUkVORFFXaERaMEYzU1VKQlowbEtRVWxN +YkVaa2QzcE0KVm5WeVRVRXdSME5UY1VkVFNXSXpSRkZGUWtOM1ZVRk5Ra2w0UlVSQlQwSm5UbFlL +UWtGTlZFSXdWa0pWUTBKRVVWUkZkMGhvWTA1TgpWRmwzVFZSRmVVMVVSVEZOUkVVeFYyaGpUazFx +V1hkTlZFRTFUVlJGTVUxRVJURlhha0ZUVFZKQmR3cEVaMWxFVmxGUlJFVjNaRVpSClZrRm5VVEJG +ZUUxSlNVSkpha0ZPUW1kcmNXaHJhVWM1ZHpCQ1FWRkZSa0ZCVDBOQlVUaEJUVWxKUWtOblMwTkJV +VVZCQ25wdVFWQlYKZWpJMlRYTmhaVFIzY3pRelkzcFNOREV2U2pKUmRISlRTVnBWUzIxV1ZYTldk +VzFFWWxsSWNsQk9kbFJZUzFOTldFRmpaWGRQVWtSUgpXVmdLVW5GMlNIWndiamhEYzJOQ01TdHZS +MWhhZGtoM2VHbzBlbFl3VjB0dlN6SjZaVmhyWVhVemRtTjViRE5JU1V0MWNFcG1jVEpVClJVRkRa +V1pXYW1vd2RBcEtWeXRZTXpWUVIxZHdPUzlJTlhwSlZVNVdUbFpxVXpkVmJYTTRORWwyUzJoU1Fq +ZzFNVEpRUWpsVmVVaGgKWjFoWlZsZzFSMWR3UVdOV2NIbG1jbXhTQ2taSk9WRmthR2dyVUdKck1I +VjVhM1JrWW1ZdlEyUm1aMGhQYjJWaWNsUjBkMUpzYWswdwpiMFIwV0NzeVEzWTJhakIzUWtzM2FF +UTRjRkIyWmpFcmRYa0tSM3BqZW1sblFWVXZORXQzTjJWYWNYbGtaamxDS3pWU2RYQlNLMGxhCmFY +QllOREY0UldsSmNrdFNkM0ZwTlRFM1YxZDZXR05xWVVjeVkwNWlaalExTVFwNGNFZzFVRzVXTTJr +eGRIRXdOR3BOUjFGVmVrWjMKU1VSQlVVRkNielJIUVUxSU5IZElVVmxFVmxJd1QwSkNXVVZHU1hk +WU5IWnpPRUpwUW1OVFkyOWtDalZ1YjFwSVVrMDRSVFFyYVUxRgpTVWRCTVZWa1NYZFJOMDFFYlVG +R1NYZFlOSFp6T0VKcFFtTlRZMjlrTlc1dldraFNUVGhGTkN0cGIxSmhhMFpFUVZNS1RWSkJkMFJu +CldVUldVVkZFUlhka1JsRldRV2RSTUVWNFoyZHJRV2QxVlZZelJFMTBWelp6ZDBSQldVUldVakJV +UWtGVmQwRjNSVUl2ZWtGTVFtZE8KVmdwSVVUaEZRa0ZOUTBGUldYZEVVVmxLUzI5YVNXaDJZMDVC +VVVWTVFsRkJSR2RuUlVKQlJtWlJjVTlVUVRkU2RqZExLMngxVVRkdwpibUZ6TkVKWmQwaEZDamxI +UlZBdmRXOW9kalpMVDNrd1ZFZFJSbUp5VWxScVJtOU1WazVDT1VKYU1YbHRUVVJhTUM5VVNYZEpW +V00zCmQyazNZVGgwTlcxRmNWbElNVFV6ZDFjS1lWZHZiMmxUYW5sTVRHaDFTVFJ6VG5KT1EwOTBh +WE5rUW5FeWNqSk5SbGgwTm1nd2JVRlIKV1U5UWRqaFNPRXMzTDJablUzaEhSbkY2YUhsT2JXMVdU +QW94Y1VKS2JHUjRNelJUY0hkelZFRk1VVlpRWWpSb1IzZEtlbHBtY2pGUQpZM0JGVVhnMmVFMXVW +R3c0ZUVWWFdrVXpUWE01T1hWaFZYaGlVWEZKZDFKMUNreG5RVTlyVGtOdFdUSnRPRGxXYUhwaFNF +b3hkVlk0Ck5VRmtUUzkwUkN0WmMyMXNibTVxZERsTVVrTmxhbUpDYVhCcVNVZHFUMWh5WnpGS1VD +dHNlRllLYlhWTk5IWklLMUF2Yld4dGVITlEKVUhvd1pEWTFZaXRGUjIxS1duQnZUR3RQTDNSa1Rr +NTJRMWw2YWtwd1ZFVlhjRVZ6VHpaT1RXaExXVzg5Q2kwdExTMHRSVTVFSUVORgpVbFJKUmtsRFFW +UkZMUzB0TFMwSwotLXtib3VuZGFyeX0tLQo= \ No newline at end of file diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithMissingBoundary.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithMissingBoundary.base64 index 3fa97d1cdd76..7023453b3992 100644 --- a/wifi/tests/assets/hsr1/HSR1ProfileWithMissingBoundary.base64 +++ b/wifi/tests/assets/hsr1/HSR1ProfileWithMissingBoundary.base64 @@ -1,85 +1,86 @@ -Q29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5PXtib3VuZGFyeX0KQ29udGVu -dC1UcmFuc2Zlci1FbmNvZGluZzogYmFzZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBh -cHBsaWNhdGlvbi94LXBhc3Nwb2ludC1wcm9maWxlCkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6 -IGJhc2U2NAoKUEUxbmJYUlVjbVZsSUhodGJHNXpQU0p6ZVc1amJXdzZaRzFrWkdZeExqSWlQZ29n -SUR4V1pYSkVWRVErTVM0eVBDOVdaWEpFVkVRKwpDaUFnUEU1dlpHVStDaUFnSUNBOFRtOWtaVTVo -YldVK1VHVnlVSEp2ZG1sa1pYSlRkV0p6WTNKcGNIUnBiMjQ4TDA1dlpHVk9ZVzFsClBnb2dJQ0Fn -UEZKVVVISnZjR1Z5ZEdsbGN6NEtJQ0FnSUNBZ1BGUjVjR1UrQ2lBZ0lDQWdJQ0FnUEVSRVJrNWhi -V1UrZFhKdU9uZG0KWVRwdGJ6cG9iM1J6Y0c5ME1tUnZkREF0Y0dWeWNISnZkbWxrWlhKemRXSnpZ -M0pwY0hScGIyNDZNUzR3UEM5RVJFWk9ZVzFsUGdvZwpJQ0FnSUNBOEwxUjVjR1UrQ2lBZ0lDQThM -MUpVVUhKdmNHVnlkR2xsY3o0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoCmJXVSth -VEF3TVR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJSbFRt -RnRaVDVJYjIxbFUxQTgKTDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lD -QWdJQ0FnUEU1dlpHVk9ZVzFsUGtaeWFXVnVaR3g1VG1GdApaVHd2VG05a1pVNWhiV1UrQ2lBZ0lD -QWdJQ0FnSUNBOFZtRnNkV1UrUTJWdWRIVnllU0JJYjNWelpUd3ZWbUZzZFdVK0NpQWdJQ0FnCklD -QWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcx -bFBrWlJSRTQ4TDA1dlpHVk8KWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBtMXBOaTVqYnk1 -MWF6d3ZWbUZzZFdVK0NpQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZwpJQ0FnSUNBZ0lEeE9iMlJsUGdv -Z0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBsSnZZVzFwYm1kRGIyNXpiM0owYVhWdFQwazhMMDV2 -ClpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ1BGWmhiSFZsUGpFeE1qSXpNeXcwTkRVMU5qWThMMVpo -YkhWbFBnb2dJQ0FnSUNBZ0lEd3YKVG05a1pUNEtJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0E4 -VG05a1pUNEtJQ0FnSUNBZ0lDQThUbTlrWlU1aGJXVStRM0psWkdWdQpkR2xoYkR3dlRtOWtaVTVo -YldVK0NpQWdJQ0FnSUNBZ1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVTVoYldVK1VtVmhi -RzA4CkwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBuTm9ZV3RsYmk1emRHbHlj -bVZrTG1OdmJUd3ZWbUZzZFdVK0NpQWcKSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9i -MlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBsVnpaWEp1WVcxbApVR0Z6YzNkdmNtUThM -MDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2Iy -UmxUbUZ0ClpUNVZjMlZ5Ym1GdFpUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUR4V1lX -eDFaVDVxWVcxbGN6d3ZWbUZzZFdVK0NpQWcKSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnSUNBZ0lD -QWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxCaApjM04zYjNKa1BD -OU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQbGx0T1hWYVJFRjNUbmM5UFR3 -dlZtRnNkV1UrCkNpQWdJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0 -S0lDQWdJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWwKUGtWQlVFMWxkR2h2WkR3dlRtOWtaVTVoYldV -K0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0FnSUR4TwpiMlJsVG1G -dFpUNUZRVkJVZVhCbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnSUNBOFZtRnNkV1Ur -TWpFOEwxWmhiSFZsClBnb2dJQ0FnSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnSUNBZ0lDQWdJQ0Fn -SUR4T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeE8KYjJSbFRtRnRaVDVKYm01bGNrMWxkR2h2 -WkR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQazFUTFVOSQpRVkF0 -VmpJOEwxWmhiSFZsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThM -MDV2WkdVK0NpQWdJQ0FnCklDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJ -Q0FnSUNBZ1BFNXZaR1ZPWVcxbFBrUnBaMmwwWVd4RFpYSjAKYVdacFkyRjBaVHd2VG05a1pVNWhi -V1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbApQ -a05sY25ScFptbGpZWFJsVkhsd1pUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUR4V1lX -eDFaVDU0TlRBNWRqTThMMVpoCmJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lD -QWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNURaWEowVTBoQk1q -VTJSbWx1WjJWeVVISnBiblE4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzZFdV -KwpNV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpG -bU1XWXhaakZtTVdZeFpqRm1NV1l4ClpqRm1NV1l4Wmp3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0FnSUNB -OEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWcKSUR4T2IyUmxQZ29nSUNB -Z0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxOSlRUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4 -VG05awpaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBrbE5VMGs4TDA1dlpHVk9ZVzFs -UGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzCmRXVSthVzF6YVR3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0Fn -SUNBOEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWcKSUNBZ0lDQWdQRTV2 -WkdWT1lXMWxQa1ZCVUZSNWNHVThMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBOFZtRnNk -V1UrTWpROApMMVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEd3ZU -bTlrWlQ0S0lDQWdJQ0FnUEM5T2IyUmxQZ29nCklDQWdQQzlPYjJSbFBnb2dJRHd2VG05a1pUNEtQ -QzlOWjIxMFZISmxaVDRLCgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94 -LXg1MDktY2EtY2VydApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKCkxTMHRMUzFD -UlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVJMUkVORFFXaERaMEYzU1VKQlowbEtR -VWxNYkVaa2QzcE0KVm5WeVRVRXdSME5UY1VkVFNXSXpSRkZGUWtOM1ZVRk5Ra2w0UlVSQlQwSm5U -bFlLUWtGTlZFSXdWa0pWUTBKRVVWUkZkMGhvWTA1TgpWRmwzVFZSRmVVMVVSVEZOUkVVeFYyaGpU -azFxV1hkTlZFRTFUVlJGTVUxRVJURlhha0ZUVFZKQmR3cEVaMWxFVmxGUlJFVjNaRVpSClZrRm5V -VEJGZUUxSlNVSkpha0ZPUW1kcmNXaHJhVWM1ZHpCQ1FWRkZSa0ZCVDBOQlVUaEJUVWxKUWtOblMw -TkJVVVZCQ25wdVFWQlYKZWpJMlRYTmhaVFIzY3pRelkzcFNOREV2U2pKUmRISlRTVnBWUzIxV1ZY -TldkVzFFWWxsSWNsQk9kbFJZUzFOTldFRmpaWGRQVWtSUgpXVmdLVW5GMlNIWndiamhEYzJOQ01T -dHZSMWhhZGtoM2VHbzBlbFl3VjB0dlN6SjZaVmhyWVhVemRtTjViRE5JU1V0MWNFcG1jVEpVClJV -RkRaV1pXYW1vd2RBcEtWeXRZTXpWUVIxZHdPUzlJTlhwSlZVNVdUbFpxVXpkVmJYTTRORWwyUzJo -U1FqZzFNVEpRUWpsVmVVaGgKWjFoWlZsZzFSMWR3UVdOV2NIbG1jbXhTQ2taSk9WRmthR2dyVUdK -ck1IVjVhM1JrWW1ZdlEyUm1aMGhQYjJWaWNsUjBkMUpzYWswdwpiMFIwV0NzeVEzWTJhakIzUWtz -M2FFUTRjRkIyWmpFcmRYa0tSM3BqZW1sblFWVXZORXQzTjJWYWNYbGtaamxDS3pWU2RYQlNLMGxh -CmFYQllOREY0UldsSmNrdFNkM0ZwTlRFM1YxZDZXR05xWVVjeVkwNWlaalExTVFwNGNFZzFVRzVX -TTJreGRIRXdOR3BOUjFGVmVrWjMKU1VSQlVVRkNielJIUVUxSU5IZElVVmxFVmxJd1QwSkNXVVZH -U1hkWU5IWnpPRUpwUW1OVFkyOWtDalZ1YjFwSVVrMDRSVFFyYVUxRgpTVWRCTVZWa1NYZFJOMDFF -YlVGR1NYZFlOSFp6T0VKcFFtTlRZMjlrTlc1dldraFNUVGhGTkN0cGIxSmhhMFpFUVZNS1RWSkJk -MFJuCldVUldVVkZFUlhka1JsRldRV2RSTUVWNFoyZHJRV2QxVlZZelJFMTBWelp6ZDBSQldVUldV -akJVUWtGVmQwRjNSVUl2ZWtGTVFtZE8KVmdwSVVUaEZRa0ZOUTBGUldYZEVVVmxLUzI5YVNXaDJZ -MDVCVVVWTVFsRkJSR2RuUlVKQlJtWlJjVTlVUVRkU2RqZExLMngxVVRkdwpibUZ6TkVKWmQwaEZD -amxIUlZBdmRXOW9kalpMVDNrd1ZFZFJSbUp5VWxScVJtOU1WazVDT1VKYU1YbHRUVVJhTUM5VVNY -ZEpWV00zCmQyazNZVGgwTlcxRmNWbElNVFV6ZDFjS1lWZHZiMmxUYW5sTVRHaDFTVFJ6VG5KT1Ew -OTBhWE5rUW5FeWNqSk5SbGgwTm1nd2JVRlIKV1U5UWRqaFNPRXMzTDJablUzaEhSbkY2YUhsT2JX -MVdUQW94Y1VKS2JHUjRNelJUY0hkelZFRk1VVlpRWWpSb1IzZEtlbHBtY2pGUQpZM0JGVVhnMmVF -MXVWR3c0ZUVWWFdrVXpUWE01T1hWaFZYaGlVWEZKZDFKMUNreG5RVTlyVGtOdFdUSnRPRGxXYUhw -aFNFb3hkVlk0Ck5VRmtUUzkwUkN0WmMyMXNibTVxZERsTVVrTmxhbUpDYVhCcVNVZHFUMWh5WnpG -S1VDdHNlRllLYlhWTk5IWklLMUF2Yld4dGVITlEKVUhvd1pEWTFZaXRGUjIxS1duQnZUR3RQTDNS -a1RrNTJRMWw2YWtwd1ZFVlhjRVZ6VHpaT1RXaExXVzg5Q2kwdExTMHRSVTVFSUVORgpVbFJKUmts -RFFWUkZMUzB0TFMwSwo= +TUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5 +PXtib3VuZGFyeX07IGNoYXJzZXQ9VVRGLTgKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogYmFz +ZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXBhc3Nwb2ludC1w +cm9maWxlOyBjaGFyc2V0PVVURi04CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2NAoK +UEUxbmJYUlVjbVZsSUhodGJHNXpQU0p6ZVc1amJXdzZaRzFrWkdZeExqSWlQZ29nSUR4V1pYSkVW +RVErTVM0eVBDOVdaWEpFVkVRKwpDaUFnUEU1dlpHVStDaUFnSUNBOFRtOWtaVTVoYldVK1VHVnlV +SEp2ZG1sa1pYSlRkV0p6WTNKcGNIUnBiMjQ4TDA1dlpHVk9ZVzFsClBnb2dJQ0FnUEZKVVVISnZj +R1Z5ZEdsbGN6NEtJQ0FnSUNBZ1BGUjVjR1UrQ2lBZ0lDQWdJQ0FnUEVSRVJrNWhiV1UrZFhKdU9u +ZG0KWVRwdGJ6cG9iM1J6Y0c5ME1tUnZkREF0Y0dWeWNISnZkbWxrWlhKemRXSnpZM0pwY0hScGIy +NDZNUzR3UEM5RVJFWk9ZVzFsUGdvZwpJQ0FnSUNBOEwxUjVjR1UrQ2lBZ0lDQThMMUpVVUhKdmNH +VnlkR2xsY3o0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoCmJXVSthVEF3TVR3dlRt +OWtaVTVoYldVK0NpQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJSbFRtRnRaVDVJYjIx +bFUxQTgKTDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1 +dlpHVk9ZVzFsUGtaeWFXVnVaR3g1VG1GdApaVHd2VG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNB +OFZtRnNkV1UrUlhoaGJYQnNaU0JPWlhSM2IzSnJQQzlXWVd4MVpUNEtJQ0FnCklDQWdJQ0E4TDA1 +dlpHVStDaUFnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlU1aGJXVStSbEZF +VGp3dlRtOWsKWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4Vm1Gc2RXVSthRzkwYzNCdmRDNWxlR0Z0 +Y0d4bExtNWxkRHd2Vm1Gc2RXVStDaUFnSUNBZwpJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJRHhP +YjJSbFBnb2dJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWxQbEp2WVcxcGJtZERiMjV6CmIzSjBhWFZ0 +VDBrOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBqRXhNakl6TXl3ME5EVTFO +alk4TDFaaGJIVmwKUGdvZ0lDQWdJQ0FnSUR3dlRtOWtaVDRLSUNBZ0lDQWdQQzlPYjJSbFBnb2dJ +Q0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0E4VG05awpaVTVoYldVK1EzSmxaR1Z1ZEdsaGJEd3ZU +bTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrClpVNWhi +V1UrVW1WaGJHMDhMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQbVY0WVcxd2JH +VXVZMjl0UEM5V1lXeDEKWlQ0S0lDQWdJQ0FnSUNBOEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnUEU1dlpH +VStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrVlhObApjbTVoYldWUVlYTnpkMjl5WkR3dlRt +OWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQRTV2ClpH +Vk9ZVzFsUGxWelpYSnVZVzFsUEM5T2IyUmxUbUZ0WlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQRlpoYkhW +bFBuVnpaWEk4TDFaaGJIVmwKUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNB +Z1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE9iMlJsVG1GdApaVDVRWVhOemQyOXlaRHd2VG05 +a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1alIwWjZZek5rZG1OdFVUMDhMMVpo +CmJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFn +SUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNUZRVkJOWlhSb2IyUThMMDV2WkdWT1lXMWxQZ29n +SUNBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZwpJQ0E4VG05a1pVNWhiV1Ur +UlVGUVZIbHdaVHd2VG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBqSXhQ +QzlXCllXeDFaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThU +bTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWcKSUNBOFRtOWtaVTVoYldVK1NXNXVaWEpOWlhSb2IyUThM +MDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1TgpVeTFEU0VGUUxWWXlQ +QzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2Iy +UmxQZ29nCklDQWdJQ0FnSUR3dlRtOWtaVDRLSUNBZ0lDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lD +QWdJRHhPYjJSbFRtRnRaVDVFYVdkcGRHRnMKUTJWeWRHbG1hV05oZEdVOEwwNXZaR1ZPWVcxbFBn +b2dJQ0FnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbApUbUZ0WlQ1RFpY +SjBhV1pwWTJGMFpWUjVjR1U4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzZFdV +K2VEVXdPWFl6ClBDOVdZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNB +Z0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ0lDQTgKVG05a1pVNWhiV1UrUTJWeWRGTklRVEkxTmta +cGJtZGxjbkJ5YVc1MFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaApiSFZsUGpG +bU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZt +TVdZeFpqRm1NV1l4ClpqRm1NV1l4WmpGbU1XWThMMVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdQQzlP +YjJSbFBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWcKSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0Fn +SUNBZ0lEeE9iMlJsVG1GdFpUNVRTVTA4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZwpQRTV2 +WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFRtRnRaVDVKVFZOSlBDOU9iMlJsVG1GdFpUNEtJ +Q0FnSUNBZ0lDQWdJQ0FnClBGWmhiSFZsUGpFeU16UTFOaW84TDFaaGJIVmxQZ29nSUNBZ0lDQWdJ +Q0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVSsKQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE9i +MlJsVG1GdFpUNUZRVkJVZVhCbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaApi +SFZsUGpJelBDOVdZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNBOEww +NXZaR1UrQ2lBZ0lDQWdJRHd2ClRtOWtaVDRLSUNBZ0lEd3ZUbTlrWlQ0S0lDQThMMDV2WkdVK0Nq +d3ZUV2R0ZEZSeVpXVSsKCi0te2JvdW5kYXJ5fQpDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL3gt +eDUwOS1jYS1jZXJ0CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2NAoKTFMwdExTMUNS +VWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVUkxSRU5EUVdoRFowRjNTVUpCWjBsS1FV +bE1iRVprZDNwTQpWblZ5VFVFd1IwTlRjVWRUU1dJelJGRkZRa04zVlVGTlFrbDRSVVJCVDBKblRs +WUtRa0ZOVkVJd1ZrSlZRMEpFVVZSRmQwaG9ZMDVOClZGbDNUVlJGZVUxVVJURk5SRVV4VjJoalRr +MXFXWGROVkVFMVRWUkZNVTFFUlRGWGFrRlRUVkpCZHdwRVoxbEVWbEZSUkVWM1pFWlIKVmtGblVU +QkZlRTFKU1VKSmFrRk9RbWRyY1docmFVYzVkekJDUVZGRlJrRkJUME5CVVRoQlRVbEpRa05uUzBO +QlVVVkJDbnB1UVZCVgplakkyVFhOaFpUUjNjelF6WTNwU05ERXZTakpSZEhKVFNWcFZTMjFXVlhO +V2RXMUVZbGxJY2xCT2RsUllTMU5OV0VGalpYZFBVa1JSCldWZ0tVbkYyU0had2JqaERjMk5DTVN0 +dlIxaGFka2gzZUdvMGVsWXdWMHR2U3pKNlpWaHJZWFV6ZG1ONWJETklTVXQxY0VwbWNUSlUKUlVG +RFpXWldhbW93ZEFwS1Z5dFlNelZRUjFkd09TOUlOWHBKVlU1V1RsWnFVemRWYlhNNE5FbDJTMmhT +UWpnMU1USlFRamxWZVVoaApaMWhaVmxnMVIxZHdRV05XY0hsbWNteFNDa1pKT1ZGa2FHZ3JVR0py +TUhWNWEzUmtZbVl2UTJSbVowaFBiMlZpY2xSMGQxSnNhazB3CmIwUjBXQ3N5UTNZMmFqQjNRa3Mz +YUVRNGNGQjJaakVyZFhrS1IzcGplbWxuUVZVdk5FdDNOMlZhY1hsa1pqbENLelZTZFhCU0swbGEK +YVhCWU5ERjRSV2xKY2t0U2QzRnBOVEUzVjFkNldHTnFZVWN5WTA1aVpqUTFNUXA0Y0VnMVVHNVdN +Mmt4ZEhFd05HcE5SMUZWZWtaMwpTVVJCVVVGQ2J6UkhRVTFJTkhkSVVWbEVWbEl3VDBKQ1dVVkdT +WGRZTkhaek9FSnBRbU5UWTI5a0NqVnViMXBJVWswNFJUUXJhVTFGClNVZEJNVlZrU1hkUk4wMUVi +VUZHU1hkWU5IWnpPRUpwUW1OVFkyOWtOVzV2V2toU1RUaEZOQ3RwYjFKaGEwWkVRVk1LVFZKQmQw +Um4KV1VSV1VWRkVSWGRrUmxGV1FXZFJNRVY0WjJkclFXZDFWVll6UkUxMFZ6WnpkMFJCV1VSV1Vq +QlVRa0ZWZDBGM1JVSXZla0ZNUW1kTwpWZ3BJVVRoRlFrRk5RMEZSV1hkRVVWbEtTMjlhU1doMlkw +NUJVVVZNUWxGQlJHZG5SVUpCUm1aUmNVOVVRVGRTZGpkTEsyeDFVVGR3CmJtRnpORUpaZDBoRkNq +bEhSVkF2ZFc5b2RqWkxUM2t3VkVkUlJtSnlVbFJxUm05TVZrNUNPVUphTVhsdFRVUmFNQzlVU1hk +SlZXTTMKZDJrM1lUaDBOVzFGY1ZsSU1UVXpkMWNLWVZkdmIybFRhbmxNVEdoMVNUUnpUbkpPUTA5 +MGFYTmtRbkV5Y2pKTlJsaDBObWd3YlVGUgpXVTlRZGpoU09FczNMMlpuVTNoSFJuRjZhSGxPYlcx +V1RBb3hjVUpLYkdSNE16UlRjSGR6VkVGTVVWWlFZalJvUjNkS2VscG1jakZRClkzQkZVWGcyZUUx +dVZHdzRlRVZYV2tVelRYTTVPWFZoVlhoaVVYRkpkMUoxQ2t4blFVOXJUa050V1RKdE9EbFdhSHBo +U0VveGRWWTQKTlVGa1RTOTBSQ3RaYzIxc2JtNXFkRGxNVWtObGFtSkNhWEJxU1VkcVQxaHlaekZL +VUN0c2VGWUtiWFZOTkhaSUsxQXZiV3h0ZUhOUQpVSG93WkRZMVlpdEZSMjFLV25CdlRHdFBMM1Jr +VGs1MlExbDZha3B3VkVWWGNFVnpUelpPVFdoTFdXODlDaTB0TFMwdFJVNUVJRU5GClVsUkpSa2xE +UVZSRkxTMHRMUzBLCg== \ No newline at end of file diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithNonBase64Part.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithNonBase64Part.base64 index 975f8e539cc3..5c23f61b1711 100644 --- a/wifi/tests/assets/hsr1/HSR1ProfileWithNonBase64Part.base64 +++ b/wifi/tests/assets/hsr1/HSR1ProfileWithNonBase64Part.base64 @@ -1,85 +1,86 @@ -Q29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5PXtib3VuZGFyeX0KQ29udGVu -dC1UcmFuc2Zlci1FbmNvZGluZzogYmFzZTMyCgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBh -cHBsaWNhdGlvbi94LXBhc3Nwb2ludC1wcm9maWxlCkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6 -IGJhc2U2NAoKUEUxbmJYUlVjbVZsSUhodGJHNXpQU0p6ZVc1amJXdzZaRzFrWkdZeExqSWlQZ29n -SUR4V1pYSkVWRVErTVM0eVBDOVdaWEpFVkVRKwpDaUFnUEU1dlpHVStDaUFnSUNBOFRtOWtaVTVo -YldVK1VHVnlVSEp2ZG1sa1pYSlRkV0p6WTNKcGNIUnBiMjQ4TDA1dlpHVk9ZVzFsClBnb2dJQ0Fn -UEZKVVVISnZjR1Z5ZEdsbGN6NEtJQ0FnSUNBZ1BGUjVjR1UrQ2lBZ0lDQWdJQ0FnUEVSRVJrNWhi -V1UrZFhKdU9uZG0KWVRwdGJ6cG9iM1J6Y0c5ME1tUnZkREF0Y0dWeWNISnZkbWxrWlhKemRXSnpZ -M0pwY0hScGIyNDZNUzR3UEM5RVJFWk9ZVzFsUGdvZwpJQ0FnSUNBOEwxUjVjR1UrQ2lBZ0lDQThM -MUpVVUhKdmNHVnlkR2xsY3o0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoCmJXVSth -VEF3TVR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJSbFRt -RnRaVDVJYjIxbFUxQTgKTDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lD -QWdJQ0FnUEU1dlpHVk9ZVzFsUGtaeWFXVnVaR3g1VG1GdApaVHd2VG05a1pVNWhiV1UrQ2lBZ0lD -QWdJQ0FnSUNBOFZtRnNkV1UrUTJWdWRIVnllU0JJYjNWelpUd3ZWbUZzZFdVK0NpQWdJQ0FnCklD -QWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcx -bFBrWlJSRTQ4TDA1dlpHVk8KWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBtMXBOaTVqYnk1 -MWF6d3ZWbUZzZFdVK0NpQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZwpJQ0FnSUNBZ0lEeE9iMlJsUGdv -Z0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBsSnZZVzFwYm1kRGIyNXpiM0owYVhWdFQwazhMMDV2 -ClpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ1BGWmhiSFZsUGpFeE1qSXpNeXcwTkRVMU5qWThMMVpo -YkhWbFBnb2dJQ0FnSUNBZ0lEd3YKVG05a1pUNEtJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0E4 -VG05a1pUNEtJQ0FnSUNBZ0lDQThUbTlrWlU1aGJXVStRM0psWkdWdQpkR2xoYkR3dlRtOWtaVTVo -YldVK0NpQWdJQ0FnSUNBZ1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVTVoYldVK1VtVmhi -RzA4CkwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBuTm9ZV3RsYmk1emRHbHlj -bVZrTG1OdmJUd3ZWbUZzZFdVK0NpQWcKSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9i -MlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBsVnpaWEp1WVcxbApVR0Z6YzNkdmNtUThM -MDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2Iy -UmxUbUZ0ClpUNVZjMlZ5Ym1GdFpUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUR4V1lX -eDFaVDVxWVcxbGN6d3ZWbUZzZFdVK0NpQWcKSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnSUNBZ0lD -QWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxCaApjM04zYjNKa1BD -OU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQbGx0T1hWYVJFRjNUbmM5UFR3 -dlZtRnNkV1UrCkNpQWdJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0 -S0lDQWdJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWwKUGtWQlVFMWxkR2h2WkR3dlRtOWtaVTVoYldV -K0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0FnSUR4TwpiMlJsVG1G -dFpUNUZRVkJVZVhCbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnSUNBOFZtRnNkV1Ur -TWpFOEwxWmhiSFZsClBnb2dJQ0FnSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnSUNBZ0lDQWdJQ0Fn -SUR4T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeE8KYjJSbFRtRnRaVDVKYm01bGNrMWxkR2h2 -WkR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQazFUTFVOSQpRVkF0 -VmpJOEwxWmhiSFZsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThM -MDV2WkdVK0NpQWdJQ0FnCklDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJ -Q0FnSUNBZ1BFNXZaR1ZPWVcxbFBrUnBaMmwwWVd4RFpYSjAKYVdacFkyRjBaVHd2VG05a1pVNWhi -V1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbApQ -a05sY25ScFptbGpZWFJsVkhsd1pUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUR4V1lX -eDFaVDU0TlRBNWRqTThMMVpoCmJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lD -QWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNURaWEowVTBoQk1q -VTJSbWx1WjJWeVVISnBiblE4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzZFdV -KwpNV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpG -bU1XWXhaakZtTVdZeFpqRm1NV1l4ClpqRm1NV1l4Wmp3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0FnSUNB -OEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWcKSUR4T2IyUmxQZ29nSUNB -Z0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxOSlRUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4 -VG05awpaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBrbE5VMGs4TDA1dlpHVk9ZVzFs -UGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzCmRXVSthVzF6YVR3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0Fn -SUNBOEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWcKSUNBZ0lDQWdQRTV2 -WkdWT1lXMWxQa1ZCVUZSNWNHVThMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBOFZtRnNk -V1UrTWpROApMMVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEd3ZU -bTlrWlQ0S0lDQWdJQ0FnUEM5T2IyUmxQZ29nCklDQWdQQzlPYjJSbFBnb2dJRHd2VG05a1pUNEtQ -QzlOWjIxMFZISmxaVDRLCgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94 -LXg1MDktY2EtY2VydApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKCkxTMHRMUzFD -UlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVJMUkVORFFXaERaMEYzU1VKQlowbEtR -VWxNYkVaa2QzcE0KVm5WeVRVRXdSME5UY1VkVFNXSXpSRkZGUWtOM1ZVRk5Ra2w0UlVSQlQwSm5U -bFlLUWtGTlZFSXdWa0pWUTBKRVVWUkZkMGhvWTA1TgpWRmwzVFZSRmVVMVVSVEZOUkVVeFYyaGpU -azFxV1hkTlZFRTFUVlJGTVUxRVJURlhha0ZUVFZKQmR3cEVaMWxFVmxGUlJFVjNaRVpSClZrRm5V -VEJGZUUxSlNVSkpha0ZPUW1kcmNXaHJhVWM1ZHpCQ1FWRkZSa0ZCVDBOQlVUaEJUVWxKUWtOblMw -TkJVVVZCQ25wdVFWQlYKZWpJMlRYTmhaVFIzY3pRelkzcFNOREV2U2pKUmRISlRTVnBWUzIxV1ZY -TldkVzFFWWxsSWNsQk9kbFJZUzFOTldFRmpaWGRQVWtSUgpXVmdLVW5GMlNIWndiamhEYzJOQ01T -dHZSMWhhZGtoM2VHbzBlbFl3VjB0dlN6SjZaVmhyWVhVemRtTjViRE5JU1V0MWNFcG1jVEpVClJV -RkRaV1pXYW1vd2RBcEtWeXRZTXpWUVIxZHdPUzlJTlhwSlZVNVdUbFpxVXpkVmJYTTRORWwyUzJo -U1FqZzFNVEpRUWpsVmVVaGgKWjFoWlZsZzFSMWR3UVdOV2NIbG1jbXhTQ2taSk9WRmthR2dyVUdK -ck1IVjVhM1JrWW1ZdlEyUm1aMGhQYjJWaWNsUjBkMUpzYWswdwpiMFIwV0NzeVEzWTJhakIzUWtz -M2FFUTRjRkIyWmpFcmRYa0tSM3BqZW1sblFWVXZORXQzTjJWYWNYbGtaamxDS3pWU2RYQlNLMGxh -CmFYQllOREY0UldsSmNrdFNkM0ZwTlRFM1YxZDZXR05xWVVjeVkwNWlaalExTVFwNGNFZzFVRzVX -TTJreGRIRXdOR3BOUjFGVmVrWjMKU1VSQlVVRkNielJIUVUxSU5IZElVVmxFVmxJd1QwSkNXVVZH -U1hkWU5IWnpPRUpwUW1OVFkyOWtDalZ1YjFwSVVrMDRSVFFyYVUxRgpTVWRCTVZWa1NYZFJOMDFF -YlVGR1NYZFlOSFp6T0VKcFFtTlRZMjlrTlc1dldraFNUVGhGTkN0cGIxSmhhMFpFUVZNS1RWSkJk -MFJuCldVUldVVkZFUlhka1JsRldRV2RSTUVWNFoyZHJRV2QxVlZZelJFMTBWelp6ZDBSQldVUldV -akJVUWtGVmQwRjNSVUl2ZWtGTVFtZE8KVmdwSVVUaEZRa0ZOUTBGUldYZEVVVmxLUzI5YVNXaDJZ -MDVCVVVWTVFsRkJSR2RuUlVKQlJtWlJjVTlVUVRkU2RqZExLMngxVVRkdwpibUZ6TkVKWmQwaEZD -amxIUlZBdmRXOW9kalpMVDNrd1ZFZFJSbUp5VWxScVJtOU1WazVDT1VKYU1YbHRUVVJhTUM5VVNY -ZEpWV00zCmQyazNZVGgwTlcxRmNWbElNVFV6ZDFjS1lWZHZiMmxUYW5sTVRHaDFTVFJ6VG5KT1Ew -OTBhWE5rUW5FeWNqSk5SbGgwTm1nd2JVRlIKV1U5UWRqaFNPRXMzTDJablUzaEhSbkY2YUhsT2JX -MVdUQW94Y1VKS2JHUjRNelJUY0hkelZFRk1VVlpRWWpSb1IzZEtlbHBtY2pGUQpZM0JGVVhnMmVF -MXVWR3c0ZUVWWFdrVXpUWE01T1hWaFZYaGlVWEZKZDFKMUNreG5RVTlyVGtOdFdUSnRPRGxXYUhw -aFNFb3hkVlk0Ck5VRmtUUzkwUkN0WmMyMXNibTVxZERsTVVrTmxhbUpDYVhCcVNVZHFUMWh5WnpG -S1VDdHNlRllLYlhWTk5IWklLMUF2Yld4dGVITlEKVUhvd1pEWTFZaXRGUjIxS1duQnZUR3RQTDNS -a1RrNTJRMWw2YWtwd1ZFVlhjRVZ6VHpaT1RXaExXVzg5Q2kwdExTMHRSVTVFSUVORgpVbFJKUmts -RFFWUkZMUzB0TFMwSwotLXtib3VuZGFyeX0tLQo= +TUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5 +PXtib3VuZGFyeX07IGNoYXJzZXQ9VVRGLTgKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogOGJp +dAoKLS17Ym91bmRhcnl9CkNvbnRlbnQtVHlwZTogYXBwbGljYXRpb24veC1wYXNzcG9pbnQtcHJv +ZmlsZTsgY2hhcnNldD1VVEYtOApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKClBF +MW5iWFJVY21WbElIaHRiRzV6UFNKemVXNWpiV3c2Wkcxa1pHWXhMaklpUGdvZ0lEeFdaWEpFVkVR +K01TNHlQQzlXWlhKRVZFUSsKQ2lBZ1BFNXZaR1UrQ2lBZ0lDQThUbTlrWlU1aGJXVStVR1Z5VUhK +dmRtbGtaWEpUZFdKelkzSnBjSFJwYjI0OEwwNXZaR1ZPWVcxbApQZ29nSUNBZ1BGSlVVSEp2Y0dW +eWRHbGxjejRLSUNBZ0lDQWdQRlI1Y0dVK0NpQWdJQ0FnSUNBZ1BFUkVSazVoYldVK2RYSnVPbmRt +CllUcHRienBvYjNSemNHOTBNbVJ2ZERBdGNHVnljSEp2ZG1sa1pYSnpkV0p6WTNKcGNIUnBiMjQ2 +TVM0d1BDOUVSRVpPWVcxbFBnb2cKSUNBZ0lDQThMMVI1Y0dVK0NpQWdJQ0E4TDFKVVVISnZjR1Z5 +ZEdsbGN6NEtJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQThUbTlrWlU1aApiV1UrYVRBd01Ud3ZUbTlr +WlU1aGJXVStDaUFnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0WlQ1SWIyMWxV +MUE4CkwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZa +R1ZPWVcxbFBrWnlhV1Z1Wkd4NVRtRnQKWlR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQThW +bUZzZFdVK1JYaGhiWEJzWlNCT1pYUjNiM0pyUEM5V1lXeDFaVDRLSUNBZwpJQ0FnSUNBOEwwNXZa +R1UrQ2lBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrUmxGRVRq +d3ZUbTlrClpVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBOFZtRnNkV1UrYUc5MGMzQnZkQzVsZUdGdGNH +eGxMbTVsZER3dlZtRnNkV1UrQ2lBZ0lDQWcKSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUR4T2Iy +UmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxKdllXMXBibWREYjI1egpiM0owYVhWdFQw +azhMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQakV4TWpJek15dzBORFUxTmpZ +OEwxWmhiSFZsClBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNB +Z0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBOFRtOWsKWlU1aGJXVStRM0psWkdWdWRHbGhiRHd2VG05 +a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05awpaVTVoYldV +K1VtVmhiRzA4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ1BGWmhiSFZsUG1WNFlXMXdiR1V1 +WTI5dFBDOVdZV3gxClpUNEtJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ1BFNXZaR1Ur +Q2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVTVoYldVK1ZYTmwKY201aGJXVlFZWE56ZDI5eVpEd3ZUbTlr +WlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEU1dgpaR1ZP +WVcxbFBsVnpaWEp1WVcxbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQ +blZ6WlhJOEwxWmhiSFZsClBnb2dJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdQ +RTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFRtRnQKWlQ1UVlYTnpkMjl5WkR3dlRtOWta +VTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhXWVd4MVpUNWpSMFo2WXpOa2RtTnRVVDA4TDFaaApi +SFZsUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1UrQ2lBZ0lD +QWdJQ0FnSUNBZ0lEeE9iMlJsClRtRnRaVDVGUVZCTlpYUm9iMlE4TDA1dlpHVk9ZVzFsUGdvZ0lD +QWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWcKSUNBOFRtOWtaVTVoYldVK1JV +RlFWSGx3WlR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQakl4UEM5 +VwpZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4VG05 +a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnCklDQThUbTlrWlU1aGJXVStTVzV1WlhKTlpYUm9iMlE4TDA1 +dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQWdJRHhXWVd4MVpUNU4KVXkxRFNFRlFMVll5UEM5 +V1lXeDFaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJs +UGdvZwpJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0Fn +SUR4T2IyUmxUbUZ0WlQ1RWFXZHBkR0ZzClEyVnlkR2xtYVdOaGRHVThMMDV2WkdWT1lXMWxQZ29n +SUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNURaWEow +YVdacFkyRjBaVlI1Y0dVOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4Vm1Gc2RXVStl +RFV3T1hZegpQQzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUNBZ0lDQWdJ +RHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4ClRtOWtaVTVoYldVK1EyVnlkRk5JUVRJMU5rWnBi +bWRsY25CeWFXNTBQQzlPYjJSbFRtRnRaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BGWmgKYkhWbFBqRm1N +V1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1X +WXhaakZtTVdZeApaakZtTVdZeFpqRm1NV1k4TDFaaGJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2Iy +UmxQZ29nSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnCklDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lD +QWdJRHhPYjJSbFRtRnRaVDVUU1UwOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWcKUEU1dlpH +VStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0WlQ1SlRWTkpQQzlPYjJSbFRtRnRaVDRLSUNB +Z0lDQWdJQ0FnSUNBZwpQRlpoYkhWbFBqRXlNelExTmlvOEwxWmhiSFZsUGdvZ0lDQWdJQ0FnSUNB +Z1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1UrCkNpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJS +bFRtRnRaVDVGUVZCVWVYQmxQQzlPYjJSbFRtRnRaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BGWmgKYkhW +bFBqSXpQQzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUNBZ0lDQThMMDV2 +WkdVK0NpQWdJQ0FnSUR3dgpUbTlrWlQ0S0lDQWdJRHd2VG05a1pUNEtJQ0E4TDA1dlpHVStDand2 +VFdkdGRGUnlaV1UrCgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXg1 +MDktY2EtY2VydApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKCkxTMHRMUzFDUlVk +SlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVJMUkVORFFXaERaMEYzU1VKQlowbEtRVWxN +YkVaa2QzcE0KVm5WeVRVRXdSME5UY1VkVFNXSXpSRkZGUWtOM1ZVRk5Ra2w0UlVSQlQwSm5UbFlL +UWtGTlZFSXdWa0pWUTBKRVVWUkZkMGhvWTA1TgpWRmwzVFZSRmVVMVVSVEZOUkVVeFYyaGpUazFx +V1hkTlZFRTFUVlJGTVUxRVJURlhha0ZUVFZKQmR3cEVaMWxFVmxGUlJFVjNaRVpSClZrRm5VVEJG +ZUUxSlNVSkpha0ZPUW1kcmNXaHJhVWM1ZHpCQ1FWRkZSa0ZCVDBOQlVUaEJUVWxKUWtOblMwTkJV +VVZCQ25wdVFWQlYKZWpJMlRYTmhaVFIzY3pRelkzcFNOREV2U2pKUmRISlRTVnBWUzIxV1ZYTldk +VzFFWWxsSWNsQk9kbFJZUzFOTldFRmpaWGRQVWtSUgpXVmdLVW5GMlNIWndiamhEYzJOQ01TdHZS +MWhhZGtoM2VHbzBlbFl3VjB0dlN6SjZaVmhyWVhVemRtTjViRE5JU1V0MWNFcG1jVEpVClJVRkRa +V1pXYW1vd2RBcEtWeXRZTXpWUVIxZHdPUzlJTlhwSlZVNVdUbFpxVXpkVmJYTTRORWwyUzJoU1Fq +ZzFNVEpRUWpsVmVVaGgKWjFoWlZsZzFSMWR3UVdOV2NIbG1jbXhTQ2taSk9WRmthR2dyVUdKck1I +VjVhM1JrWW1ZdlEyUm1aMGhQYjJWaWNsUjBkMUpzYWswdwpiMFIwV0NzeVEzWTJhakIzUWtzM2FF +UTRjRkIyWmpFcmRYa0tSM3BqZW1sblFWVXZORXQzTjJWYWNYbGtaamxDS3pWU2RYQlNLMGxhCmFY +QllOREY0UldsSmNrdFNkM0ZwTlRFM1YxZDZXR05xWVVjeVkwNWlaalExTVFwNGNFZzFVRzVXTTJr +eGRIRXdOR3BOUjFGVmVrWjMKU1VSQlVVRkNielJIUVUxSU5IZElVVmxFVmxJd1QwSkNXVVZHU1hk +WU5IWnpPRUpwUW1OVFkyOWtDalZ1YjFwSVVrMDRSVFFyYVUxRgpTVWRCTVZWa1NYZFJOMDFFYlVG +R1NYZFlOSFp6T0VKcFFtTlRZMjlrTlc1dldraFNUVGhGTkN0cGIxSmhhMFpFUVZNS1RWSkJkMFJu +CldVUldVVkZFUlhka1JsRldRV2RSTUVWNFoyZHJRV2QxVlZZelJFMTBWelp6ZDBSQldVUldVakJV +UWtGVmQwRjNSVUl2ZWtGTVFtZE8KVmdwSVVUaEZRa0ZOUTBGUldYZEVVVmxLUzI5YVNXaDJZMDVC +VVVWTVFsRkJSR2RuUlVKQlJtWlJjVTlVUVRkU2RqZExLMngxVVRkdwpibUZ6TkVKWmQwaEZDamxI +UlZBdmRXOW9kalpMVDNrd1ZFZFJSbUp5VWxScVJtOU1WazVDT1VKYU1YbHRUVVJhTUM5VVNYZEpW +V00zCmQyazNZVGgwTlcxRmNWbElNVFV6ZDFjS1lWZHZiMmxUYW5sTVRHaDFTVFJ6VG5KT1EwOTBh +WE5rUW5FeWNqSk5SbGgwTm1nd2JVRlIKV1U5UWRqaFNPRXMzTDJablUzaEhSbkY2YUhsT2JXMVdU +QW94Y1VKS2JHUjRNelJUY0hkelZFRk1VVlpRWWpSb1IzZEtlbHBtY2pGUQpZM0JGVVhnMmVFMXVW +R3c0ZUVWWFdrVXpUWE01T1hWaFZYaGlVWEZKZDFKMUNreG5RVTlyVGtOdFdUSnRPRGxXYUhwaFNF +b3hkVlk0Ck5VRmtUUzkwUkN0WmMyMXNibTVxZERsTVVrTmxhbUpDYVhCcVNVZHFUMWh5WnpGS1VD +dHNlRllLYlhWTk5IWklLMUF2Yld4dGVITlEKVUhvd1pEWTFZaXRGUjIxS1duQnZUR3RQTDNSa1Rr +NTJRMWw2YWtwd1ZFVlhjRVZ6VHpaT1RXaExXVzg5Q2kwdExTMHRSVTVFSUVORgpVbFJKUmtsRFFW +UkZMUzB0TFMwSwotLXtib3VuZGFyeX0tLQo= \ No newline at end of file diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithUpdateIdentifier.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithUpdateIdentifier.base64 index f4d2abb08e36..bab7607512c8 100644 --- a/wifi/tests/assets/hsr1/HSR1ProfileWithUpdateIdentifier.base64 +++ b/wifi/tests/assets/hsr1/HSR1ProfileWithUpdateIdentifier.base64 @@ -14,75 +14,75 @@ MVpUNEsKSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoYldV K2FUQXdNVHd2VG05a1pVNWhiV1UrQ2lBZwpJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJS bFRtRnRaVDVJYjIxbFUxQThMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJRHhPCmIyUmxQZ29nSUNB Z0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGtaeWFXVnVaR3g1VG1GdFpUd3ZUbTlrWlU1aGJXVStDaUFn -SUNBZ0lDQWcKSUNBOFZtRnNkV1UrUTJWdWRIVnllU0JJYjNWelpUd3ZWbUZzZFdVK0NpQWdJQ0Fn -SUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUR4TwpiMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZP -WVcxbFBrWlJSRTQ4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ1BGWmhiSFZsClBtMXBOaTVq -Ynk1MWF6d3ZWbUZzZFdVK0NpQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxQ -Z29nSUNBZ0lDQWcKSUNBZ1BFNXZaR1ZPWVcxbFBsSnZZVzFwYm1kRGIyNXpiM0owYVhWdFQwazhM -MDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEZaaApiSFZsUGpFeE1qSXpNeXcwTkRVMU5qWThM -MVpoYkhWbFBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnUEM5T2IyUmxQZ29nCklDQWdJ -Q0E4VG05a1pUNEtJQ0FnSUNBZ0lDQThUbTlrWlU1aGJXVStRM0psWkdWdWRHbGhiRHd2VG05a1pV -NWhiV1UrQ2lBZ0lDQWcKSUNBZ1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVTVoYldVK1Vt -VmhiRzA4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZwpQRlpoYkhWbFBuTm9ZV3RsYmk1emRH -bHljbVZrTG1OdmJUd3ZWbUZzZFdVK0NpQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnCklE -eE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBsVnpaWEp1WVcxbFVHRnpjM2R2Y21R -OEwwNXZaR1ZPWVcxbFBnb2cKSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4 -T2IyUmxUbUZ0WlQ1VmMyVnlibUZ0WlR3dlRtOWtaVTVoYldVKwpDaUFnSUNBZ0lDQWdJQ0FnSUR4 -V1lXeDFaVDVxWVcxbGN6d3ZWbUZzZFdVK0NpQWdJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0Fn -CklDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxCaGMzTjNiM0pr -UEM5T2IyUmxUbUZ0WlQ0S0lDQWcKSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQbGx0T1hWYVJFRjNUbmM5 -UFR3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0FnSUNBOEwwNXZaR1UrQ2lBZwpJQ0FnSUNBZ0lDQThUbTlr -WlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWxQa1ZCVUUxbGRHaHZaRHd2VG05a1pVNWhi -V1UrCkNpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0FnSUR4T2IyUmxU -bUZ0WlQ1RlFWQlVlWEJsUEM5T2IyUmwKVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnSUNBOFZtRnNk -V1UrTWpFOEwxWmhiSFZsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThMMDV2WkdVKwpDaUFnSUNBZ0lDQWdJ -Q0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeE9iMlJsVG1GdFpUNUpibTVsY2sxbGRH -aHZaRHd2ClRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQazFUTFVOSVFW -QXRWakk4TDFaaGJIVmxQZ29nSUNBZ0lDQWcKSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ0lD -QThMMDV2WkdVK0NpQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUR4TwpiMlJsUGdvZ0lD -QWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBrUnBaMmwwWVd4RFpYSjBhV1pwWTJGMFpUd3ZUbTlrWlU1 -aGJXVStDaUFnCklDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcx -bFBrTmxjblJwWm1sallYUmxWSGx3WlR3dlRtOWsKWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUR4 -V1lXeDFaVDU0TlRBNWRqTThMMVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdQQzlPYjJSbApQZ29nSUNB -Z0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0WlQ1RFpYSjBVMGhC -TWpVMlJtbHVaMlZ5CmNISnBiblE4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZz -ZFdVK01XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXgKWmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4 -WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaand2Vm1Gc2RXVStDaUFnSUNBZwpJQ0Fn -SUNBOEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJSbFBnb2dJ -Q0FnSUNBZ0lDQWdQRTV2ClpHVk9ZVzFsUGxOSlRUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJ -Q0E4VG05a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEU1dlpHVk8KWVcxbFBrbE5VMGs4TDA1dlpHVk9Z -VzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzZFdVK2FXMXphVHd2Vm1Gc2RXVStDaUFnSUNBZwpJ -Q0FnSUNBOEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BF -NXZaR1ZPWVcxbFBrVkJVRlI1CmNHVThMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBOFZt -RnNkV1UrTWpROEwxWmhiSFZsUGdvZ0lDQWdJQ0FnSUNBZ1BDOU8KYjJSbFBnb2dJQ0FnSUNBZ0lE -d3ZUbTlrWlQ0S0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ1BDOU9iMlJsUGdvZ0lEd3ZUbTlrWlQ0 -SwpQQzlOWjIxMFZISmxaVDRLCgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlv -bi94LXg1MDktY2EtY2VydApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKCkxTMHRM -UzFDUlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVJMUkVORFFXaERaMEYzU1VKQlow -bEtRVWxNYkVaa2QzcE0KVm5WeVRVRXdSME5UY1VkVFNXSXpSRkZGUWtOM1ZVRk5Ra2w0UlVSQlQw -Sm5UbFlLUWtGTlZFSXdWa0pWUTBKRVVWUkZkMGhvWTA1TgpWRmwzVFZSRmVVMVVSVEZOUkVVeFYy -aGpUazFxV1hkTlZFRTFUVlJGTVUxRVJURlhha0ZUVFZKQmR3cEVaMWxFVmxGUlJFVjNaRVpSClZr -Rm5VVEJGZUUxSlNVSkpha0ZPUW1kcmNXaHJhVWM1ZHpCQ1FWRkZSa0ZCVDBOQlVUaEJUVWxKUWtO -blMwTkJVVVZCQ25wdVFWQlYKZWpJMlRYTmhaVFIzY3pRelkzcFNOREV2U2pKUmRISlRTVnBWUzIx -V1ZYTldkVzFFWWxsSWNsQk9kbFJZUzFOTldFRmpaWGRQVWtSUgpXVmdLVW5GMlNIWndiamhEYzJO -Q01TdHZSMWhhZGtoM2VHbzBlbFl3VjB0dlN6SjZaVmhyWVhVemRtTjViRE5JU1V0MWNFcG1jVEpV -ClJVRkRaV1pXYW1vd2RBcEtWeXRZTXpWUVIxZHdPUzlJTlhwSlZVNVdUbFpxVXpkVmJYTTRORWwy -UzJoU1FqZzFNVEpRUWpsVmVVaGgKWjFoWlZsZzFSMWR3UVdOV2NIbG1jbXhTQ2taSk9WRmthR2dy -VUdKck1IVjVhM1JrWW1ZdlEyUm1aMGhQYjJWaWNsUjBkMUpzYWswdwpiMFIwV0NzeVEzWTJhakIz -UWtzM2FFUTRjRkIyWmpFcmRYa0tSM3BqZW1sblFWVXZORXQzTjJWYWNYbGtaamxDS3pWU2RYQlNL -MGxhCmFYQllOREY0UldsSmNrdFNkM0ZwTlRFM1YxZDZXR05xWVVjeVkwNWlaalExTVFwNGNFZzFV -RzVXTTJreGRIRXdOR3BOUjFGVmVrWjMKU1VSQlVVRkNielJIUVUxSU5IZElVVmxFVmxJd1QwSkNX -VVZHU1hkWU5IWnpPRUpwUW1OVFkyOWtDalZ1YjFwSVVrMDRSVFFyYVUxRgpTVWRCTVZWa1NYZFJO -MDFFYlVGR1NYZFlOSFp6T0VKcFFtTlRZMjlrTlc1dldraFNUVGhGTkN0cGIxSmhhMFpFUVZNS1RW -SkJkMFJuCldVUldVVkZFUlhka1JsRldRV2RSTUVWNFoyZHJRV2QxVlZZelJFMTBWelp6ZDBSQldV -UldVakJVUWtGVmQwRjNSVUl2ZWtGTVFtZE8KVmdwSVVUaEZRa0ZOUTBGUldYZEVVVmxLUzI5YVNX -aDJZMDVCVVVWTVFsRkJSR2RuUlVKQlJtWlJjVTlVUVRkU2RqZExLMngxVVRkdwpibUZ6TkVKWmQw -aEZDamxIUlZBdmRXOW9kalpMVDNrd1ZFZFJSbUp5VWxScVJtOU1WazVDT1VKYU1YbHRUVVJhTUM5 -VVNYZEpWV00zCmQyazNZVGgwTlcxRmNWbElNVFV6ZDFjS1lWZHZiMmxUYW5sTVRHaDFTVFJ6VG5K -T1EwOTBhWE5rUW5FeWNqSk5SbGgwTm1nd2JVRlIKV1U5UWRqaFNPRXMzTDJablUzaEhSbkY2YUhs -T2JXMVdUQW94Y1VKS2JHUjRNelJUY0hkelZFRk1VVlpRWWpSb1IzZEtlbHBtY2pGUQpZM0JGVVhn -MmVFMXVWR3c0ZUVWWFdrVXpUWE01T1hWaFZYaGlVWEZKZDFKMUNreG5RVTlyVGtOdFdUSnRPRGxX -YUhwaFNFb3hkVlk0Ck5VRmtUUzkwUkN0WmMyMXNibTVxZERsTVVrTmxhbUpDYVhCcVNVZHFUMWh5 -WnpGS1VDdHNlRllLYlhWTk5IWklLMUF2Yld4dGVITlEKVUhvd1pEWTFZaXRGUjIxS1duQnZUR3RQ -TDNSa1RrNTJRMWw2YWtwd1ZFVlhjRVZ6VHpaT1RXaExXVzg5Q2kwdExTMHRSVTVFSUVORgpVbFJK -UmtsRFFWUkZMUzB0TFMwSwotLXtib3VuZGFyeX0tLQo= \ No newline at end of file +SUNBZ0lDQWcKSUNBOFZtRnNkV1UrUlhoaGJYQnNaU0JPWlhSM2IzSnJQQzlXWVd4MVpUNEtJQ0Fn +SUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZwpQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlr +WlU1aGJXVStSbEZFVGp3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQThWbUZzCmRXVSthRzkw +YzNCdmRDNWxlR0Z0Y0d4bExtNWxkRHd2Vm1Gc2RXVStDaUFnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJ +Q0FnSUNBZ0lEeE8KYjJSbFBnb2dJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWxQbEp2WVcxcGJtZERi +MjV6YjNKMGFYVnRUMGs4TDA1dlpHVk9ZVzFsUGdvZwpJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBqRXhN +akl6TXl3ME5EVTFOalk4TDFaaGJIVmxQZ29nSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnCklDQWdQ +QzlPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrUTNKbFpH +VnVkR2xoYkR3dlRtOWsKWlU1aGJXVStDaUFnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lD +QThUbTlrWlU1aGJXVStVbVZoYkcwOEwwNXZaR1ZPWVcxbApQZ29nSUNBZ0lDQWdJQ0FnUEZaaGJI +VmxQbVY0WVcxd2JHVXVZMjl0UEM5V1lXeDFaVDRLSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnCklD +QWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrVlhObGNtNWhiV1ZRWVhO +emQyOXlaRHd2VG05a1pVNWgKYldVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNB +Z0lDQWdQRTV2WkdWT1lXMWxQbFZ6WlhKdVlXMWxQQzlPYjJSbApUbUZ0WlQ0S0lDQWdJQ0FnSUNB +Z0lDQWdQRlpoYkhWbFBuVnpaWEk4TDFaaGJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29n +CklDQWdJQ0FnSUNBZ1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE9iMlJsVG1GdFpUNVFZWE56 +ZDI5eVpEd3ZUbTlrWlU1aGJXVSsKQ2lBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1alIwWjZZek5r +ZG1OdFVUMDhMMVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdQQzlPYjJSbApQZ29nSUNBZ0lDQWdJQ0Fn +UEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0WlQ1RlFWQk5aWFJvYjJROEwwNXZa +R1ZPCllXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZ0lDQThU +bTlrWlU1aGJXVStSVUZRVkhsd1pUd3YKVG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdQ +RlpoYkhWbFBqSXhQQzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEM5TwpiMlJsUGdvZ0lDQWdJ +Q0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrU1c1dVpY +Sk5aWFJvCmIyUThMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1TlV5 +MURTRUZRTFZZeVBDOVdZV3gxWlQ0S0lDQWcKSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lD +QWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUNBZwpJQ0E4VG05a1pU +NEtJQ0FnSUNBZ0lDQWdJRHhPYjJSbFRtRnRaVDVFYVdkcGRHRnNRMlZ5ZEdsbWFXTmhkR1U4TDA1 +dlpHVk9ZVzFsClBnb2dJQ0FnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJS +bFRtRnRaVDVEWlhKMGFXWnBZMkYwWlZSNWNHVTgKTDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNB +Z0lDQThWbUZzZFdVK2VEVXdPWFl6UEM5V1lXeDFaVDRLSUNBZ0lDQWdJQ0FnSUR3dgpUbTlrWlQ0 +S0lDQWdJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThUbTlrWlU1aGJXVStRMlZ5 +ZEZOSVFUSTFOa1pwCmJtZGxjbkJ5YVc1MFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0Fn +UEZaaGJIVmxQakZtTVdZeFpqRm1NV1l4WmpGbU1XWXgKWmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4 +WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZOEwxWmhiSFZsUGdvZwpJQ0Fn +SUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNBOFRtOWta +VDRLSUNBZ0lDQWdJQ0FnCklEeE9iMlJsVG1GdFpUNVRTVTA4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJ +Q0FnSUNBZ1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE8KYjJSbFRtRnRaVDVKVFZOSlBDOU9i +MlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQakV5TXpRMU5pbzhMMVpoYkhWbApQ +Z29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lD +QWdJQ0FnSUR4T2IyUmxUbUZ0ClpUNUZRVkJVZVhCbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lD +QWdJQ0FnUEZaaGJIVmxQakl6UEM5V1lXeDFaVDRLSUNBZ0lDQWcKSUNBZ0lEd3ZUbTlrWlQ0S0lD +QWdJQ0FnSUNBOEwwNXZaR1UrQ2lBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUR3dlRtOWtaVDRLSUNB +OApMMDV2WkdVK0Nqd3ZUV2R0ZEZSeVpXVSsKCi0te2JvdW5kYXJ5fQpDb250ZW50LVR5cGU6IGFw +cGxpY2F0aW9uL3gteDUwOS1jYS1jZXJ0CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2 +NAoKTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVUkxSRU5EUVdoRFow +RjNTVUpCWjBsS1FVbE1iRVprZDNwTQpWblZ5VFVFd1IwTlRjVWRUU1dJelJGRkZRa04zVlVGTlFr +bDRSVVJCVDBKblRsWUtRa0ZOVkVJd1ZrSlZRMEpFVVZSRmQwaG9ZMDVOClZGbDNUVlJGZVUxVVJU +Rk5SRVV4VjJoalRrMXFXWGROVkVFMVRWUkZNVTFFUlRGWGFrRlRUVkpCZHdwRVoxbEVWbEZSUkVW +M1pFWlIKVmtGblVUQkZlRTFKU1VKSmFrRk9RbWRyY1docmFVYzVkekJDUVZGRlJrRkJUME5CVVRo +QlRVbEpRa05uUzBOQlVVVkJDbnB1UVZCVgplakkyVFhOaFpUUjNjelF6WTNwU05ERXZTakpSZEhK +VFNWcFZTMjFXVlhOV2RXMUVZbGxJY2xCT2RsUllTMU5OV0VGalpYZFBVa1JSCldWZ0tVbkYyU0ha +d2JqaERjMk5DTVN0dlIxaGFka2gzZUdvMGVsWXdWMHR2U3pKNlpWaHJZWFV6ZG1ONWJETklTVXQx +Y0VwbWNUSlUKUlVGRFpXWldhbW93ZEFwS1Z5dFlNelZRUjFkd09TOUlOWHBKVlU1V1RsWnFVemRW +YlhNNE5FbDJTMmhTUWpnMU1USlFRamxWZVVoaApaMWhaVmxnMVIxZHdRV05XY0hsbWNteFNDa1pK +T1ZGa2FHZ3JVR0pyTUhWNWEzUmtZbVl2UTJSbVowaFBiMlZpY2xSMGQxSnNhazB3CmIwUjBXQ3N5 +UTNZMmFqQjNRa3MzYUVRNGNGQjJaakVyZFhrS1IzcGplbWxuUVZVdk5FdDNOMlZhY1hsa1pqbENL +elZTZFhCU0swbGEKYVhCWU5ERjRSV2xKY2t0U2QzRnBOVEUzVjFkNldHTnFZVWN5WTA1aVpqUTFN +UXA0Y0VnMVVHNVdNMmt4ZEhFd05HcE5SMUZWZWtaMwpTVVJCVVVGQ2J6UkhRVTFJTkhkSVVWbEVW +bEl3VDBKQ1dVVkdTWGRZTkhaek9FSnBRbU5UWTI5a0NqVnViMXBJVWswNFJUUXJhVTFGClNVZEJN +VlZrU1hkUk4wMUViVUZHU1hkWU5IWnpPRUpwUW1OVFkyOWtOVzV2V2toU1RUaEZOQ3RwYjFKaGEw +WkVRVk1LVFZKQmQwUm4KV1VSV1VWRkVSWGRrUmxGV1FXZFJNRVY0WjJkclFXZDFWVll6UkUxMFZ6 +WnpkMFJCV1VSV1VqQlVRa0ZWZDBGM1JVSXZla0ZNUW1kTwpWZ3BJVVRoRlFrRk5RMEZSV1hkRVVW +bEtTMjlhU1doMlkwNUJVVVZNUWxGQlJHZG5SVUpCUm1aUmNVOVVRVGRTZGpkTEsyeDFVVGR3CmJt +RnpORUpaZDBoRkNqbEhSVkF2ZFc5b2RqWkxUM2t3VkVkUlJtSnlVbFJxUm05TVZrNUNPVUphTVhs +dFRVUmFNQzlVU1hkSlZXTTMKZDJrM1lUaDBOVzFGY1ZsSU1UVXpkMWNLWVZkdmIybFRhbmxNVEdo +MVNUUnpUbkpPUTA5MGFYTmtRbkV5Y2pKTlJsaDBObWd3YlVGUgpXVTlRZGpoU09FczNMMlpuVTNo +SFJuRjZhSGxPYlcxV1RBb3hjVUpLYkdSNE16UlRjSGR6VkVGTVVWWlFZalJvUjNkS2VscG1jakZR +ClkzQkZVWGcyZUUxdVZHdzRlRVZYV2tVelRYTTVPWFZoVlhoaVVYRkpkMUoxQ2t4blFVOXJUa050 +V1RKdE9EbFdhSHBoU0VveGRWWTQKTlVGa1RTOTBSQ3RaYzIxc2JtNXFkRGxNVWtObGFtSkNhWEJx +U1VkcVQxaHlaekZLVUN0c2VGWUtiWFZOTkhaSUsxQXZiV3h0ZUhOUQpVSG93WkRZMVlpdEZSMjFL +V25CdlRHdFBMM1JrVGs1MlExbDZha3B3VkVWWGNFVnpUelpPVFdoTFdXODlDaTB0TFMwdFJVNUVJ +RU5GClVsUkpSa2xEUVZSRkxTMHRMUzBLCi0te2JvdW5kYXJ5fS0tCg== \ No newline at end of file diff --git a/wifi/tests/assets/hsr1/README.txt b/wifi/tests/assets/hsr1/README.txt index d1f8384fc979..9f3cdc274ee1 100644 --- a/wifi/tests/assets/hsr1/README.txt +++ b/wifi/tests/assets/hsr1/README.txt @@ -2,4 +2,5 @@ HSR1ProfileWithCACert.conf - unencoded installation file that contains a Passpoi HSR1ProfileWithCACert.base64 - base64 encoded of the data contained in HSR1ProfileWithCAWith.conf HSR1ProfileWithNonBase64Part.base64 - base64 encoded installation file that contains a part of non-base64 encoding type HSR1ProfileWithMissingBoundary.base64 - base64 encoded installation file with missing end-boundary in the MIME data -HSR1ProfileWithInvalidContentType.base64 - base64 encoded installation file with that contains a MIME part with an invalid content type. +HSR1ProfileWithInvalidContentType.base64 - base64 encoded installation file with that contains a MIME part with an invalid content type +HSR1ProfileWithUpdateIdentifier.base64 - base64 encoded installation file with that contains an R2 update identifier diff --git a/wifi/tests/src/android/net/wifi/hotspot2/ConfigParserTest.java b/wifi/tests/src/android/net/wifi/hotspot2/ConfigParserTest.java index c815d7519c4c..439e67259cb9 100644 --- a/wifi/tests/src/android/net/wifi/hotspot2/ConfigParserTest.java +++ b/wifi/tests/src/android/net/wifi/hotspot2/ConfigParserTest.java @@ -87,17 +87,17 @@ public class ConfigParserTest { // HomeSP configuration. HomeSp homeSp = new HomeSp(); - homeSp.setFriendlyName("Century House"); - homeSp.setFqdn("mi6.co.uk"); + homeSp.setFriendlyName("Example Network"); + homeSp.setFqdn("hotspot.example.net"); homeSp.setRoamingConsortiumOis(new long[] {0x112233L, 0x445566L}); config.setHomeSp(homeSp); // Credential configuration. Credential credential = new Credential(); - credential.setRealm("shaken.stirred.com"); + credential.setRealm("example.com"); Credential.UserCredential userCredential = new Credential.UserCredential(); - userCredential.setUsername("james"); - userCredential.setPassword("Ym9uZDAwNw=="); + userCredential.setUsername("user"); + userCredential.setPassword("cGFzc3dvcmQ="); userCredential.setEapType(21); userCredential.setNonEapInnerMethod("MS-CHAP-V2"); credential.setUserCredential(userCredential); @@ -108,8 +108,8 @@ public class ConfigParserTest { certCredential.setCertSha256Fingerprint(certSha256Fingerprint); credential.setCertCredential(certCredential); Credential.SimCredential simCredential = new Credential.SimCredential(); - simCredential.setImsi("imsi"); - simCredential.setEapType(24); + simCredential.setImsi("123456*"); + simCredential.setEapType(23); credential.setSimCredential(simCredential); credential.setCaCertificate(FakeKeys.CA_CERT0); config.setCredential(credential); @@ -220,5 +220,4 @@ public class ConfigParserTest { // Expected configuration does not contain an update identifier assertTrue(actualConfig.equals(expectedConfig)); } - } \ No newline at end of file -- cgit v1.2.3 From f62fe1b72e1d9c6d2543498dcbee246492f7810d Mon Sep 17 00:00:00 2001 From: David Su Date: Tue, 22 Oct 2019 13:50:05 -0700 Subject: Clarify JavaDoc for SoftAP APIs Add more documentation to WifiManager's EXTRA_WIFI_AP_INTERFACE_NAME, EXTRA_WIFI_AP_MODE, and startSoftAp(). Bug: 143138160 Test: compiles Change-Id: I15a22ca8d0718e02e606ba6e19d20b1727aa93d2 --- wifi/java/android/net/wifi/WifiManager.java | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 04b073be28e2..11c21318e594 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -530,7 +530,9 @@ public class WifiManager { @SystemApi public static final String EXTRA_PREVIOUS_WIFI_AP_STATE = "previous_wifi_state"; /** - * The interface used for the softap. + * The lookup key for a String extra that stores the interface name used for the Soft AP. + * This extra is included in the broadcast {@link #WIFI_AP_STATE_CHANGED_ACTION}. + * Retrieve its value with {@link android.content.Intent#getStringExtra(String)}. * * @hide */ @@ -538,9 +540,10 @@ public class WifiManager { 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 - * @see #IFACE_IP_MODE_LOCAL_ONLY + * The lookup key for an int extra that stores the intended IP mode for this Soft AP. + * One of {@link #IFACE_IP_MODE_TETHERED} or {@link #IFACE_IP_MODE_LOCAL_ONLY}. + * This extra is included in the broadcast {@link #WIFI_AP_STATE_CHANGED_ACTION}. + * Retrieve its value with {@link android.content.Intent#getIntExtra(String, int)}. * * @hide */ @@ -2697,12 +2700,13 @@ public class WifiManager { } /** - * Start SoftAp mode with the specified configuration. - * Note that starting in access point mode disables station - * mode operation - * @param wifiConfig SSID, security and channel details as - * part of WifiConfiguration - * @return {@code true} if the operation succeeds, {@code false} otherwise + * Start Soft AP (hotspot) mode with the specified configuration. + * Note that starting Soft AP mode may disable station mode operation if the device does not + * support concurrency. + * @param wifiConfig SSID, security and channel details as part of WifiConfiguration, or null to + * use the persisted Soft AP configuration that was previously set using + * {@link #setWifiApConfiguration(WifiConfiguration)}. + * @return {@code true} if the operation succeeded, {@code false} otherwise * * @hide */ -- cgit v1.2.3 From aefe78c409fd8412ad5d7ea2c35eb46bd89b6905 Mon Sep 17 00:00:00 2001 From: James Mattis Date: Fri, 4 Oct 2019 17:46:12 -0700 Subject: Support for hotspot client visibility. Adding support for visibility into clients that connect to an active hotspot. Bug: 137309578 Test: atest FrameworksNetTests:com.android.server.connectivity.TetheringTest atest FrameworksWifiApiTests:android.net.wifi.WifiManagerTest atest FrameworksWifiApiTests:android.net.wifi.WifiClientTest Tested manually on Hawk. Change-Id: I1caeb10bc50202873e760a76b346bccd941e2574 --- wifi/java/android/net/wifi/ISoftApCallback.aidl | 8 +- wifi/java/android/net/wifi/WifiClient.aidl | 19 +++++ wifi/java/android/net/wifi/WifiClient.java | 97 ++++++++++++++++++++++ wifi/java/android/net/wifi/WifiManager.java | 26 +++--- wifi/tests/Android.mk | 1 + .../tests/src/android/net/wifi/WifiClientTest.java | 75 +++++++++++++++++ .../src/android/net/wifi/WifiManagerTest.java | 45 +++------- 7 files changed, 225 insertions(+), 46 deletions(-) create mode 100644 wifi/java/android/net/wifi/WifiClient.aidl create mode 100644 wifi/java/android/net/wifi/WifiClient.java create mode 100644 wifi/tests/src/android/net/wifi/WifiClientTest.java (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/ISoftApCallback.aidl b/wifi/java/android/net/wifi/ISoftApCallback.aidl index b8d2971e74bb..8a252dd1e447 100644 --- a/wifi/java/android/net/wifi/ISoftApCallback.aidl +++ b/wifi/java/android/net/wifi/ISoftApCallback.aidl @@ -16,6 +16,8 @@ package android.net.wifi; +import android.net.wifi.WifiClient; + /** * Interface for Soft AP callback. * @@ -36,9 +38,9 @@ oneway interface ISoftApCallback void onStateChanged(int state, int failureReason); /** - * Service to manager callback providing number of connected clients. + * Service to manager callback providing connected client's information. * - * @param numClients number of connected clients + * @param clients the currently connected clients */ - void onNumClientsChanged(int numClients); + void onConnectedClientsChanged(in List clients); } diff --git a/wifi/java/android/net/wifi/WifiClient.aidl b/wifi/java/android/net/wifi/WifiClient.aidl new file mode 100644 index 000000000000..accdaddfc848 --- /dev/null +++ b/wifi/java/android/net/wifi/WifiClient.aidl @@ -0,0 +1,19 @@ +/* + * 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; + +@JavaOnlyStableParcelable parcelable WifiClient; \ No newline at end of file diff --git a/wifi/java/android/net/wifi/WifiClient.java b/wifi/java/android/net/wifi/WifiClient.java new file mode 100644 index 000000000000..3e09580802ce --- /dev/null +++ b/wifi/java/android/net/wifi/WifiClient.java @@ -0,0 +1,97 @@ +/* + * 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.annotation.NonNull; +import android.annotation.SystemApi; +import android.net.MacAddress; +import android.os.Parcel; +import android.os.Parcelable; + +import com.android.internal.util.Preconditions; + +import java.util.Objects; + +/** @hide */ +@SystemApi +public final class WifiClient implements Parcelable { + + private final MacAddress mMacAddress; + + /** + * The mac address of this client. + */ + @NonNull + public MacAddress getMacAddress() { + return mMacAddress; + } + + private WifiClient(Parcel in) { + mMacAddress = in.readParcelable(null); + } + + /** @hide */ + public WifiClient(@NonNull MacAddress macAddress) { + Preconditions.checkNotNull(macAddress, "mMacAddress must not be null."); + + this.mMacAddress = macAddress; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeParcelable(mMacAddress, flags); + } + + @NonNull + public static final Creator CREATOR = new Creator() { + public WifiClient createFromParcel(Parcel in) { + return new WifiClient(in); + } + + public WifiClient[] newArray(int size) { + return new WifiClient[size]; + } + }; + + @NonNull + @Override + public String toString() { + return "WifiClient{" + + "mMacAddress=" + mMacAddress + + '}'; + } + + @Override + public boolean equals(@NonNull Object o) { + if (this == o) return true; + if (!(o instanceof WifiClient)) return false; + WifiClient client = (WifiClient) o; + return mMacAddress.equals(client.mMacAddress); + } + + @Override + public int hashCode() { + return Objects.hash(mMacAddress); + } +} + + diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index f626b0c46fa9..3b7690b1e8fa 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -3254,21 +3254,22 @@ public class WifiManager { /** * Called when soft AP state changes. * - * @param state new new AP state. One of {@link #WIFI_AP_STATE_DISABLED}, - * {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED}, - * {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED} + * @param state new new AP state. One of {@link #WIFI_AP_STATE_DISABLED}, + * {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED}, + * {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED} * @param failureReason reason when in failed state. One of - * {@link #SAP_START_FAILURE_GENERAL}, {@link #SAP_START_FAILURE_NO_CHANNEL} + * {@link #SAP_START_FAILURE_GENERAL}, + * {@link #SAP_START_FAILURE_NO_CHANNEL} */ - public abstract void onStateChanged(@WifiApState int state, + void onStateChanged(@WifiApState int state, @SapStartFailure int failureReason); /** - * Called when number of connected clients to soft AP changes. + * Called when the connected clients to soft AP changes. * - * @param numClients number of connected clients + * @param clients the currently connected clients */ - public abstract void onNumClientsChanged(int numClients); + void onConnectedClientsChanged(@NonNull List clients); } /** @@ -3291,18 +3292,21 @@ public class WifiManager { Log.v(TAG, "SoftApCallbackProxy: onStateChanged: state=" + state + ", failureReason=" + failureReason); } + mHandler.post(() -> { mCallback.onStateChanged(state, failureReason); }); } @Override - public void onNumClientsChanged(int numClients) { + public void onConnectedClientsChanged(List clients) { if (mVerboseLoggingEnabled) { - Log.v(TAG, "SoftApCallbackProxy: onNumClientsChanged: numClients=" + numClients); + Log.v(TAG, "SoftApCallbackProxy: onConnectedClientsChanged: clients=" + + clients.size() + " clients"); } + mHandler.post(() -> { - mCallback.onNumClientsChanged(numClients); + mCallback.onConnectedClientsChanged(clients); }); } } diff --git a/wifi/tests/Android.mk b/wifi/tests/Android.mk index 401b652289cd..3453d6ec827f 100644 --- a/wifi/tests/Android.mk +++ b/wifi/tests/Android.mk @@ -49,6 +49,7 @@ LOCAL_STATIC_JAVA_LIBRARIES := \ core-test-rules \ guava \ mockito-target-minus-junit4 \ + net-tests-utils \ frameworks-base-testutils \ truth-prebuilt \ diff --git a/wifi/tests/src/android/net/wifi/WifiClientTest.java b/wifi/tests/src/android/net/wifi/WifiClientTest.java new file mode 100644 index 000000000000..42cab55305b9 --- /dev/null +++ b/wifi/tests/src/android/net/wifi/WifiClientTest.java @@ -0,0 +1,75 @@ +/* + * 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 com.android.testutils.MiscAssertsKt.assertFieldCountEquals; +import static com.android.testutils.ParcelUtilsKt.assertParcelSane; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +import android.net.MacAddress; + +import androidx.test.filters.SmallTest; + +import org.junit.Test; + +/** + * Unit tests for {@link android.net.wifi.WifiClient}. + */ +@SmallTest +public class WifiClientTest { + private static final String INTERFACE_NAME = "wlan0"; + private static final String MAC_ADDRESS_STRING = "00:0a:95:9d:68:16"; + private static final MacAddress MAC_ADDRESS = MacAddress.fromString(MAC_ADDRESS_STRING); + + /** + * Verify parcel write/read with WifiClient. + */ + @Test + public void testWifiClientParcelWriteRead() throws Exception { + WifiClient writeWifiClient = new WifiClient(MAC_ADDRESS); + + assertParcelSane(writeWifiClient, 1); + } + + /** + * Verify equals with WifiClient. + */ + @Test + public void testWifiClientEquals() throws Exception { + WifiClient writeWifiClient = new WifiClient(MAC_ADDRESS); + WifiClient writeWifiClientEquals = new WifiClient(MAC_ADDRESS); + + assertEquals(writeWifiClient, writeWifiClientEquals); + assertEquals(writeWifiClient.hashCode(), writeWifiClientEquals.hashCode()); + assertFieldCountEquals(1, WifiClient.class); + } + + /** + * Verify not-equals with WifiClient. + */ + @Test + public void testWifiClientNotEquals() throws Exception { + final MacAddress macAddressNotEquals = MacAddress.fromString("00:00:00:00:00:00"); + WifiClient writeWifiClient = new WifiClient(MAC_ADDRESS); + WifiClient writeWifiClientNotEquals = new WifiClient(macAddressNotEquals); + + assertNotEquals(writeWifiClient, writeWifiClientNotEquals); + assertNotEquals(writeWifiClient.hashCode(), writeWifiClientNotEquals.hashCode()); + } +} diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 881dcbb80492..8d0579bde92c 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -99,8 +99,7 @@ public class WifiManagerTest { private static final String[] TEST_MAC_ADDRESSES = {"da:a1:19:0:0:0"}; @Mock Context mContext; - @Mock - android.net.wifi.IWifiManager mWifiService; + @Mock android.net.wifi.IWifiManager mWifiService; @Mock ApplicationInfo mApplicationInfo; @Mock WifiConfiguration mApConfig; @Mock SoftApCallback mSoftApCallback; @@ -115,7 +114,8 @@ public class WifiManagerTest { private TestLooper mLooper; private WifiManager mWifiManager; - @Before public void setUp() throws Exception { + @Before + public void setUp() throws Exception { MockitoAnnotations.initMocks(this); mLooper = new TestLooper(); mHandler = spy(new Handler(mLooper.getLooper())); @@ -210,7 +210,7 @@ public class WifiManagerTest { @Test public void testCreationOfLocalOnlyHotspotSubscription() throws Exception { try (WifiManager.LocalOnlyHotspotSubscription sub = - mWifiManager.new LocalOnlyHotspotSubscription()) { + mWifiManager.new LocalOnlyHotspotSubscription()) { sub.close(); } } @@ -752,17 +752,17 @@ public class WifiManagerTest { * Verify client-provided callback is being called through callback proxy */ @Test - public void softApCallbackProxyCallsOnNumClientsChanged() throws Exception { + public void softApCallbackProxyCallsOnConnectedClientsChanged() throws Exception { ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(ISoftApCallback.Stub.class); mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler); verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(), anyInt()); - final int testNumClients = 3; - callbackCaptor.getValue().onNumClientsChanged(testNumClients); + final List testClients = new ArrayList(); + callbackCaptor.getValue().onConnectedClientsChanged(testClients); mLooper.dispatchAll(); - verify(mSoftApCallback).onNumClientsChanged(testNumClients); + verify(mSoftApCallback).onConnectedClientsChanged(testClients); } /* @@ -776,14 +776,14 @@ public class WifiManagerTest { verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(), anyInt()); - final int testNumClients = 5; + final List testClients = new ArrayList(); callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_ENABLING, 0); - callbackCaptor.getValue().onNumClientsChanged(testNumClients); + callbackCaptor.getValue().onConnectedClientsChanged(testClients); callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL); mLooper.dispatchAll(); verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLING, 0); - verify(mSoftApCallback).onNumClientsChanged(testNumClients); + verify(mSoftApCallback).onConnectedClientsChanged(testClients); verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL); } @@ -1020,8 +1020,8 @@ public class WifiManagerTest { verifyNoMoreInteractions(mWifiService); } - /** -i * Verify that a call to cancel WPS immediately returns a failure. + /** + * Verify that a call to cancel WPS immediately returns a failure. */ @Test public void testCancelWpsImmediatelyFailsWithCallback() { @@ -1324,7 +1324,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Verify getting the factory MAC address. - * @throws Exception */ @Test public void testGetFactoryMacAddress() throws Exception { @@ -1371,7 +1370,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of isEnhancedOpenSupported - * @throws Exception */ @Test public void testIsEnhancedOpenSupported() throws Exception { @@ -1385,7 +1383,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of isWpa3SaeSupported - * @throws Exception */ @Test public void testIsWpa3SaeSupported() throws Exception { @@ -1399,7 +1396,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of isWpa3SuiteBSupported - * @throws Exception */ @Test public void testIsWpa3SuiteBSupported() throws Exception { @@ -1413,7 +1409,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of isEasyConnectSupported - * @throws Exception */ @Test public void testIsEasyConnectSupported() throws Exception { @@ -1427,7 +1422,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of {@link WifiManager#addNetwork(WifiConfiguration)} - * @throws Exception */ @Test public void testAddNetwork() throws Exception { @@ -1444,7 +1438,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of {@link WifiManager#addNetwork(WifiConfiguration)} - * @throws Exception */ @Test public void testUpdateNetwork() throws Exception { @@ -1466,7 +1459,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of {@link WifiManager#enableNetwork(int, boolean)} - * @throws Exception */ @Test public void testEnableNetwork() throws Exception { @@ -1478,7 +1470,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of {@link WifiManager#disableNetwork(int)} - * @throws Exception */ @Test public void testDisableNetwork() throws Exception { @@ -1500,7 +1491,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of {@link WifiManager#disconnect()} - * @throws Exception */ @Test public void testDisconnect() throws Exception { @@ -1511,7 +1501,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of {@link WifiManager#reconnect()} - * @throws Exception */ @Test public void testReconnect() throws Exception { @@ -1522,7 +1511,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of {@link WifiManager#reassociate()} - * @throws Exception */ @Test public void testReassociate() throws Exception { @@ -1533,7 +1521,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of {@link WifiManager#getSupportedFeatures()} - * @throws Exception */ @Test public void testGetSupportedFeatures() throws Exception { @@ -1560,7 +1547,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of {@link WifiManager#getControllerActivityEnergyInfo()} - * @throws Exception */ @Test public void testGetControllerActivityEnergyInfo() throws Exception { @@ -1573,7 +1559,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of {@link WifiManager#getConnectionInfo()} - * @throws Exception */ @Test public void testGetConnectionInfo() throws Exception { @@ -1585,7 +1570,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of {@link WifiManager#isDualModeSupported()} ()} - * @throws Exception */ @Test public void testIsDualModeSupported() throws Exception { @@ -1596,7 +1580,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of {@link WifiManager#isDualBandSupported()} - * @throws Exception */ @Test public void testIsDualBandSupported() throws Exception { @@ -1607,7 +1590,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of {@link WifiManager#getDhcpInfo()} - * @throws Exception */ @Test public void testGetDhcpInfo() throws Exception { @@ -1620,7 +1602,6 @@ i * Verify that a call to cancel WPS immediately returns a failure. /** * Test behavior of {@link WifiManager#setWifiEnabled(boolean)} - * @throws Exception */ @Test public void testSetWifiEnabled() throws Exception { -- cgit v1.2.3 From 26ac48bcd76cc5dc0f5fa646be29d076d7862632 Mon Sep 17 00:00:00 2001 From: Sunil Ravi Date: Fri, 25 Oct 2019 13:41:47 -0700 Subject: wifi: Change WIFI_FEATURE_XXX type from int to long This change is to avoid issues in assigning signed integer feature (WIFI_FEATURE_DPP) to long featureSet. The assignement was resulting in large, signed integer. Bug: 143363031 Test: atest com.android.wifi.server Test: Wifi ON/OFF, Connect and data transfer Test: Added logs and verified feature set saved in iface. Change-Id: Ic3828e675e49a8c1628368a7e6cf7f01e420bd96 --- wifi/java/android/net/wifi/WifiManager.java | 64 ++++++++++++++--------------- 1 file changed, 32 insertions(+), 32 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 3b7690b1e8fa..8f71b0ba136f 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -2154,69 +2154,69 @@ public class WifiManager { } /** @hide */ - public static final int WIFI_FEATURE_INFRA = 0x0001; // Basic infrastructure mode + public static final long WIFI_FEATURE_INFRA = 0x0001L; // Basic infrastructure mode /** @hide */ - public static final int WIFI_FEATURE_INFRA_5G = 0x0002; // Support for 5 GHz Band + public static final long WIFI_FEATURE_INFRA_5G = 0x0002L; // Support for 5 GHz Band /** @hide */ - public static final int WIFI_FEATURE_PASSPOINT = 0x0004; // Support for GAS/ANQP + public static final long WIFI_FEATURE_PASSPOINT = 0x0004L; // Support for GAS/ANQP /** @hide */ - public static final int WIFI_FEATURE_P2P = 0x0008; // Wifi-Direct + public static final long WIFI_FEATURE_P2P = 0x0008L; // Wifi-Direct /** @hide */ - public static final int WIFI_FEATURE_MOBILE_HOTSPOT = 0x0010; // Soft AP + public static final long WIFI_FEATURE_MOBILE_HOTSPOT = 0x0010L; // Soft AP /** @hide */ - public static final int WIFI_FEATURE_SCANNER = 0x0020; // WifiScanner APIs + public static final long WIFI_FEATURE_SCANNER = 0x0020L; // WifiScanner APIs /** @hide */ - public static final int WIFI_FEATURE_AWARE = 0x0040; // Wi-Fi AWare networking + public static final long WIFI_FEATURE_AWARE = 0x0040L; // Wi-Fi AWare networking /** @hide */ - public static final int WIFI_FEATURE_D2D_RTT = 0x0080; // Device-to-device RTT + public static final long WIFI_FEATURE_D2D_RTT = 0x0080L; // Device-to-device RTT /** @hide */ - public static final int WIFI_FEATURE_D2AP_RTT = 0x0100; // Device-to-AP RTT + public static final long WIFI_FEATURE_D2AP_RTT = 0x0100L; // Device-to-AP RTT /** @hide */ - public static final int WIFI_FEATURE_BATCH_SCAN = 0x0200; // Batched Scan (deprecated) + public static final long WIFI_FEATURE_BATCH_SCAN = 0x0200L; // Batched Scan (deprecated) /** @hide */ - public static final int WIFI_FEATURE_PNO = 0x0400; // Preferred network offload + public static final long WIFI_FEATURE_PNO = 0x0400L; // Preferred network offload /** @hide */ - public static final int WIFI_FEATURE_ADDITIONAL_STA = 0x0800; // Support for two STAs + public static final long WIFI_FEATURE_ADDITIONAL_STA = 0x0800L; // Support for two STAs /** @hide */ - public static final int WIFI_FEATURE_TDLS = 0x1000; // Tunnel directed link setup + public static final long WIFI_FEATURE_TDLS = 0x1000L; // Tunnel directed link setup /** @hide */ - public static final int WIFI_FEATURE_TDLS_OFFCHANNEL = 0x2000; // Support for TDLS off channel + public static final long WIFI_FEATURE_TDLS_OFFCHANNEL = 0x2000L; // TDLS off channel /** @hide */ - public static final int WIFI_FEATURE_EPR = 0x4000; // Enhanced power reporting + public static final long WIFI_FEATURE_EPR = 0x4000L; // Enhanced power reporting /** @hide */ - public static final int WIFI_FEATURE_AP_STA = 0x8000; // AP STA Concurrency + public static final long WIFI_FEATURE_AP_STA = 0x8000L; // AP STA Concurrency /** @hide */ - public static final int WIFI_FEATURE_LINK_LAYER_STATS = 0x10000; // Link layer stats collection + public static final long WIFI_FEATURE_LINK_LAYER_STATS = 0x10000L; // Link layer stats /** @hide */ - public static final int WIFI_FEATURE_LOGGER = 0x20000; // WiFi Logger + public static final long WIFI_FEATURE_LOGGER = 0x20000L; // WiFi Logger /** @hide */ - public static final int WIFI_FEATURE_HAL_EPNO = 0x40000; // Enhanced PNO + public static final long WIFI_FEATURE_HAL_EPNO = 0x40000L; // Enhanced PNO /** @hide */ - public static final int WIFI_FEATURE_RSSI_MONITOR = 0x80000; // RSSI Monitor + public static final long WIFI_FEATURE_RSSI_MONITOR = 0x80000L; // RSSI Monitor /** @hide */ - public static final int WIFI_FEATURE_MKEEP_ALIVE = 0x100000; // mkeep_alive + public static final long WIFI_FEATURE_MKEEP_ALIVE = 0x100000L; // mkeep_alive /** @hide */ - public static final int WIFI_FEATURE_CONFIG_NDO = 0x200000; // ND offload + public static final long WIFI_FEATURE_CONFIG_NDO = 0x200000L; // ND offload /** @hide */ - public static final int WIFI_FEATURE_TRANSMIT_POWER = 0x400000; // Capture transmit power + public static final long WIFI_FEATURE_TRANSMIT_POWER = 0x400000L; // Capture transmit power /** @hide */ - public static final int WIFI_FEATURE_CONTROL_ROAMING = 0x800000; // Control firmware roaming + public static final long WIFI_FEATURE_CONTROL_ROAMING = 0x800000L; // Control firmware roaming /** @hide */ - public static final int WIFI_FEATURE_IE_WHITELIST = 0x1000000; // Probe IE white listing + public static final long WIFI_FEATURE_IE_WHITELIST = 0x1000000L; // Probe IE white listing /** @hide */ - public static final int WIFI_FEATURE_SCAN_RAND = 0x2000000; // Random MAC & Probe seq + public static final long WIFI_FEATURE_SCAN_RAND = 0x2000000L; // Random MAC & Probe seq /** @hide */ - public static final int WIFI_FEATURE_TX_POWER_LIMIT = 0x4000000; // Set Tx power limit + public static final long WIFI_FEATURE_TX_POWER_LIMIT = 0x4000000L; // Set Tx power limit /** @hide */ - public static final int WIFI_FEATURE_WPA3_SAE = 0x8000000; // WPA3-Personal SAE + public static final long WIFI_FEATURE_WPA3_SAE = 0x8000000L; // WPA3-Personal SAE /** @hide */ - public static final int WIFI_FEATURE_WPA3_SUITE_B = 0x10000000; // WPA3-Enterprise Suite-B + public static final long WIFI_FEATURE_WPA3_SUITE_B = 0x10000000L; // WPA3-Enterprise Suite-B /** @hide */ - public static final int WIFI_FEATURE_OWE = 0x20000000; // Enhanced Open + public static final long WIFI_FEATURE_OWE = 0x20000000L; // Enhanced Open /** @hide */ - public static final int WIFI_FEATURE_LOW_LATENCY = 0x40000000; // Low Latency modes + public static final long WIFI_FEATURE_LOW_LATENCY = 0x40000000L; // Low Latency modes /** @hide */ - public static final int WIFI_FEATURE_DPP = 0x80000000; // DPP (Easy-Connect) + public static final long WIFI_FEATURE_DPP = 0x80000000L; // DPP (Easy-Connect) /** @hide */ public static final long WIFI_FEATURE_P2P_RAND_MAC = 0x100000000L; // Random P2P MAC -- cgit v1.2.3 From c7c962f3fc16eae5b8285be0eac03a1a579a15b8 Mon Sep 17 00:00:00 2001 From: Patrik Fimml Date: Tue, 10 Sep 2019 15:35:09 +0200 Subject: Configurable SoftAP: Add System API. This adds a facility for system apps (with NETWORK_SETUP_WIZARD or NETWORK_SETTINGS permission) to have more control over hotspot parameters, while allowing them to use local-only mode and the LOHS callback API for status updates. Linters give conflicting advice about parameter ordering. With startLocalOnlyHotspot(config, executor, callback), we satisfy (+) put callback last (enforced at compile time) (+) use Executor instead of Handler (+) put most meaningful argument first while we're not satisfying (-) put executor last as it is a SAM (doesn't seem to make much sense to instantiate executor as SAM anyway, users are more likely to get an instance from elsewhere) (-) for overloads, add new arguments at the end. Bug: 132705022 Test: atest SoftApConfigurationTest android.net.wifi.WifiManagerTest Test: atest android.net.wifi.cts.WifiManagerTest (not tested due to failures on emulator b/143120756) Change-Id: Ia189b3664b47a253e160acb71eafab4f217649eb --- wifi/java/android/net/wifi/IWifiManager.aidl | 4 +- .../java/android/net/wifi/SoftApConfiguration.aidl | 19 ++ .../java/android/net/wifi/SoftApConfiguration.java | 231 +++++++++++++++++++++ wifi/java/android/net/wifi/WifiManager.java | 76 +++++-- .../com/android/server/wifi/BaseWifiService.java | 10 +- .../android/net/wifi/SoftApConfigurationTest.java | 78 +++++++ .../src/android/net/wifi/WifiManagerTest.java | 47 +++-- 7 files changed, 432 insertions(+), 33 deletions(-) create mode 100644 wifi/java/android/net/wifi/SoftApConfiguration.aidl create mode 100644 wifi/java/android/net/wifi/SoftApConfiguration.java create mode 100644 wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 19be13268d27..023df70ef55a 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -34,6 +34,7 @@ import android.net.wifi.ITrafficStateCallback; import android.net.wifi.ITxPacketCountListener; import android.net.wifi.IOnWifiUsabilityStatsListener; import android.net.wifi.ScanResult; +import android.net.wifi.SoftApConfiguration; import android.net.wifi.WifiActivityEnergyInfo; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; @@ -142,7 +143,8 @@ interface IWifiManager boolean stopSoftAp(); - int startLocalOnlyHotspot(in ILocalOnlyHotspotCallback callback, String packageName); + int startLocalOnlyHotspot(in ILocalOnlyHotspotCallback callback, String packageName, + in SoftApConfiguration customConfig); void stopLocalOnlyHotspot(); diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.aidl b/wifi/java/android/net/wifi/SoftApConfiguration.aidl new file mode 100644 index 000000000000..1d06f458318f --- /dev/null +++ b/wifi/java/android/net/wifi/SoftApConfiguration.aidl @@ -0,0 +1,19 @@ +/* + * 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; + +parcelable SoftApConfiguration; \ No newline at end of file diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java new file mode 100644 index 000000000000..4cc86539926c --- /dev/null +++ b/wifi/java/android/net/wifi/SoftApConfiguration.java @@ -0,0 +1,231 @@ +/* + * 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.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.net.MacAddress; +import android.os.Parcel; +import android.os.Parcelable; + +import com.android.internal.util.Preconditions; + +import java.nio.charset.StandardCharsets; +import java.util.Objects; +import java.util.concurrent.Executor; + +/** + * WiFi configuration for a soft access point (a.k.a. Soft AP, SAP, Hotspot). + * + * This is input for the framework provided by a client app, i.e. it exposes knobs to instruct the + * framework how it should open a hotspot. It is not meant to describe the network as it will be + * seen by clients; this role is currently served by {@link WifiConfiguration} (see + * {@link WifiManager.LocalOnlyHotspotReservation#getWifiConfiguration()}). + * + * System apps can use this to configure a local-only hotspot using + * {@link WifiManager#startLocalOnlyHotspot(SoftApConfiguration, Executor, + * WifiManager.LocalOnlyHotspotCallback)}. + * + * Instances of this class are immutable; use {@link SoftApConfiguration.Builder} and its methods to + * create a new instance. + * + * @hide + */ +@SystemApi +public final class SoftApConfiguration implements Parcelable { + /** + * SSID for the AP, or null for a framework-determined SSID. + */ + private final @Nullable String mSsid; + /** + * BSSID for the AP, or null to use a framework-determined BSSID. + */ + private final @Nullable MacAddress mBssid; + /** + * Pre-shared key for WPA2-PSK encryption (non-null enables WPA2-PSK). + */ + private final @Nullable String mWpa2Passphrase; + + /** Private constructor for Builder and Parcelable implementation. */ + private SoftApConfiguration( + @Nullable String ssid, @Nullable MacAddress bssid, String wpa2Passphrase) { + mSsid = ssid; + mBssid = bssid; + mWpa2Passphrase = wpa2Passphrase; + } + + @Override + public boolean equals(Object otherObj) { + if (this == otherObj) { + return true; + } + if (!(otherObj instanceof SoftApConfiguration)) { + return false; + } + SoftApConfiguration other = (SoftApConfiguration) otherObj; + return Objects.equals(mSsid, other.mSsid) + && Objects.equals(mBssid, other.mBssid) + && Objects.equals(mWpa2Passphrase, other.mWpa2Passphrase); + } + + @Override + public int hashCode() { + return Objects.hash(mSsid, mBssid, mWpa2Passphrase); + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeString(mSsid); + dest.writeParcelable(mBssid, flags); + dest.writeString(mWpa2Passphrase); + } + + @Override + public int describeContents() { + return 0; + } + + @NonNull + public static final Creator CREATOR = new Creator() { + @Override + public SoftApConfiguration createFromParcel(Parcel in) { + return new SoftApConfiguration( + in.readString(), + in.readParcelable(MacAddress.class.getClassLoader()), + in.readString()); + } + + @Override + public SoftApConfiguration[] newArray(int size) { + return new SoftApConfiguration[size]; + } + }; + + @Nullable + public String getSsid() { + return mSsid; + } + + @Nullable + public MacAddress getBssid() { + return mBssid; + } + + @Nullable + public String getWpa2Passphrase() { + return mWpa2Passphrase; + } + + /** + * Builds a {@link SoftApConfiguration}, which allows an app to configure various aspects of a + * Soft AP. + * + * All fields are optional. By default, SSID and BSSID are automatically chosen by the + * framework, and an open network is created. + */ + public static final class Builder { + private String mSsid; + private MacAddress mBssid; + private String mWpa2Passphrase; + + /** + * Constructs a Builder with default values (see {@link Builder}). + */ + public Builder() { + mSsid = null; + mBssid = null; + mWpa2Passphrase = null; + } + + /** + * Constructs a Builder initialized from an existing {@link SoftApConfiguration} instance. + */ + public Builder(@NonNull SoftApConfiguration other) { + Objects.requireNonNull(other); + + mSsid = other.mSsid; + mBssid = other.mBssid; + mWpa2Passphrase = other.mWpa2Passphrase; + } + + /** + * Builds the {@link SoftApConfiguration}. + * + * @return A new {@link SoftApConfiguration}, as configured by previous method calls. + */ + @NonNull + public SoftApConfiguration build() { + return new SoftApConfiguration(mSsid, mBssid, mWpa2Passphrase); + } + + /** + * Specifies an SSID for the AP. + * + * @param ssid SSID of valid Unicode characters, or null to have the SSID automatically + * chosen by the framework. + * @return Builder for chaining. + * @throws IllegalArgumentException when the SSID is empty or not valid Unicode. + */ + @NonNull + public Builder setSsid(@Nullable String ssid) { + if (ssid != null) { + Preconditions.checkStringNotEmpty(ssid); + Preconditions.checkArgument(StandardCharsets.UTF_8.newEncoder().canEncode(ssid)); + } + mSsid = ssid; + return this; + } + + /** + * Specifies a BSSID for the AP. + * + * @param bssid BSSID, or null to have the BSSID chosen by the framework. The caller is + * responsible for avoiding collisions. + * @return Builder for chaining. + * @throws IllegalArgumentException when the given BSSID is the all-zero or broadcast MAC + * address. + */ + @NonNull + public Builder setBssid(@Nullable MacAddress bssid) { + if (bssid != null) { + Preconditions.checkArgument(!bssid.equals(MacAddress.ALL_ZEROS_ADDRESS)); + Preconditions.checkArgument(!bssid.equals(MacAddress.BROADCAST_ADDRESS)); + } + mBssid = bssid; + return this; + } + + /** + * Specifies that this AP should use WPA2-PSK with the given passphrase. When set to null + * and no other encryption method is configured, an open network is created. + * + * @param passphrase The passphrase to use, or null to unset a previously-set WPA2-PSK + * configuration. + * @return Builder for chaining. + * @throws IllegalArgumentException when the passphrase is the empty string + */ + @NonNull + public Builder setWpa2Passphrase(@Nullable String passphrase) { + if (passphrase != null) { + Preconditions.checkStringNotEmpty(passphrase); + } + mWpa2Passphrase = passphrase; + return this; + } + } +} diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 8f71b0ba136f..380ebf104a14 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -71,6 +71,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.concurrent.Executor; @@ -2747,13 +2748,6 @@ 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 @@ -2809,9 +2803,59 @@ public class WifiManager { * @param handler Handler to be used for callbacks. If the caller passes a null Handler, the * main thread will be used. */ + @RequiresPermission(allOf = { + android.Manifest.permission.CHANGE_WIFI_STATE, + android.Manifest.permission.ACCESS_FINE_LOCATION}) public void startLocalOnlyHotspot(LocalOnlyHotspotCallback callback, @Nullable Handler handler) { - Executor executor = executorForHandler(handler); + Executor executor = handler == null ? null : new HandlerExecutor(handler); + startLocalOnlyHotspotInternal(null, executor, callback); + } + + /** + * Starts a local-only hotspot with a specific configuration applied. See + * {@link #startLocalOnlyHotspot(LocalOnlyHotspotCallback, Handler)}. + * + * Applications need either {@link android.Manifest.permission#NETWORK_SETUP_WIZARD} or + * {@link android.Manifest.permission#NETWORK_SETTINGS} to call this method. + * + * Since custom configuration settings may be incompatible with each other, the hotspot started + * through this method cannot coexist with another hotspot created through + * startLocalOnlyHotspot. If this is attempted, the first hotspot request wins and others + * receive {@link LocalOnlyHotspotCallback#ERROR_GENERIC} through + * {@link LocalOnlyHotspotCallback#onFailed}. + * + * @param config Custom configuration for the hotspot. See {@link SoftApConfiguration}. + * @param executor Executor to run callback methods on, or null to use the main thread. + * @param callback Callback object for updates about hotspot status, or null for no updates. + * @hide + */ + @SystemApi + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_SETTINGS, + android.Manifest.permission.NETWORK_SETUP_WIZARD}) + public void startLocalOnlyHotspot(@NonNull SoftApConfiguration config, + @Nullable Executor executor, + @Nullable LocalOnlyHotspotCallback callback) { + Objects.requireNonNull(config); + startLocalOnlyHotspotInternal(config, executor, callback); + } + + /** + * Common implementation of both configurable and non-configurable LOHS. + * + * @param config App-specified configuration, or null. When present, additional privileges are + * required, and the hotspot cannot be shared with other clients. + * @param executor Executor to run callback methods on, or null to use the main thread. + * @param callback Callback object for updates about hotspot status, or null for no updates. + */ + private void startLocalOnlyHotspotInternal( + @Nullable SoftApConfiguration config, + @Nullable Executor executor, + @Nullable LocalOnlyHotspotCallback callback) { + if (executor == null) { + executor = mContext.getMainExecutor(); + } synchronized (mLock) { LocalOnlyHotspotCallbackProxy proxy = new LocalOnlyHotspotCallbackProxy(this, executor, callback); @@ -2821,7 +2865,7 @@ public class WifiManager { throw new RemoteException("Wifi service is not running"); } String packageName = mContext.getOpPackageName(); - int returnCode = iWifiManager.startLocalOnlyHotspot(proxy, packageName); + int returnCode = iWifiManager.startLocalOnlyHotspot(proxy, packageName, config); if (returnCode != LocalOnlyHotspotCallback.REQUEST_REGISTERED) { // Send message to the proxy to make sure we call back on the correct thread proxy.onHotspotFailed(returnCode); @@ -2902,7 +2946,8 @@ public class WifiManager { */ public void watchLocalOnlyHotspot(LocalOnlyHotspotObserver observer, @Nullable Handler handler) { - Executor executor = executorForHandler(handler); + Executor executor = handler == null ? mContext.getMainExecutor() + : new HandlerExecutor(handler); synchronized (mLock) { mLOHSObserverProxy = new LocalOnlyHotspotObserverProxy(this, executor, observer); @@ -3484,10 +3529,12 @@ public class WifiManager { * * @param manager WifiManager * @param executor Executor for delivering callbacks. - * @param callback LocalOnlyHotspotCallback to notify the calling application. + * @param callback LocalOnlyHotspotCallback to notify the calling application, or null. */ - LocalOnlyHotspotCallbackProxy(WifiManager manager, Executor executor, - LocalOnlyHotspotCallback callback) { + LocalOnlyHotspotCallbackProxy( + @NonNull WifiManager manager, + @NonNull Executor executor, + @Nullable LocalOnlyHotspotCallback callback) { mWifiManager = new WeakReference<>(manager); mExecutor = executor; mCallback = callback; @@ -3505,6 +3552,7 @@ public class WifiManager { } final LocalOnlyHotspotReservation reservation = manager.new LocalOnlyHotspotReservation(config); + if (mCallback == null) return; mExecutor.execute(() -> mCallback.onStarted(reservation)); } @@ -3514,6 +3562,7 @@ public class WifiManager { if (manager == null) return; Log.w(TAG, "LocalOnlyHotspotCallbackProxy: hotspot stopped"); + if (mCallback == null) return; mExecutor.execute(() -> mCallback.onStopped()); } @@ -3524,6 +3573,7 @@ public class WifiManager { Log.w(TAG, "LocalOnlyHotspotCallbackProxy: failed to start. reason: " + reason); + if (mCallback == null) return; mExecutor.execute(() -> mCallback.onFailed(reason)); } } diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index 5e6c107dc187..4b7d205e7922 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -32,6 +32,7 @@ import android.net.wifi.ITrafficStateCallback; import android.net.wifi.ITxPacketCountListener; import android.net.wifi.IWifiManager; import android.net.wifi.ScanResult; +import android.net.wifi.SoftApConfiguration; import android.net.wifi.WifiActivityEnergyInfo; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; @@ -293,8 +294,15 @@ public class BaseWifiService extends IWifiManager.Stub { throw new UnsupportedOperationException(); } - @Override + /** @deprecated replaced by newer signature */ + @Deprecated public int startLocalOnlyHotspot(ILocalOnlyHotspotCallback callback, String packageName) { + return startLocalOnlyHotspot(callback, packageName, null); + } + + @Override + public int startLocalOnlyHotspot(ILocalOnlyHotspotCallback callback, String packageName, + SoftApConfiguration customConfig) { throw new UnsupportedOperationException(); } diff --git a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java new file mode 100644 index 000000000000..949b4790d998 --- /dev/null +++ b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java @@ -0,0 +1,78 @@ +/* + * 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 com.google.common.truth.Truth.assertThat; + +import android.net.MacAddress; +import android.os.Parcel; + +import androidx.test.filters.SmallTest; + +import org.junit.Test; + +@SmallTest +public class SoftApConfigurationTest { + private SoftApConfiguration parcelUnparcel(SoftApConfiguration configIn) { + Parcel parcel = Parcel.obtain(); + parcel.writeParcelable(configIn, 0); + parcel.setDataPosition(0); + SoftApConfiguration configOut = + parcel.readParcelable(SoftApConfiguration.class.getClassLoader()); + parcel.recycle(); + return configOut; + } + + @Test + public void testBasicSettings() { + SoftApConfiguration original = new SoftApConfiguration.Builder() + .setSsid("ssid") + .setBssid(MacAddress.fromString("11:22:33:44:55:66")) + .build(); + assertThat(original.getSsid()).isEqualTo("ssid"); + assertThat(original.getBssid()).isEqualTo(MacAddress.fromString("11:22:33:44:55:66")); + assertThat(original.getWpa2Passphrase()).isNull(); + + SoftApConfiguration unparceled = parcelUnparcel(original); + assertThat(unparceled).isNotSameAs(original); + assertThat(unparceled).isEqualTo(original); + assertThat(unparceled.hashCode()).isEqualTo(original.hashCode()); + + SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build(); + assertThat(copy).isNotSameAs(original); + assertThat(copy).isEqualTo(original); + assertThat(copy.hashCode()).isEqualTo(original.hashCode()); + } + + @Test + public void testWpa2() { + SoftApConfiguration original = new SoftApConfiguration.Builder() + .setWpa2Passphrase("secretsecret") + .build(); + assertThat(original.getWpa2Passphrase()).isEqualTo("secretsecret"); + + SoftApConfiguration unparceled = parcelUnparcel(original); + assertThat(unparceled).isNotSameAs(original); + assertThat(unparceled).isEqualTo(original); + assertThat(unparceled.hashCode()).isEqualTo(original.hashCode()); + + SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build(); + assertThat(copy).isNotSameAs(original); + assertThat(copy).isEqualTo(original); + assertThat(copy.hashCode()).isEqualTo(original.hashCode()); + } +} diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 8d0579bde92c..d2516a33fead 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -173,7 +173,7 @@ public class WifiManagerTest { public void testCreationAndCloseOfLocalOnlyHotspotReservation() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), - anyString())).thenReturn(REQUEST_REGISTERED); + anyString(), eq(null))).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(mApConfig)); @@ -191,7 +191,7 @@ public class WifiManagerTest { throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), - anyString())).thenReturn(REQUEST_REGISTERED); + anyString(), eq(null))).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(mApConfig)); @@ -351,7 +351,7 @@ public class WifiManagerTest { mWifiManager.startLocalOnlyHotspot(callback, mHandler); verify(mWifiService) - .startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString()); + .startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), eq(null)); } /** @@ -362,7 +362,7 @@ public class WifiManagerTest { public void testStartLocalOnlyHotspotThrowsSecurityException() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); doThrow(new SecurityException()).when(mWifiService) - .startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString()); + .startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), eq(null)); mWifiManager.startLocalOnlyHotspot(callback, mHandler); } @@ -374,7 +374,7 @@ public class WifiManagerTest { public void testStartLocalOnlyHotspotThrowsIllegalStateException() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); doThrow(new IllegalStateException()).when(mWifiService) - .startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString()); + .startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), eq(null)); mWifiManager.startLocalOnlyHotspot(callback, mHandler); } @@ -385,7 +385,7 @@ public class WifiManagerTest { public void testCorrectLooperIsUsedForHandler() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), - anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE); + anyString(), eq(null))).thenReturn(ERROR_INCOMPATIBLE_MODE); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mLooper.dispatchAll(); assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason); @@ -404,7 +404,7 @@ public class WifiManagerTest { when(mContext.getMainExecutor()).thenReturn(altLooper.getNewExecutor()); TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), - anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE); + anyString(), eq(null))).thenReturn(ERROR_INCOMPATIBLE_MODE); mWifiManager.startLocalOnlyHotspot(callback, null); altLooper.dispatchAll(); assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason); @@ -423,7 +423,7 @@ public class WifiManagerTest { Handler callbackHandler = new Handler(callbackLooper.getLooper()); ArgumentCaptor internalCallback = ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); - when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString())) + when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(), eq(null))) .thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, callbackHandler); callbackLooper.dispatchAll(); @@ -449,7 +449,7 @@ public class WifiManagerTest { Handler callbackHandler = new Handler(callbackLooper.getLooper()); ArgumentCaptor internalCallback = ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); - when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString())) + when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(), eq(null))) .thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, callbackHandler); callbackLooper.dispatchAll(); @@ -474,7 +474,7 @@ public class WifiManagerTest { Handler callbackHandler = new Handler(callbackLooper.getLooper()); ArgumentCaptor internalCallback = ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); - when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString())) + when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(), eq(null))) .thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, callbackHandler); callbackLooper.dispatchAll(); @@ -497,7 +497,7 @@ public class WifiManagerTest { Handler callbackHandler = new Handler(callbackLooper.getLooper()); ArgumentCaptor internalCallback = ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); - when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString())) + when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(), eq(null))) .thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, callbackHandler); callbackLooper.dispatchAll(); @@ -517,7 +517,7 @@ public class WifiManagerTest { public void testLocalOnlyHotspotCallbackFullOnIncompatibleMode() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), - anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE); + anyString(), eq(null))).thenReturn(ERROR_INCOMPATIBLE_MODE); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mLooper.dispatchAll(); assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason); @@ -533,7 +533,7 @@ public class WifiManagerTest { public void testLocalOnlyHotspotCallbackFullOnTetheringDisallowed() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), - anyString())).thenReturn(ERROR_TETHERING_DISALLOWED); + anyString(), eq(null))).thenReturn(ERROR_TETHERING_DISALLOWED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mLooper.dispatchAll(); assertEquals(ERROR_TETHERING_DISALLOWED, callback.mFailureReason); @@ -550,7 +550,7 @@ public class WifiManagerTest { public void testLocalOnlyHotspotCallbackFullOnSecurityException() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); doThrow(new SecurityException()).when(mWifiService) - .startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString()); + .startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), eq(null)); try { mWifiManager.startLocalOnlyHotspot(callback, mHandler); } catch (SecurityException e) { @@ -571,7 +571,7 @@ public class WifiManagerTest { public void testLocalOnlyHotspotCallbackFullOnNoChannelError() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), - anyString())).thenReturn(REQUEST_REGISTERED); + anyString(), eq(null))).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mLooper.dispatchAll(); //assertEquals(ERROR_NO_CHANNEL, callback.mFailureReason); @@ -587,7 +587,7 @@ public class WifiManagerTest { public void testCancelLocalOnlyHotspotRequestCallsStopOnWifiService() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), - anyString())).thenReturn(REQUEST_REGISTERED); + anyString(), eq(null))).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mWifiManager.cancelLocalOnlyHotspotRequest(); verify(mWifiService).stopLocalOnlyHotspot(); @@ -609,7 +609,7 @@ public class WifiManagerTest { public void testCallbackAfterLocalOnlyHotspotWasCancelled() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), - anyString())).thenReturn(REQUEST_REGISTERED); + anyString(), eq(null))).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mWifiManager.cancelLocalOnlyHotspotRequest(); verify(mWifiService).stopLocalOnlyHotspot(); @@ -628,7 +628,7 @@ public class WifiManagerTest { public void testCancelAfterLocalOnlyHotspotCallbackTriggered() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), - anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE); + anyString(), eq(null))).thenReturn(ERROR_INCOMPATIBLE_MODE); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mLooper.dispatchAll(); assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason); @@ -639,6 +639,17 @@ public class WifiManagerTest { verify(mWifiService, never()).stopLocalOnlyHotspot(); } + @Test + public void testStartLocalOnlyHotspotForwardsCustomConfig() throws Exception { + SoftApConfiguration customConfig = new SoftApConfiguration.Builder() + .setSsid("customSsid") + .build(); + TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); + mWifiManager.startLocalOnlyHotspot(customConfig, mExecutor, callback); + verify(mWifiService).startLocalOnlyHotspot( + any(ILocalOnlyHotspotCallback.class), anyString(), eq(customConfig)); + } + /** * Verify the watchLocalOnlyHotspot call goes to WifiServiceImpl. */ -- cgit v1.2.3 From 48b101f5a08bbb4cd66bdce2ffd46ad9c97272b9 Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Mon, 19 Aug 2019 14:28:03 -0700 Subject: Add carrier ID field for WifiConfiguration and PasspointConfiguration This is only for the load and save Carrier ID field. Bug: 130875004 Test: build, bootup, unit test Change-Id: Id48587ca26fc9dc0f7678b5a449e2d39a2e90dae --- wifi/java/android/net/wifi/WifiConfiguration.java | 13 +++++++++ .../android/net/wifi/WifiEnterpriseConfig.java | 19 +++++++++++++ .../android/net/wifi/WifiNetworkSuggestion.java | 29 ++++++++++++++++++++ .../net/wifi/hotspot2/PasspointConfiguration.java | 32 +++++++++++++++++++++- 4 files changed, 92 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 3dc5a628fe7c..30c24d37a494 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -34,6 +34,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.os.SystemClock; import android.os.UserHandle; +import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.BackupUtils; import android.util.Log; @@ -729,6 +730,14 @@ public class WifiConfiguration implements Parcelable { @SystemApi public String lastUpdateName; + /** + * The carrier ID identifies the operator who provides this network configuration. + * see {@link TelephonyManager#getSimCarrierId()} + * @hide + */ + @SystemApi + public int carrierId = TelephonyManager.UNKNOWN_CARRIER_ID; + /** * @hide * Status of user approval for connection @@ -1850,6 +1859,7 @@ public class WifiConfiguration implements Parcelable { .append(" PRIO: ").append(this.priority) .append(" HIDDEN: ").append(this.hiddenSSID) .append(" PMF: ").append(this.requirePMF) + .append("CarrierId: ").append(this.carrierId) .append('\n'); @@ -2443,6 +2453,7 @@ public class WifiConfiguration implements Parcelable { randomizedMacExpirationTimeMs = source.randomizedMacExpirationTimeMs; requirePMF = source.requirePMF; updateIdentifier = source.updateIdentifier; + carrierId = source.carrierId; } } @@ -2517,6 +2528,7 @@ public class WifiConfiguration implements Parcelable { dest.writeInt(macRandomizationSetting); dest.writeInt(osu ? 1 : 0); dest.writeLong(randomizedMacExpirationTimeMs); + dest.writeInt(carrierId); } /** Implement the Parcelable interface {@hide} */ @@ -2593,6 +2605,7 @@ public class WifiConfiguration implements Parcelable { config.macRandomizationSetting = in.readInt(); config.osu = in.readInt() != 0; config.randomizedMacExpirationTimeMs = in.readLong(); + config.carrierId = in.readInt(); return config; } diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java index f8c20111d79b..7b99a2b5502f 100644 --- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java +++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java @@ -1263,4 +1263,23 @@ public class WifiEnterpriseConfig implements Parcelable { public @Ocsp int getOcsp() { return mOcsp; } + + /** + * If the current authentication method needs SIM card. + * @return true if the credential information require SIM card for current authentication + * method, otherwise it returns false. + * @hide + */ + public boolean requireSimCredential() { + if (mEapMethod == Eap.SIM || mEapMethod == Eap.AKA || mEapMethod == Eap.AKA_PRIME) { + return true; + } + if (mEapMethod == Eap.PEAP) { + if (mPhase2Method == Phase2.SIM || mPhase2Method == Phase2.AKA + || mPhase2Method == Phase2.AKA_PRIME) { + return true; + } + } + return false; + } } diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java index 9b529cee58b3..246e96f4ce3f 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java +++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java @@ -21,12 +21,15 @@ import static com.android.internal.util.Preconditions.checkNotNull; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.RequiresPermission; +import android.annotation.SystemApi; 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; +import android.telephony.TelephonyManager; import android.text.TextUtils; import java.nio.charset.CharsetEncoder; @@ -107,6 +110,12 @@ public final class WifiNetworkSuggestion implements Parcelable { */ private int mPriority; + /** + * The carrier ID identifies the operator who provides this network configuration. + * see {@link TelephonyManager#getSimCarrierId()} + */ + private int mCarrierId; + public Builder() { mSsid = null; mBssid = null; @@ -121,6 +130,7 @@ public final class WifiNetworkSuggestion implements Parcelable { mIsUserInteractionRequired = false; mIsMetered = false; mPriority = UNASSIGNED_PRIORITY; + mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID; } /** @@ -257,6 +267,23 @@ public final class WifiNetworkSuggestion implements Parcelable { return this; } + /** + * Set the carrier ID of the network operator. The carrier ID associates a Suggested + * network with a specific carrier (and therefore SIM). The carrier ID must be provided + * for any network which uses the SIM-based authentication: e.g. EAP-SIM, EAP-AKA, + * EAP-AKA', and EAP-PEAP with SIM-based phase 2 authentication. + * @param carrierId see {@link TelephonyManager#getSimCarrierId()}. + * @return Instance of {@link Builder} to enable chaining of the builder method. + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_CARRIER_PROVISIONING) + public @NonNull Builder setCarrierId(int carrierId) { + mCarrierId = carrierId; + return this; + } + /** * Specifies whether this represents a hidden network. *

    @@ -380,6 +407,7 @@ public final class WifiNetworkSuggestion implements Parcelable { wifiConfiguration.meteredOverride = mIsMetered ? WifiConfiguration.METERED_OVERRIDE_METERED : WifiConfiguration.METERED_OVERRIDE_NONE; + wifiConfiguration.carrierId = mCarrierId; return wifiConfiguration; } @@ -405,6 +433,7 @@ public final class WifiNetworkSuggestion implements Parcelable { wifiConfiguration.meteredOverride = mIsMetered ? WifiConfiguration.METERED_OVERRIDE_METERED : WifiConfiguration.METERED_OVERRIDE_NONE; + mPasspointConfiguration.setCarrierId(mCarrierId); return wifiConfiguration; } diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java index e9aa076798e1..5befb54ce50a 100644 --- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java +++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java @@ -24,6 +24,7 @@ import android.net.wifi.hotspot2.pps.UpdateParameter; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; +import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; @@ -397,6 +398,30 @@ public final class PasspointConfiguration implements Parcelable { return mServiceFriendlyNames.get(mServiceFriendlyNames.keySet().stream().findFirst().get()); } + /** + * The carrier ID identifies the operator who provides this network configuration. + * see {@link TelephonyManager#getSimCarrierId()} + */ + private int mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID; + + /** + * Set the carrier ID associated with current configuration. + * @param carrierId {@code mCarrierId} + * @hide + */ + public void setCarrierId(int carrierId) { + this.mCarrierId = carrierId; + } + + /** + * Get the carrier ID associated with current configuration. + * @return {@code mCarrierId} + * @hide + */ + public int getCarrierId() { + return mCarrierId; + } + /** * Constructor for creating PasspointConfiguration with default values. */ @@ -438,6 +463,7 @@ public final class PasspointConfiguration implements Parcelable { mUsageLimitUsageTimePeriodInMinutes = source.mUsageLimitUsageTimePeriodInMinutes; mServiceFriendlyNames = source.mServiceFriendlyNames; mAaaServerTrustedNames = source.mAaaServerTrustedNames; + mCarrierId = source.mCarrierId; } @Override @@ -466,6 +492,7 @@ public final class PasspointConfiguration implements Parcelable { bundle.putSerializable("serviceFriendlyNames", (HashMap) mServiceFriendlyNames); dest.writeBundle(bundle); + dest.writeInt(mCarrierId); } @Override @@ -495,6 +522,7 @@ public final class PasspointConfiguration implements Parcelable { && mUsageLimitStartTimeInMillis == that.mUsageLimitStartTimeInMillis && mUsageLimitDataLimit == that.mUsageLimitDataLimit && mUsageLimitTimeLimitInMinutes == that.mUsageLimitTimeLimitInMinutes + && mCarrierId == that.mCarrierId && (mServiceFriendlyNames == null ? that.mServiceFriendlyNames == null : mServiceFriendlyNames.equals(that.mServiceFriendlyNames)); } @@ -505,7 +533,7 @@ public final class PasspointConfiguration implements Parcelable { mUpdateIdentifier, mCredentialPriority, mSubscriptionCreationTimeInMillis, mSubscriptionExpirationTimeInMillis, mUsageLimitUsageTimePeriodInMinutes, mUsageLimitStartTimeInMillis, mUsageLimitDataLimit, mUsageLimitTimeLimitInMinutes, - mServiceFriendlyNames); + mServiceFriendlyNames, mCarrierId); } @Override @@ -558,6 +586,7 @@ public final class PasspointConfiguration implements Parcelable { if (mServiceFriendlyNames != null) { builder.append("ServiceFriendlyNames: ").append(mServiceFriendlyNames); } + builder.append("CarrierId:" + mCarrierId); return builder.toString(); } @@ -662,6 +691,7 @@ public final class PasspointConfiguration implements Parcelable { Map friendlyNamesMap = (HashMap) bundle.getSerializable( "serviceFriendlyNames"); config.setServiceFriendlyNames(friendlyNamesMap); + config.mCarrierId = in.readInt(); return config; } -- cgit v1.2.3 From 070fb4411ad1aa8e7771a173612121c4ca373815 Mon Sep 17 00:00:00 2001 From: David Su Date: Tue, 29 Oct 2019 18:13:19 -0700 Subject: WifiScanner.getAvailableChannels(): throw exception instead of returning null On RemoteException, rethrow as RuntimeException instead of returning null. Bug: 143550768 Test: compiles Change-Id: Ia4ab148e4fc9efbd19c37abb244a5d3360d40fa0 --- wifi/java/android/net/wifi/WifiScanner.java | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index 21189a411d94..67993e1b72db 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -19,7 +19,6 @@ package android.net.wifi; import android.Manifest; import android.annotation.IntDef; import android.annotation.NonNull; -import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.annotation.SystemApi; @@ -134,14 +133,14 @@ public class WifiScanner { * @hide */ @SystemApi - @Nullable + @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public List getAvailableChannels(@WifiBand int band) { try { Bundle bundle = mService.getAvailableChannels(band, mContext.getOpPackageName()); return bundle.getIntegerArrayList(GET_AVAILABLE_CHANNELS_EXTRA); } catch (RemoteException e) { - return null; + throw e.rethrowFromSystemServer(); } } @@ -344,7 +343,7 @@ public class WifiScanner { } /** Implement the Parcelable interface {@hide} */ - public static final @android.annotation.NonNull Creator CREATOR = + public static final @NonNull Creator CREATOR = new Creator() { public ScanSettings createFromParcel(Parcel in) { ScanSettings settings = new ScanSettings(); @@ -492,7 +491,7 @@ public class WifiScanner { } /** Implement the Parcelable interface {@hide} */ - public static final @android.annotation.NonNull Creator CREATOR = + public static final @NonNull Creator CREATOR = new Creator() { public ScanData createFromParcel(Parcel in) { int id = in.readInt(); @@ -541,7 +540,7 @@ public class WifiScanner { } /** Implement the Parcelable interface {@hide} */ - public static final @android.annotation.NonNull Creator CREATOR = + public static final @NonNull Creator CREATOR = new Creator() { public ParcelableScanData createFromParcel(Parcel in) { int n = in.readInt(); @@ -589,7 +588,7 @@ public class WifiScanner { } /** Implement the Parcelable interface {@hide} */ - public static final @android.annotation.NonNull Creator CREATOR = + public static final @NonNull Creator CREATOR = new Creator() { public ParcelableScanResults createFromParcel(Parcel in) { int n = in.readInt(); @@ -720,7 +719,7 @@ public class WifiScanner { } /** Implement the Parcelable interface {@hide} */ - public static final @android.annotation.NonNull Creator CREATOR = + public static final @NonNull Creator CREATOR = new Creator() { public PnoSettings createFromParcel(Parcel in) { PnoSettings settings = new PnoSettings(); @@ -1068,7 +1067,7 @@ public class WifiScanner { } /** Implement the Parcelable interface {@hide} */ - public static final @android.annotation.NonNull Creator CREATOR = + public static final @NonNull Creator CREATOR = new Creator() { public WifiChangeSettings createFromParcel(Parcel in) { return new WifiChangeSettings(); @@ -1179,7 +1178,7 @@ public class WifiScanner { } /** Implement the Parcelable interface {@hide} */ - public static final @android.annotation.NonNull Creator CREATOR = + public static final @NonNull Creator CREATOR = new Creator() { public HotlistSettings createFromParcel(Parcel in) { HotlistSettings settings = new HotlistSettings(); @@ -1412,7 +1411,7 @@ public class WifiScanner { } /** Implement the Parcelable interface {@hide} */ - public static final @android.annotation.NonNull Creator CREATOR = + public static final @NonNull Creator CREATOR = new Creator() { public OperationResult createFromParcel(Parcel in) { int reason = in.readInt(); -- cgit v1.2.3 From 0f8fa208482bdfd56e55300c5ac7692d02b71c8c Mon Sep 17 00:00:00 2001 From: "Nate(Qiang) Jiang" Date: Wed, 30 Oct 2019 14:05:05 -0700 Subject: add support for multiple listeners from same package Bug: 143138047 Test: atest android.net.wifi Test: atest com.android.server.wifi Change-Id: Ia1ce78bf8fd540869f74308c1d25a358ea344e58 --- wifi/java/android/net/wifi/WifiManager.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 380ebf104a14..07831c71b0d3 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -5240,16 +5240,18 @@ public class WifiManager { /** * 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 should use {@link WifiManager#getScanResults()} requires + * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} to get the scan results. * Caller can remove a previously registered listener using * {@link WifiManager#removeScanResultsListener(ScanResultsListener)} + * Same caller can add multiple listeners. *

    * Applications should have the * {@link android.Manifest.permission#ACCESS_WIFI_STATE} permission. Callers * without the permission will trigger a {@link java.lang.SecurityException}. *

    * - * @param executor The executor to execute the listener of the {@code listener} object. + * @param executor The executor to execute the listener of the {@code listener} object. * @param listener listener for Scan Results events */ @@ -5267,7 +5269,7 @@ public class WifiManager { iWifiManager.registerScanResultsListener( new Binder(), new ScanResultsListenerProxy(executor, listener), - mContext.getOpPackageName().hashCode()); + listener.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -5289,7 +5291,7 @@ public class WifiManager { if (iWifiManager == null) { throw new RemoteException("Wifi service is not running"); } - iWifiManager.unregisterScanResultsListener(mContext.getOpPackageName().hashCode()); + iWifiManager.unregisterScanResultsListener(listener.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } -- cgit v1.2.3 From b746c431e7e3d144b7a675fe8584e3d7bdc32afd Mon Sep 17 00:00:00 2001 From: Ahmed ElArabawy Date: Thu, 17 Oct 2019 20:21:23 -0700 Subject: Wifi: Support of HE Operation handling for Wifi-6 This Commit adds support for handling of HE Operation Information element as part of the support for 11ax Bug: 139354972 Test: atest com.android.wifi.server Change-Id: I5e8319c4065e57eef1b89f21be2725b6bab3ad4d --- wifi/java/android/net/wifi/ScanResult.java | 10 ++++++++++ wifi/tests/src/android/net/wifi/ScanResultTest.java | 21 +++++++++++++++++++++ 2 files changed, 31 insertions(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java index c0c0361dd92f..ac86778f068f 100644 --- a/wifi/java/android/net/wifi/ScanResult.java +++ b/wifi/java/android/net/wifi/ScanResult.java @@ -465,9 +465,16 @@ public class ScanResult implements Parcelable { public static final int EID_VHT_OPERATION = 192; @UnsupportedAppUsage public static final int EID_VSA = 221; + public static final int EID_EXTENSION_PRESENT = 255; + + /** + * Extension IDs + */ + public static final int EID_EXT_HE_OPERATION = 36; @UnsupportedAppUsage public int id; + public int idExt; @UnsupportedAppUsage public byte[] bytes; @@ -476,6 +483,7 @@ public class ScanResult implements Parcelable { public InformationElement(InformationElement rhs) { this.id = rhs.id; + this.idExt = rhs.idExt; this.bytes = rhs.bytes.clone(); } } @@ -717,6 +725,7 @@ public class ScanResult implements Parcelable { dest.writeInt(informationElements.length); for (int i = 0; i < informationElements.length; i++) { dest.writeInt(informationElements[i].id); + dest.writeInt(informationElements[i].idExt); dest.writeInt(informationElements[i].bytes.length); dest.writeByteArray(informationElements[i].bytes); } @@ -799,6 +808,7 @@ public class ScanResult implements Parcelable { for (int i = 0; i < n; i++) { sr.informationElements[i] = new InformationElement(); sr.informationElements[i].id = in.readInt(); + sr.informationElements[i].idExt = in.readInt(); int len = in.readInt(); sr.informationElements[i].bytes = new byte[len]; in.readByteArray(sr.informationElements[i].bytes); diff --git a/wifi/tests/src/android/net/wifi/ScanResultTest.java b/wifi/tests/src/android/net/wifi/ScanResultTest.java index 54ec32502878..4973c4cd37fd 100644 --- a/wifi/tests/src/android/net/wifi/ScanResultTest.java +++ b/wifi/tests/src/android/net/wifi/ScanResultTest.java @@ -21,6 +21,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.mockito.Mockito.validateMockitoUsage; +import android.net.wifi.ScanResult.InformationElement; import android.os.Parcel; import androidx.test.filters.SmallTest; @@ -123,6 +124,25 @@ public class ScanResultTest { assertScanResultEquals(scanResult, copyScanResult); } + /** + * Verify parcel read/write for ScanResult with Information Element + */ + @Test + public void verifyScanResultParcelWithInformationElement() throws Exception { + ScanResult writeScanResult = createScanResult(); + writeScanResult.informationElements = new ScanResult.InformationElement[2]; + writeScanResult.informationElements[0] = new ScanResult.InformationElement(); + writeScanResult.informationElements[0].id = InformationElement.EID_HT_OPERATION; + writeScanResult.informationElements[0].idExt = 0; + writeScanResult.informationElements[0].bytes = new byte[]{0x11, 0x22, 0x33}; + writeScanResult.informationElements[1] = new ScanResult.InformationElement(); + writeScanResult.informationElements[1].id = InformationElement.EID_EXTENSION_PRESENT; + writeScanResult.informationElements[1].idExt = InformationElement.EID_EXT_HE_OPERATION; + writeScanResult.informationElements[1].bytes = new byte[]{0x44, 0x55, 0x66}; + ScanResult readScanResult = new ScanResult(writeScanResult); + assertScanResultEquals(writeScanResult, readScanResult); + } + /** * Verify toString for ScanResult. */ @@ -188,5 +208,6 @@ public class ScanResultTest { assertEquals(expected.frequency, actual.frequency); assertEquals(expected.timestamp, actual.timestamp); assertArrayEquals(expected.radioChainInfos, actual.radioChainInfos); + assertArrayEquals(expected.informationElements, actual.informationElements); } } -- cgit v1.2.3 From 1e13ad6574604835d192e8fb1510f8105347ac62 Mon Sep 17 00:00:00 2001 From: Ahmed ElArabawy Date: Fri, 1 Nov 2019 17:49:20 -0700 Subject: Wifi: Change "Technology" to "Standard" in API This commit is to change the naming from Wifi Technology to Wifi Standard. This is to comply with the API council review. Bug: 143551314 Test: atest com.android.wifi.server Change-Id: I0584f9b791dd14119af199cb14d4caf4ffbf54ab --- wifi/java/android/net/wifi/WifiInfo.java | 52 +++++++++++------------ wifi/tests/src/android/net/wifi/WifiInfoTest.java | 6 +-- 2 files changed, 29 insertions(+), 29 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java index 62ba95dc806b..9de39edff38c 100644 --- a/wifi/java/android/net/wifi/WifiInfo.java +++ b/wifi/java/android/net/wifi/WifiInfo.java @@ -99,45 +99,45 @@ public class WifiInfo implements Parcelable { private int mRssi; /** - * Wi-Fi unknown technology + * Wi-Fi unknown standard */ - public static final int WIFI_TECHNOLOGY_UNKNOWN = 0; + public static final int WIFI_STANDARD_UNKNOWN = 0; /** * Wi-Fi 802.11a/b/g */ - public static final int WIFI_TECHNOLOGY_LEGACY = 1; + public static final int WIFI_STANDARD_LEGACY = 1; /** * Wi-Fi 802.11n */ - public static final int WIFI_TECHNOLOGY_11N = 4; + public static final int WIFI_STANDARD_11N = 4; /** * Wi-Fi 802.11ac */ - public static final int WIFI_TECHNOLOGY_11AC = 5; + public static final int WIFI_STANDARD_11AC = 5; /** * Wi-Fi 802.11ax */ - public static final int WIFI_TECHNOLOGY_11AX = 6; + public static final int WIFI_STANDARD_11AX = 6; /** @hide */ - @IntDef(prefix = { "WIFI_TECHNOLOGY_" }, value = { - WIFI_TECHNOLOGY_UNKNOWN, - WIFI_TECHNOLOGY_LEGACY, - WIFI_TECHNOLOGY_11N, - WIFI_TECHNOLOGY_11AC, - WIFI_TECHNOLOGY_11AX + @IntDef(prefix = { "WIFI_STANDARD_" }, value = { + WIFI_STANDARD_UNKNOWN, + WIFI_STANDARD_LEGACY, + WIFI_STANDARD_11N, + WIFI_STANDARD_11AC, + WIFI_STANDARD_11AX }) @Retention(RetentionPolicy.SOURCE) - public @interface WifiTechnology{} + public @interface WifiStandard{} /** - * Wi-Fi technology for the connection + * Wi-Fi standard for the connection */ - private @WifiTechnology int mWifiTechnology; + private @WifiStandard int mWifiStandard; /** * The unit in which links speeds are expressed. @@ -330,7 +330,7 @@ public class WifiInfo implements Parcelable { txSuccessRate = source.txSuccessRate; rxSuccessRate = source.rxSuccessRate; score = source.score; - mWifiTechnology = source.mWifiTechnology; + mWifiStandard = source.mWifiStandard; } } @@ -419,19 +419,19 @@ public class WifiInfo implements Parcelable { } /** - * Sets the Wi-Fi technology + * Sets the Wi-Fi standard * @hide */ - public void setWifiTechnology(@WifiTechnology int wifiTechnology) { - mWifiTechnology = wifiTechnology; + public void setWifiStandard(@WifiStandard int wifiStandard) { + mWifiStandard = wifiStandard; } /** - * Get connection Wi-Fi technology - * @return the connection Wi-Fi technology + * Get connection Wi-Fi standard + * @return the connection Wi-Fi standard */ - public @WifiTechnology int getWifiTechnology() { - return mWifiTechnology; + public @WifiStandard int getWifiStandard() { + return mWifiStandard; } /** @@ -740,7 +740,7 @@ public class WifiInfo implements Parcelable { .append(", MAC: ").append(mMacAddress == null ? none : mMacAddress) .append(", Supplicant state: ") .append(mSupplicantState == null ? none : mSupplicantState) - .append(", Wi-Fi technology: ").append(mWifiTechnology) + .append(", Wi-Fi standard: ").append(mWifiStandard) .append(", RSSI: ").append(mRssi) .append(", Link speed: ").append(mLinkSpeed).append(LINK_SPEED_UNITS) .append(", Tx Link speed: ").append(mTxLinkSpeed).append(LINK_SPEED_UNITS) @@ -796,7 +796,7 @@ public class WifiInfo implements Parcelable { dest.writeString(mNetworkSuggestionOrSpecifierPackageName); dest.writeString(mFqdn); dest.writeString(mProviderFriendlyName); - dest.writeInt(mWifiTechnology); + dest.writeInt(mWifiStandard); } /** Implement the Parcelable interface {@hide} */ @@ -838,7 +838,7 @@ public class WifiInfo implements Parcelable { info.mNetworkSuggestionOrSpecifierPackageName = in.readString(); info.mFqdn = in.readString(); info.mProviderFriendlyName = in.readString(); - info.mWifiTechnology = in.readInt(); + info.mWifiStandard = in.readInt(); return info; } diff --git a/wifi/tests/src/android/net/wifi/WifiInfoTest.java b/wifi/tests/src/android/net/wifi/WifiInfoTest.java index ea08ea8e8333..b98cdc3b4121 100644 --- a/wifi/tests/src/android/net/wifi/WifiInfoTest.java +++ b/wifi/tests/src/android/net/wifi/WifiInfoTest.java @@ -38,7 +38,7 @@ public class WifiInfoTest { private static final String TEST_PACKAGE_NAME = "com.test.example"; private static final String TEST_FQDN = "test.com"; private static final String TEST_PROVIDER_NAME = "test"; - private static final int TEST_WIFI_TECHNOLOGY = WifiInfo.WIFI_TECHNOLOGY_11AC; + private static final int TEST_WIFI_STANDARD = WifiInfo.WIFI_STANDARD_11AC; /** * Verify parcel write/read with WifiInfo. @@ -55,7 +55,7 @@ public class WifiInfoTest { writeWifiInfo.setFQDN(TEST_FQDN); writeWifiInfo.setProviderFriendlyName(TEST_PROVIDER_NAME); writeWifiInfo.setNetworkSuggestionOrSpecifierPackageName(TEST_PACKAGE_NAME); - writeWifiInfo.setWifiTechnology(TEST_WIFI_TECHNOLOGY); + writeWifiInfo.setWifiStandard(TEST_WIFI_STANDARD); Parcel parcel = Parcel.obtain(); writeWifiInfo.writeToParcel(parcel, 0); @@ -74,6 +74,6 @@ public class WifiInfoTest { assertEquals(TEST_PACKAGE_NAME, readWifiInfo.getNetworkSuggestionOrSpecifierPackageName()); assertEquals(TEST_FQDN, readWifiInfo.getPasspointFqdn()); assertEquals(TEST_PROVIDER_NAME, readWifiInfo.getPasspointProviderFriendlyName()); - assertEquals(TEST_WIFI_TECHNOLOGY, readWifiInfo.getWifiTechnology()); + assertEquals(TEST_WIFI_STANDARD, readWifiInfo.getWifiStandard()); } } -- cgit v1.2.3 From dbe3883155c12fdc893fb5ddc1266b2654129fe0 Mon Sep 17 00:00:00 2001 From: Ahmed ElArabawy Date: Wed, 28 Aug 2019 17:47:28 -0700 Subject: Wifi: Add AP wifi technology to ScanResult This CL adds to ScanResult structure information about the Wifi technology. Bug: 143382822 Test: atest com.android.wifi.server Change-Id: Ibe1d30e2efc4693be22148443b26446b90d89179 --- wifi/java/android/net/wifi/ScanResult.java | 96 ++++++++++++++++++++-- wifi/java/android/net/wifi/WifiInfo.java | 45 +--------- .../tests/src/android/net/wifi/ScanResultTest.java | 34 +++++--- wifi/tests/src/android/net/wifi/WifiInfoTest.java | 2 +- 4 files changed, 116 insertions(+), 61 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java index ac86778f068f..aa895a61df9b 100644 --- a/wifi/java/android/net/wifi/ScanResult.java +++ b/wifi/java/android/net/wifi/ScanResult.java @@ -16,11 +16,15 @@ package android.net.wifi; +import android.annotation.IntDef; +import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -223,11 +227,86 @@ public class ScanResult implements Parcelable { */ public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4; - /** - * AP Channel bandwidth; one of {@link #CHANNEL_WIDTH_20MHZ}, {@link #CHANNEL_WIDTH_40MHZ}, - * {@link #CHANNEL_WIDTH_80MHZ}, {@link #CHANNEL_WIDTH_160MHZ} - * or {@link #CHANNEL_WIDTH_80MHZ_PLUS_MHZ}. - */ + /** + * Wi-Fi unknown standard + */ + public static final int WIFI_STANDARD_UNKNOWN = 0; + + /** + * Wi-Fi 802.11a/b/g + */ + public static final int WIFI_STANDARD_LEGACY = 1; + + /** + * Wi-Fi 802.11n + */ + public static final int WIFI_STANDARD_11N = 4; + + /** + * Wi-Fi 802.11ac + */ + public static final int WIFI_STANDARD_11AC = 5; + + /** + * Wi-Fi 802.11ax + */ + public static final int WIFI_STANDARD_11AX = 6; + + /** @hide */ + @IntDef(prefix = { "WIFI_STANDARD_" }, value = { + WIFI_STANDARD_UNKNOWN, + WIFI_STANDARD_LEGACY, + WIFI_STANDARD_11N, + WIFI_STANDARD_11AC, + WIFI_STANDARD_11AX + }) + @Retention(RetentionPolicy.SOURCE) + public @interface WifiStandard{} + + /** + * AP wifi standard. + */ + private @WifiStandard int mWifiStandard; + + /** + * return the AP wifi standard. + */ + public @WifiStandard int getWifiStandard() { + return mWifiStandard; + } + + /** + * sets the AP wifi standard. + * @hide + */ + public void setWifiStandard(@WifiStandard int standard) { + mWifiStandard = standard; + } + + /** + * Convert Wi-Fi standard to string + */ + private static @Nullable String wifiStandardToString(@WifiStandard int standard) { + switch(standard) { + case WIFI_STANDARD_LEGACY: + return "legacy"; + case WIFI_STANDARD_11N: + return "11n"; + case WIFI_STANDARD_11AC: + return "11ac"; + case WIFI_STANDARD_11AX: + return "11ax"; + case WIFI_STANDARD_UNKNOWN: + return "unknown"; + } + return null; + } + + /** + * AP Channel bandwidth; one of {@link #CHANNEL_WIDTH_20MHZ}, {@link #CHANNEL_WIDTH_40MHZ}, + * {@link #CHANNEL_WIDTH_80MHZ}, {@link #CHANNEL_WIDTH_160MHZ} + * or {@link #CHANNEL_WIDTH_80MHZ_PLUS_MHZ}. + */ public int channelWidth; /** @@ -549,6 +628,7 @@ public class ScanResult implements Parcelable { this.carrierApEapType = UNSPECIFIED; this.carrierName = null; this.radioChainInfos = null; + this.mWifiStandard = WIFI_STANDARD_UNKNOWN; } /** {@hide} */ @@ -571,6 +651,7 @@ public class ScanResult implements Parcelable { this.carrierApEapType = UNSPECIFIED; this.carrierName = null; this.radioChainInfos = null; + this.mWifiStandard = WIFI_STANDARD_UNKNOWN; } /** {@hide} */ @@ -600,6 +681,7 @@ public class ScanResult implements Parcelable { this.carrierApEapType = UNSPECIFIED; this.carrierName = null; this.radioChainInfos = null; + this.mWifiStandard = WIFI_STANDARD_UNKNOWN; } /** {@hide} */ @@ -641,6 +723,7 @@ public class ScanResult implements Parcelable { carrierApEapType = source.carrierApEapType; carrierName = source.carrierName; radioChainInfos = source.radioChainInfos; + this.mWifiStandard = source.mWifiStandard; } } @@ -679,6 +762,7 @@ public class ScanResult implements Parcelable { sb.append(", ChannelBandwidth: ").append(channelWidth); sb.append(", centerFreq0: ").append(centerFreq0); sb.append(", centerFreq1: ").append(centerFreq1); + sb.append(", standard: ").append(wifiStandardToString(mWifiStandard)); sb.append(", 80211mcResponder: "); sb.append(((flags & FLAG_80211mc_RESPONDER) != 0) ? "is supported" : "is not supported"); sb.append(", Carrier AP: ").append(isCarrierAp ? "yes" : "no"); @@ -714,6 +798,7 @@ public class ScanResult implements Parcelable { dest.writeInt(channelWidth); dest.writeInt(centerFreq0); dest.writeInt(centerFreq1); + dest.writeInt(mWifiStandard); dest.writeLong(seen); dest.writeInt(untrusted ? 1 : 0); dest.writeInt(numUsage); @@ -796,6 +881,7 @@ public class ScanResult implements Parcelable { fixed with flags below */ ); + sr.mWifiStandard = in.readInt(); sr.seen = in.readLong(); sr.untrusted = in.readInt() != 0; sr.numUsage = in.readInt(); diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java index 9de39edff38c..86e51227575b 100644 --- a/wifi/java/android/net/wifi/WifiInfo.java +++ b/wifi/java/android/net/wifi/WifiInfo.java @@ -16,7 +16,6 @@ package android.net.wifi; -import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.Nullable; import android.annotation.SystemApi; @@ -28,8 +27,6 @@ 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; @@ -98,46 +95,10 @@ public class WifiInfo implements Parcelable { */ private int mRssi; - /** - * Wi-Fi unknown standard - */ - public static final int WIFI_STANDARD_UNKNOWN = 0; - - /** - * Wi-Fi 802.11a/b/g - */ - public static final int WIFI_STANDARD_LEGACY = 1; - - /** - * Wi-Fi 802.11n - */ - public static final int WIFI_STANDARD_11N = 4; - - /** - * Wi-Fi 802.11ac - */ - public static final int WIFI_STANDARD_11AC = 5; - - /** - * Wi-Fi 802.11ax - */ - public static final int WIFI_STANDARD_11AX = 6; - - /** @hide */ - @IntDef(prefix = { "WIFI_STANDARD_" }, value = { - WIFI_STANDARD_UNKNOWN, - WIFI_STANDARD_LEGACY, - WIFI_STANDARD_11N, - WIFI_STANDARD_11AC, - WIFI_STANDARD_11AX - }) - @Retention(RetentionPolicy.SOURCE) - public @interface WifiStandard{} - /** * Wi-Fi standard for the connection */ - private @WifiStandard int mWifiStandard; + private @ScanResult.WifiStandard int mWifiStandard; /** * The unit in which links speeds are expressed. @@ -422,7 +383,7 @@ public class WifiInfo implements Parcelable { * Sets the Wi-Fi standard * @hide */ - public void setWifiStandard(@WifiStandard int wifiStandard) { + public void setWifiStandard(@ScanResult.WifiStandard int wifiStandard) { mWifiStandard = wifiStandard; } @@ -430,7 +391,7 @@ public class WifiInfo implements Parcelable { * Get connection Wi-Fi standard * @return the connection Wi-Fi standard */ - public @WifiStandard int getWifiStandard() { + public @ScanResult.WifiStandard int getWifiStandard() { return mWifiStandard; } diff --git a/wifi/tests/src/android/net/wifi/ScanResultTest.java b/wifi/tests/src/android/net/wifi/ScanResultTest.java index 4973c4cd37fd..b5c74d1d01b1 100644 --- a/wifi/tests/src/android/net/wifi/ScanResultTest.java +++ b/wifi/tests/src/android/net/wifi/ScanResultTest.java @@ -42,6 +42,8 @@ public class ScanResultTest { public static final int TEST_LEVEL = -56; public static final int TEST_FREQUENCY = 2412; public static final long TEST_TSF = 04660l; + public static final @ScanResult.WifiStandard int TEST_WIFI_STANDARD = + ScanResult.WIFI_STANDARD_11AC; /** * Setup before tests. @@ -149,12 +151,14 @@ public class ScanResultTest { @Test public void verifyScanResultToStringWithoutRadioChainInfo() throws Exception { ScanResult scanResult = createScanResult(); - assertEquals("SSID: \"test_ssid\", BSSID: 04:ac:fe:45:34:10, capabilities: CCMP, " + - "level: -56, frequency: 2412, timestamp: 2480, distance: 0(cm), distanceSd: 0(cm), " + - "passpoint: no, ChannelBandwidth: 0, centerFreq0: 0, centerFreq1: 0, " + - "80211mcResponder: is not supported, Carrier AP: no, " + - "Carrier AP EAP Type: 0, Carrier name: null, " + - "Radio Chain Infos: null", scanResult.toString()); + assertEquals("SSID: \"test_ssid\", BSSID: 04:ac:fe:45:34:10, capabilities: CCMP, " + + "level: -56, frequency: 2412, timestamp: 2480, " + + "distance: 0(cm), distanceSd: 0(cm), " + + "passpoint: no, ChannelBandwidth: 0, centerFreq0: 0, centerFreq1: 0, " + + "standard: 11ac, " + + "80211mcResponder: is not supported, Carrier AP: no, " + + "Carrier AP EAP Type: 0, Carrier name: null, " + + "Radio Chain Infos: null", scanResult.toString()); } /** @@ -170,13 +174,15 @@ public class ScanResultTest { scanResult.radioChainInfos[1] = new ScanResult.RadioChainInfo(); scanResult.radioChainInfos[1].id = 1; scanResult.radioChainInfos[1].level = -54; - assertEquals("SSID: \"test_ssid\", BSSID: 04:ac:fe:45:34:10, capabilities: CCMP, " + - "level: -56, frequency: 2412, timestamp: 2480, distance: 0(cm), distanceSd: 0(cm), " + - "passpoint: no, ChannelBandwidth: 0, centerFreq0: 0, centerFreq1: 0, " + - "80211mcResponder: is not supported, Carrier AP: no, " + - "Carrier AP EAP Type: 0, Carrier name: null, " + - "Radio Chain Infos: [RadioChainInfo: id=0, level=-45, " + - "RadioChainInfo: id=1, level=-54]", scanResult.toString()); + assertEquals("SSID: \"test_ssid\", BSSID: 04:ac:fe:45:34:10, capabilities: CCMP, " + + "level: -56, frequency: 2412, timestamp: 2480, distance: 0(cm), " + + "distanceSd: 0(cm), " + + "passpoint: no, ChannelBandwidth: 0, centerFreq0: 0, centerFreq1: 0, " + + "standard: 11ac, " + + "80211mcResponder: is not supported, Carrier AP: no, " + + "Carrier AP EAP Type: 0, Carrier name: null, " + + "Radio Chain Infos: [RadioChainInfo: id=0, level=-45, " + + "RadioChainInfo: id=1, level=-54]", scanResult.toString()); } /** @@ -197,6 +203,7 @@ public class ScanResultTest { result.level = TEST_LEVEL; result.frequency = TEST_FREQUENCY; result.timestamp = TEST_TSF; + result.setWifiStandard(TEST_WIFI_STANDARD); return result; } @@ -207,6 +214,7 @@ public class ScanResultTest { assertEquals(expected.level, actual.level); assertEquals(expected.frequency, actual.frequency); assertEquals(expected.timestamp, actual.timestamp); + assertEquals(expected.getWifiStandard(), actual.getWifiStandard()); assertArrayEquals(expected.radioChainInfos, actual.radioChainInfos); assertArrayEquals(expected.informationElements, actual.informationElements); } diff --git a/wifi/tests/src/android/net/wifi/WifiInfoTest.java b/wifi/tests/src/android/net/wifi/WifiInfoTest.java index b98cdc3b4121..22a5faaac112 100644 --- a/wifi/tests/src/android/net/wifi/WifiInfoTest.java +++ b/wifi/tests/src/android/net/wifi/WifiInfoTest.java @@ -38,7 +38,7 @@ public class WifiInfoTest { private static final String TEST_PACKAGE_NAME = "com.test.example"; private static final String TEST_FQDN = "test.com"; private static final String TEST_PROVIDER_NAME = "test"; - private static final int TEST_WIFI_STANDARD = WifiInfo.WIFI_STANDARD_11AC; + private static final int TEST_WIFI_STANDARD = ScanResult.WIFI_STANDARD_11AC; /** * Verify parcel write/read with WifiInfo. -- cgit v1.2.3 From b0e56cb5923ea0259f3c81b63ee54e58df079a1b Mon Sep 17 00:00:00 2001 From: Ahmed ElArabawy Date: Wed, 28 Aug 2019 17:47:28 -0700 Subject: Wifi: Add 802.11ax support to RTT This CL makes modidfication to support Wifi 802.11ax to RTT procedures. Bug: 139354972 Test: atest com.android.wifi.server Change-Id: I3d07509b27c4be83ea7c59ee4d1f0e404db5a04d --- wifi/java/android/net/wifi/ScanResult.java | 1 + wifi/java/android/net/wifi/rtt/ResponderConfig.java | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java index aa895a61df9b..ed1a2f9f16ca 100644 --- a/wifi/java/android/net/wifi/ScanResult.java +++ b/wifi/java/android/net/wifi/ScanResult.java @@ -549,6 +549,7 @@ public class ScanResult implements Parcelable { /** * Extension IDs */ + public static final int EID_EXT_HE_CAPABILITIES = 35; public static final int EID_EXT_HE_OPERATION = 36; @UnsupportedAppUsage diff --git a/wifi/java/android/net/wifi/rtt/ResponderConfig.java b/wifi/java/android/net/wifi/rtt/ResponderConfig.java index 64dfc3499aaf..be4eeccd0c31 100644 --- a/wifi/java/android/net/wifi/rtt/ResponderConfig.java +++ b/wifi/java/android/net/wifi/rtt/ResponderConfig.java @@ -16,6 +16,8 @@ package android.net.wifi.rtt; +import static android.net.wifi.ScanResult.InformationElement.EID_EXTENSION_PRESENT; +import static android.net.wifi.ScanResult.InformationElement.EID_EXT_HE_CAPABILITIES; import static android.net.wifi.ScanResult.InformationElement.EID_HT_CAPABILITIES; import static android.net.wifi.ScanResult.InformationElement.EID_VHT_CAPABILITIES; @@ -106,7 +108,7 @@ public final class ResponderConfig implements Parcelable { public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4; /** @hide */ - @IntDef({PREAMBLE_LEGACY, PREAMBLE_HT, PREAMBLE_VHT}) + @IntDef({PREAMBLE_LEGACY, PREAMBLE_HT, PREAMBLE_VHT, PREAMBLE_HE}) @Retention(RetentionPolicy.SOURCE) public @interface PreambleType { } @@ -126,6 +128,10 @@ public final class ResponderConfig implements Parcelable { */ public static final int PREAMBLE_VHT = 2; + /** + * Preamble type: HE. + */ + public static final int PREAMBLE_HE = 3; /** * The MAC address of the Responder. Will be null if a Wi-Fi Aware peer identifier (the @@ -307,14 +313,21 @@ public final class ResponderConfig implements Parcelable { if (scanResult.informationElements != null && scanResult.informationElements.length != 0) { boolean htCapabilitiesPresent = false; boolean vhtCapabilitiesPresent = false; + boolean heCapabilitiesPresent = false; + for (ScanResult.InformationElement ie : scanResult.informationElements) { if (ie.id == EID_HT_CAPABILITIES) { htCapabilitiesPresent = true; } else if (ie.id == EID_VHT_CAPABILITIES) { vhtCapabilitiesPresent = true; + } else if (ie.id == EID_EXTENSION_PRESENT && ie.idExt == EID_EXT_HE_CAPABILITIES) { + heCapabilitiesPresent = true; } } - if (vhtCapabilitiesPresent) { + + if (heCapabilitiesPresent) { + preamble = PREAMBLE_HE; + } else if (vhtCapabilitiesPresent) { preamble = PREAMBLE_VHT; } else if (htCapabilitiesPresent) { preamble = PREAMBLE_HT; -- cgit v1.2.3 From 3fd4b647f78f9ef79dcc9143b98e7a7ce1d428b3 Mon Sep 17 00:00:00 2001 From: lesl Date: Wed, 23 Oct 2019 10:47:34 +0800 Subject: wifi: Add SoftApInfo Callback support Bug: 142752869 Test: unit test, atest frameworks/base/wifi/tests/ Test: Manual test - checked by log. Change-Id: I9fe7a18654721f98026680711685c06add3da264 --- wifi/java/android/net/wifi/ISoftApCallback.aidl | 8 + wifi/java/android/net/wifi/SoftApInfo.aidl | 20 ++ wifi/java/android/net/wifi/SoftApInfo.java | 211 +++++++++++++++++++++ wifi/java/android/net/wifi/WifiManager.java | 19 ++ .../tests/src/android/net/wifi/SoftApInfoTest.java | 71 +++++++ .../src/android/net/wifi/WifiManagerTest.java | 28 ++- 6 files changed, 356 insertions(+), 1 deletion(-) create mode 100644 wifi/java/android/net/wifi/SoftApInfo.aidl create mode 100644 wifi/java/android/net/wifi/SoftApInfo.java create mode 100644 wifi/tests/src/android/net/wifi/SoftApInfoTest.java (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/ISoftApCallback.aidl b/wifi/java/android/net/wifi/ISoftApCallback.aidl index 8a252dd1e447..452a655edc7b 100644 --- a/wifi/java/android/net/wifi/ISoftApCallback.aidl +++ b/wifi/java/android/net/wifi/ISoftApCallback.aidl @@ -15,6 +15,7 @@ */ package android.net.wifi; +import android.net.wifi.SoftApInfo; import android.net.wifi.WifiClient; @@ -43,4 +44,11 @@ oneway interface ISoftApCallback * @param clients the currently connected clients */ void onConnectedClientsChanged(in List clients); + + /** + * Service to manager callback providing information of softap. + * + * @param softApInfo is the softap information. {@link SoftApInfo} + */ + void onInfoChanged(in SoftApInfo softApInfo); } diff --git a/wifi/java/android/net/wifi/SoftApInfo.aidl b/wifi/java/android/net/wifi/SoftApInfo.aidl new file mode 100644 index 000000000000..d4551cfac044 --- /dev/null +++ b/wifi/java/android/net/wifi/SoftApInfo.aidl @@ -0,0 +1,20 @@ +/** + * 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; + +parcelable SoftApInfo; + diff --git a/wifi/java/android/net/wifi/SoftApInfo.java b/wifi/java/android/net/wifi/SoftApInfo.java new file mode 100644 index 000000000000..375a9774f570 --- /dev/null +++ b/wifi/java/android/net/wifi/SoftApInfo.java @@ -0,0 +1,211 @@ +/* + * 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.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.Objects; + +/** + * A class representing information about SoftAp. + * {@see WifiManager} + * + * @hide + */ +@SystemApi +public final class SoftApInfo implements Parcelable { + + /** + * AP Channel bandwidth is invalid. + * + * @see #getBandwidth() + */ + public static final int CHANNEL_WIDTH_INVALID = 0; + + /** + * AP Channel bandwidth is 20 MHZ but no HT. + * + * @see #getBandwidth() + */ + public static final int CHANNEL_WIDTH_20MHZ_NOHT = 1; + + /** + * AP Channel bandwidth is 20 MHZ. + * + * @see #getBandwidth() + */ + public static final int CHANNEL_WIDTH_20MHZ = 2; + + /** + * AP Channel bandwidth is 40 MHZ. + * + * @see #getBandwidth() + */ + public static final int CHANNEL_WIDTH_40MHZ = 3; + + /** + * AP Channel bandwidth is 80 MHZ. + * + * @see #getBandwidth() + */ + public static final int CHANNEL_WIDTH_80MHZ = 4; + + /** + * AP Channel bandwidth is 160 MHZ, but 80MHZ + 80MHZ. + * + * @see #getBandwidth() + */ + public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 5; + + /** + * AP Channel bandwidth is 160 MHZ. + * + * @see #getBandwidth() + */ + public static final int CHANNEL_WIDTH_160MHZ = 6; + + /** + * @hide + */ + @IntDef(prefix = { "CHANNEL_WIDTH_" }, value = { + CHANNEL_WIDTH_INVALID, + CHANNEL_WIDTH_20MHZ_NOHT, + CHANNEL_WIDTH_20MHZ, + CHANNEL_WIDTH_40MHZ, + CHANNEL_WIDTH_80MHZ, + CHANNEL_WIDTH_80MHZ_PLUS_MHZ, + CHANNEL_WIDTH_160MHZ, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface Bandwidth {} + + + /** The frequency which AP resides on. */ + private int mFrequency = 0; + + @Bandwidth + private int mBandwidth = CHANNEL_WIDTH_INVALID; + + /** + * Get the frequency which AP resides on. + */ + public int getFrequency() { + return mFrequency; + } + + /** + * Set the frequency which AP resides on. + * @hide + */ + public void setFrequency(int freq) { + mFrequency = freq; + } + + /** + * Get AP Channel bandwidth. + * + * @return One of {@link #CHANNEL_WIDTH_20MHZ}, {@link #CHANNEL_WIDTH_40MHZ}, + * {@link #CHANNEL_WIDTH_80MHZ}, {@link #CHANNEL_WIDTH_160MHZ}, + * {@link #CHANNEL_WIDTH_80MHZ_PLUS_MHZ} or {@link #CHANNEL_WIDTH_UNKNOWN}. + */ + @Bandwidth + public int getBandwidth() { + return mBandwidth; + } + + /** + * Set AP Channel bandwidth. + * @hide + */ + public void setBandwidth(@Bandwidth int bandwidth) { + mBandwidth = bandwidth; + } + + /** + * @hide + */ + public SoftApInfo(@Nullable SoftApInfo source) { + if (source != null) { + mFrequency = source.mFrequency; + mBandwidth = source.mBandwidth; + } + } + + /** + * @hide + */ + public SoftApInfo() { + } + + @Override + /** Implement the Parcelable interface. */ + public int describeContents() { + return 0; + } + + @Override + /** Implement the Parcelable interface */ + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(mFrequency); + dest.writeInt(mBandwidth); + } + + @NonNull + /** Implement the Parcelable interface */ + public static final Creator CREATOR = new Creator() { + public SoftApInfo createFromParcel(Parcel in) { + SoftApInfo info = new SoftApInfo(); + info.mFrequency = in.readInt(); + info.mBandwidth = in.readInt(); + return info; + } + + public SoftApInfo[] newArray(int size) { + return new SoftApInfo[size]; + } + }; + + @NonNull + @Override + public String toString() { + return "SoftApInfo{" + + "bandwidth= " + mBandwidth + + ",frequency= " + mFrequency + + '}'; + } + + @Override + public boolean equals(@NonNull Object o) { + if (this == o) return true; + if (!(o instanceof SoftApInfo)) return false; + SoftApInfo softApInfo = (SoftApInfo) o; + return mFrequency == softApInfo.mFrequency + && mBandwidth == softApInfo.mBandwidth; + } + + @Override + public int hashCode() { + return Objects.hash(mFrequency, mBandwidth); + } +} diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 380ebf104a14..c41d33d5f6e2 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -3315,6 +3315,15 @@ public class WifiManager { * @param clients the currently connected clients */ void onConnectedClientsChanged(@NonNull List clients); + + /** + * Called when information of softap changes. + * + * @param softApInfo is the softap information. {@link SoftApInfo} + */ + default void onInfoChanged(@NonNull SoftApInfo softApInfo) { + // Do nothing: can be updated to add SoftApInfo details (e.g. channel) to the UI. + } } /** @@ -3354,6 +3363,16 @@ public class WifiManager { mCallback.onConnectedClientsChanged(clients); }); } + + @Override + public void onInfoChanged(SoftApInfo softApInfo) { + if (mVerboseLoggingEnabled) { + Log.v(TAG, "SoftApCallbackProxy: onInfoChange: softApInfo=" + softApInfo); + } + mHandler.post(() -> { + mCallback.onInfoChanged(softApInfo); + }); + } } /** diff --git a/wifi/tests/src/android/net/wifi/SoftApInfoTest.java b/wifi/tests/src/android/net/wifi/SoftApInfoTest.java new file mode 100644 index 000000000000..929f3ab88fd8 --- /dev/null +++ b/wifi/tests/src/android/net/wifi/SoftApInfoTest.java @@ -0,0 +1,71 @@ +/* + * 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.os.Parcel; + +import static org.junit.Assert.assertEquals; + +import androidx.test.filters.SmallTest; + +import org.junit.Test; + +/** + * Unit tests for {@link android.net.wifi.SoftApInfo}. + */ +@SmallTest +public class SoftApInfoTest { + + /** + * Verifies copy constructor. + */ + @Test + public void testCopyOperator() throws Exception { + SoftApInfo info = new SoftApInfo(); + info.setFrequency(2412); + info.setBandwidth(SoftApInfo.CHANNEL_WIDTH_20MHZ); + + SoftApInfo copiedInfo = new SoftApInfo(info); + + assertEquals(info, copiedInfo); + assertEquals(info.hashCode(), copiedInfo.hashCode()); + } + + /** + * Verifies parcel serialization/deserialization. + */ + @Test + public void testParcelOperation() throws Exception { + SoftApInfo info = new SoftApInfo(); + info.setFrequency(2412); + info.setBandwidth(SoftApInfo.CHANNEL_WIDTH_20MHZ); + + Parcel parcelW = Parcel.obtain(); + info.writeToParcel(parcelW, 0); + byte[] bytes = parcelW.marshall(); + parcelW.recycle(); + + Parcel parcelR = Parcel.obtain(); + parcelR.unmarshall(bytes, 0, bytes.length); + parcelR.setDataPosition(0); + SoftApInfo fromParcel = SoftApInfo.CREATOR.createFromParcel(parcelR); + + assertEquals(info, fromParcel); + assertEquals(info.hashCode(), fromParcel.hashCode()); + } + +} diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index d2516a33fead..14e994cf0f08 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -97,6 +97,8 @@ public class WifiManagerTest { private static final String TEST_PACKAGE_NAME = "TestPackage"; private static final String TEST_COUNTRY_CODE = "US"; private static final String[] TEST_MAC_ADDRESSES = {"da:a1:19:0:0:0"}; + private static final int TEST_AP_FREQUENCY = 2412; + private static final int TEST_AP_BANDWIDTH = SoftApInfo.CHANNEL_WIDTH_20MHZ; @Mock Context mContext; @Mock android.net.wifi.IWifiManager mWifiService; @@ -122,7 +124,6 @@ public class WifiManagerTest { mApplicationInfo.targetSdkVersion = Build.VERSION_CODES.Q; when(mContext.getApplicationInfo()).thenReturn(mApplicationInfo); when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME); - mWifiManager = new WifiManager(mContext, mWifiService, mLooper.getLooper()); verify(mWifiService).getVerboseLoggingLevel(); } @@ -776,11 +777,34 @@ public class WifiManagerTest { verify(mSoftApCallback).onConnectedClientsChanged(testClients); } + + /* + * Verify client-provided callback is being called through callback proxy + */ + @Test + public void softApCallbackProxyCallsOnSoftApInfoChanged() throws Exception { + SoftApInfo testSoftApInfo = new SoftApInfo(); + testSoftApInfo.setFrequency(TEST_AP_FREQUENCY); + testSoftApInfo.setBandwidth(TEST_AP_BANDWIDTH); + ArgumentCaptor callbackCaptor = + ArgumentCaptor.forClass(ISoftApCallback.Stub.class); + mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler); + verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(), + anyInt()); + + callbackCaptor.getValue().onInfoChanged(testSoftApInfo); + mLooper.dispatchAll(); + verify(mSoftApCallback).onInfoChanged(testSoftApInfo); + } + /* * Verify client-provided callback is being called through callback proxy on multiple events */ @Test public void softApCallbackProxyCallsOnMultipleUpdates() throws Exception { + SoftApInfo testSoftApInfo = new SoftApInfo(); + testSoftApInfo.setFrequency(TEST_AP_FREQUENCY); + testSoftApInfo.setBandwidth(TEST_AP_BANDWIDTH); ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(ISoftApCallback.Stub.class); mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler); @@ -790,11 +814,13 @@ public class WifiManagerTest { final List testClients = new ArrayList(); callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_ENABLING, 0); callbackCaptor.getValue().onConnectedClientsChanged(testClients); + callbackCaptor.getValue().onInfoChanged(testSoftApInfo); callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL); mLooper.dispatchAll(); verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLING, 0); verify(mSoftApCallback).onConnectedClientsChanged(testClients); + verify(mSoftApCallback).onInfoChanged(testSoftApInfo); verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL); } -- cgit v1.2.3 From d09d44ec4f84ef6b48f784ff316a66dcf548b15b Mon Sep 17 00:00:00 2001 From: David Su Date: Tue, 5 Nov 2019 21:41:48 -0800 Subject: WifiScanner: check nullness of bundle extra In WifiScanner#getAvailableChannels(), check if the extra is null and return an empty list if that is the case to ensure that the API upholds its @NonNull guarantee. Bug: 143985829 Test: compiles Change-Id: I5abc2e6362469f77db0fa386adbe06b445aa799c --- wifi/java/android/net/wifi/WifiScanner.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index 67993e1b72db..0a9932624d18 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -138,7 +138,8 @@ public class WifiScanner { public List getAvailableChannels(@WifiBand int band) { try { Bundle bundle = mService.getAvailableChannels(band, mContext.getOpPackageName()); - return bundle.getIntegerArrayList(GET_AVAILABLE_CHANNELS_EXTRA); + List channels = bundle.getIntegerArrayList(GET_AVAILABLE_CHANNELS_EXTRA); + return channels == null ? new ArrayList<>() : channels; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } -- cgit v1.2.3 From b55ba05c10f938b87613cde648893b12675a8389 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Wed, 30 Oct 2019 09:10:24 -0700 Subject: WifiManager: Add @SystemApi for STA/AP MAC randomization This ensures that we don't use wifi overlays in settings. Bug: 143464763 Test: Verfied MAC randomization setting toggle via Wifi picker. Change-Id: I24ec509be579ec9c1a3d5e18fdc8d5709d83886c --- wifi/java/android/net/wifi/WifiManager.java | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 8108fef5d3ee..b5c3d6f5878f 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -2220,6 +2220,10 @@ public class WifiManager { public static final long WIFI_FEATURE_DPP = 0x80000000L; // DPP (Easy-Connect) /** @hide */ public static final long WIFI_FEATURE_P2P_RAND_MAC = 0x100000000L; // Random P2P MAC + /** @hide */ + public static final long WIFI_FEATURE_CONNECTED_RAND_MAC = 0x200000000L; // Random STA MAC + /** @hide */ + public static final long WIFI_FEATURE_AP_RAND_MAC = 0x400000000L; // Random AP MAC private long getSupportedFeatures() { try { @@ -2344,6 +2348,24 @@ public class WifiManager { return isFeatureSupported(WIFI_FEATURE_LINK_LAYER_STATS); } + /** + * @return true if this device supports connected MAC randomization. + * @hide + */ + @SystemApi + public boolean isConnectedMacRandomizationSupported() { + return isFeatureSupported(WIFI_FEATURE_CONNECTED_RAND_MAC); + } + + /** + * @return true if this device supports connected MAC randomization. + * @hide + */ + @SystemApi + public boolean isApMacRandomizationSupported() { + return isFeatureSupported(WIFI_FEATURE_AP_RAND_MAC); + } + /** * Return the record of {@link WifiActivityEnergyInfo} object that * has the activity and energy info. This can be used to ascertain what -- cgit v1.2.3 From d076cbcd8d80713ea4d46877508e06909a1faef2 Mon Sep 17 00:00:00 2001 From: "Nate(Qiang) Jiang" Date: Mon, 21 Oct 2019 13:38:30 -0700 Subject: [Suggestion API] add network callback API Add new API that allow apps to get connection event. Bug: 142062781 Test: atest android.net.wifi Test: atest com.android.server.wifi Change-Id: I387f620901621feb2b15dff7c696d5d3f9a068b9 --- .../wifi/ISuggestionConnectionStatusListener.aidl | 29 +++++ wifi/java/android/net/wifi/IWifiManager.aidl | 5 + wifi/java/android/net/wifi/WifiManager.java | 133 ++++++++++++++++++++- .../com/android/server/wifi/BaseWifiService.java | 14 +++ .../src/android/net/wifi/WifiManagerTest.java | 69 +++++++++++ 5 files changed, 249 insertions(+), 1 deletion(-) create mode 100644 wifi/java/android/net/wifi/ISuggestionConnectionStatusListener.aidl (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/ISuggestionConnectionStatusListener.aidl b/wifi/java/android/net/wifi/ISuggestionConnectionStatusListener.aidl new file mode 100644 index 000000000000..b49e49ba0cd5 --- /dev/null +++ b/wifi/java/android/net/wifi/ISuggestionConnectionStatusListener.aidl @@ -0,0 +1,29 @@ +/* + * 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.WifiNetworkSuggestion; + +/** + * Interface for suggestion network connection listener. + * + * @hide + */ +oneway interface ISuggestionConnectionStatusListener +{ + void onConnectionStatus(in WifiNetworkSuggestion wifiNetworkSuggestion, int failureReason); +} diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 023df70ef55a..bc73a93f1e56 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -30,6 +30,7 @@ import android.net.wifi.ILocalOnlyHotspotCallback; import android.net.wifi.INetworkRequestMatchCallback; import android.net.wifi.IScanResultsListener; import android.net.wifi.ISoftApCallback; +import android.net.wifi.ISuggestionConnectionStatusListener; import android.net.wifi.ITrafficStateCallback; import android.net.wifi.ITxPacketCountListener; import android.net.wifi.IOnWifiUsabilityStatsListener; @@ -236,4 +237,8 @@ interface IWifiManager void registerScanResultsListener(in IBinder binder, in IScanResultsListener Listener, int listenerIdentifier); void unregisterScanResultsListener(int listenerIdentifier); + + void registerSuggestionConnectionStatusListener(in IBinder binder, in ISuggestionConnectionStatusListener listener, int listenerIdentifier, String packageName); + + void unregisterSuggestionConnectionStatusListener(int listenerIdentifier, String packageName); } diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 8108fef5d3ee..24d099af6f08 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -207,6 +207,33 @@ public class WifiManager { @Retention(RetentionPolicy.SOURCE) public @interface NetworkSuggestionsStatusCode {} + /** + * Reason code if suggested network connection attempt failed with an unknown failure. + */ + public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN = 0; + /** + * Reason code if suggested network connection attempt failed with association failure. + */ + public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION = 1; + /** + * Reason code if suggested network connection attempt failed with an authentication failure. + */ + public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION = 2; + /** + * Reason code if suggested network connection attempt failed with an IP provision failure. + */ + public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING = 3; + + /** @hide */ + @IntDef(prefix = {"STATUS_SUGGESTION_CONNECTION_FAILURE_"}, + value = {STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN, + STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION, + STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION, + STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING + }) + @Retention(RetentionPolicy.SOURCE) + public @interface SuggestionConnectionStatusCode {} + /** * Broadcast intent action indicating whether Wi-Fi scanning is allowed currently * @hide @@ -5229,7 +5256,7 @@ public class WifiManager { } /** - * Base class for scan results listener. Should be implemented by applications and set when + * Interface for scan results listener. Should be implemented by applications and set when * calling {@link WifiManager#addScanResultsListener(Executor, ScanResultsListener)}. */ public interface ScanResultsListener { @@ -5315,4 +5342,108 @@ public class WifiManager { throw e.rethrowFromSystemServer(); } } + + /** + * Interface for suggestion connection status listener. + * Should be implemented by applications and set when calling + * {@link WifiManager#addSuggestionConnectionStatusListener( + * Executor, SuggestionConnectionStatusListener)}. + */ + public interface SuggestionConnectionStatusListener { + + /** + * Called when the framework attempted to connect to a suggestion provided by the + * registering app, but the connection to the suggestion failed. + * @param wifiNetworkSuggestion The suggestion which failed to connect. + * @param failureReason the connection failure reason code. One of + * {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION}, + * {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION}, + * {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING} + * {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN} + */ + void onConnectionStatus( + @NonNull WifiNetworkSuggestion wifiNetworkSuggestion, + @SuggestionConnectionStatusCode int failureReason); + } + + private class SuggestionConnectionStatusListenerProxy extends + ISuggestionConnectionStatusListener.Stub { + private final Executor mExecutor; + private final SuggestionConnectionStatusListener mListener; + + SuggestionConnectionStatusListenerProxy(@NonNull Executor executor, + @NonNull SuggestionConnectionStatusListener listener) { + mExecutor = executor; + mListener = listener; + } + + @Override + public void onConnectionStatus(@NonNull WifiNetworkSuggestion wifiNetworkSuggestion, + int failureReason) { + mExecutor.execute(() -> + mListener.onConnectionStatus(wifiNetworkSuggestion, failureReason)); + } + + } + + /** + * Add a listener for suggestion networks. See {@link SuggestionConnectionStatusListener}. + * Caller will receive the event when suggested network have connection failure. + * Caller can remove a previously registered listener using + * {@link WifiManager#removeSuggestionConnectionStatusListener( + * SuggestionConnectionStatusListener)} + * Same caller can add multiple listeners to monitor the event. + *

    + * Applications should have the + * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and + * {@link android.Manifest.permission#ACCESS_WIFI_STATE} permissions. + * Callers without the permission will trigger a {@link java.lang.SecurityException}. + *

    + * + * @param executor The executor to execute the listener of the {@code listener} object. + * @param listener listener for suggestion network connection failure. + */ + @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE}) + public void addSuggestionConnectionStatusListener(@NonNull @CallbackExecutor Executor executor, + @NonNull SuggestionConnectionStatusListener listener) { + if (listener == null) throw new IllegalArgumentException("Listener cannot be null"); + if (executor == null) throw new IllegalArgumentException("Executor cannot be null"); + Log.v(TAG, "addSuggestionConnectionStatusListener listener=" + listener + + ", executor=" + executor); + try { + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.registerSuggestionConnectionStatusListener(new Binder(), + new SuggestionConnectionStatusListenerProxy(executor, listener), + listener.hashCode(), mContext.getOpPackageName()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + + } + + /** + * Allow callers to remove a previously registered listener. After calling this method, + * applications will no longer receive suggestion connection events through that listener. + * + * @param listener listener to remove. + */ + @RequiresPermission(ACCESS_WIFI_STATE) + public void removeSuggestionConnectionStatusListener( + @NonNull SuggestionConnectionStatusListener listener) { + if (listener == null) throw new IllegalArgumentException("Listener cannot be null"); + Log.v(TAG, "removeSuggestionConnectionStatusListener: listener=" + listener); + try { + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + iWifiManager.unregisterSuggestionConnectionStatusListener(listener.hashCode(), + mContext.getOpPackageName()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } } diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index 4b7d205e7922..671708ff4c9d 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -28,6 +28,7 @@ import android.net.wifi.INetworkRequestMatchCallback; import android.net.wifi.IOnWifiUsabilityStatsListener; import android.net.wifi.IScanResultsListener; import android.net.wifi.ISoftApCallback; +import android.net.wifi.ISuggestionConnectionStatusListener; import android.net.wifi.ITrafficStateCallback; import android.net.wifi.ITxPacketCountListener; import android.net.wifi.IWifiManager; @@ -540,4 +541,17 @@ public class BaseWifiService extends IWifiManager.Stub { public void unregisterScanResultsListener(int listenerIdentifier) { throw new UnsupportedOperationException(); } + + @Override + public void registerSuggestionConnectionStatusListener(IBinder binder, + ISuggestionConnectionStatusListener listener, + int listenerIdentifier, String packageName) { + throw new UnsupportedOperationException(); + } + + @Override + public void unregisterSuggestionConnectionStatusListener(int listenerIdentifier, + String packageName) { + throw new UnsupportedOperationException(); + } } diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 14e994cf0f08..a78cca3aefdd 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -61,6 +61,7 @@ import android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback; import android.net.wifi.WifiManager.OnWifiUsabilityStatsListener; import android.net.wifi.WifiManager.ScanResultsListener; import android.net.wifi.WifiManager.SoftApCallback; +import android.net.wifi.WifiManager.SuggestionConnectionStatusListener; import android.net.wifi.WifiManager.TrafficStateCallback; import android.os.Binder; import android.os.Build; @@ -109,12 +110,14 @@ public class WifiManagerTest { @Mock NetworkRequestMatchCallback mNetworkRequestMatchCallback; @Mock OnWifiUsabilityStatsListener mOnWifiUsabilityStatsListener; @Mock ScanResultsListener mScanResultListener; + @Mock SuggestionConnectionStatusListener mListener; @Mock Executor mCallbackExecutor; @Mock Executor mExecutor; private Handler mHandler; private TestLooper mLooper; private WifiManager mWifiManager; + private WifiNetworkSuggestion mWifiNetworkSuggestion; @Before public void setUp() throws Exception { @@ -126,6 +129,7 @@ public class WifiManagerTest { when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME); mWifiManager = new WifiManager(mContext, mWifiService, mLooper.getLooper()); verify(mWifiService).getVerboseLoggingLevel(); + mWifiNetworkSuggestion = new WifiNetworkSuggestion(); } /** @@ -1803,4 +1807,69 @@ public class WifiManagerTest { public void testRemoveScanResultsListenerWithNullListener() throws Exception { mWifiManager.removeScanResultsListener(null); } + + /** + * Verify an IllegalArgumentException is thrown if executor not provided. + */ + @Test(expected = IllegalArgumentException.class) + public void testAddSuggestionConnectionStatusListenerWithNullExecutor() { + mWifiManager.addSuggestionConnectionStatusListener(null, mListener); + } + + /** + * Verify an IllegalArgumentException is thrown if listener is not provided. + */ + @Test(expected = IllegalArgumentException.class) + public void testAddSuggestionConnectionStatusListenerWithNullListener() { + mWifiManager.addSuggestionConnectionStatusListener(mExecutor, null); + } + + /** + * Verify client provided listener is being called to the right listener. + */ + @Test + public void testAddSuggestionConnectionStatusListenerAndReceiveEvent() throws Exception { + int errorCode = WifiManager.STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION; + ArgumentCaptor callbackCaptor = + ArgumentCaptor.forClass(ISuggestionConnectionStatusListener.Stub.class); + Executor executor = new SynchronousExecutor(); + mWifiManager.addSuggestionConnectionStatusListener(executor, mListener); + verify(mWifiService).registerSuggestionConnectionStatusListener(any(IBinder.class), + callbackCaptor.capture(), anyInt(), anyString()); + callbackCaptor.getValue().onConnectionStatus(mWifiNetworkSuggestion, errorCode); + verify(mListener).onConnectionStatus(any(WifiNetworkSuggestion.class), eq(errorCode)); + } + + /** + * Verify client provided listener is being called to the right executor. + */ + @Test + public void testAddSuggestionConnectionStatusListenerWithTheTargetExecutor() throws Exception { + int errorCode = WifiManager.STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION; + ArgumentCaptor callbackCaptor = + ArgumentCaptor.forClass(ISuggestionConnectionStatusListener.Stub.class); + mWifiManager.addSuggestionConnectionStatusListener(mExecutor, mListener); + verify(mWifiService).registerSuggestionConnectionStatusListener(any(IBinder.class), + callbackCaptor.capture(), anyInt(), anyString()); + callbackCaptor.getValue().onConnectionStatus(any(WifiNetworkSuggestion.class), errorCode); + verify(mExecutor).execute(any(Runnable.class)); + } + + /** + * Verify an IllegalArgumentException is thrown if listener is not provided. + */ + @Test(expected = IllegalArgumentException.class) + public void testRemoveSuggestionConnectionListenerWithNullListener() { + mWifiManager.removeSuggestionConnectionStatusListener(null); + } + + /** + * Verify removeSuggestionConnectionListener. + */ + @Test + public void testRemoveSuggestionConnectionListener() throws Exception { + + mWifiManager.removeSuggestionConnectionStatusListener(mListener); + verify(mWifiService).unregisterSuggestionConnectionStatusListener(anyInt(), anyString()); + } } -- cgit v1.2.3 From a4b01b2a8f67f5acf2aaa4a246318ccdcb6127dd Mon Sep 17 00:00:00 2001 From: Sunil Ravi Date: Thu, 31 Oct 2019 16:56:42 -0700 Subject: wifi: MBO-OCE feature support (phase 1) Define feature flags for MBO and OCE. Bug: 139474288 Test: atest com.android.server.wifi Test: Manual Change-Id: If713da6500c1d511972b9a84bd0c37b36148d92c --- wifi/java/android/net/wifi/WifiManager.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 2cf3b59c9a51..c20841f1aa4d 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -2246,11 +2246,15 @@ public class WifiManager { /** @hide */ public static final long WIFI_FEATURE_DPP = 0x80000000L; // DPP (Easy-Connect) /** @hide */ - public static final long WIFI_FEATURE_P2P_RAND_MAC = 0x100000000L; // Random P2P MAC + public static final long WIFI_FEATURE_P2P_RAND_MAC = 0x100000000L; // Random P2P MAC /** @hide */ public static final long WIFI_FEATURE_CONNECTED_RAND_MAC = 0x200000000L; // Random STA MAC /** @hide */ - public static final long WIFI_FEATURE_AP_RAND_MAC = 0x400000000L; // Random AP MAC + public static final long WIFI_FEATURE_AP_RAND_MAC = 0x400000000L; // Random AP MAC + /** @hide */ + public static final long WIFI_FEATURE_MBO = 0x800000000L; // MBO Support + /** @hide */ + public static final long WIFI_FEATURE_OCE = 0x1000000000L; // OCE Support private long getSupportedFeatures() { try { -- cgit v1.2.3 From 80c86d5c080e99a4f685cc8e7693e587033c6b45 Mon Sep 17 00:00:00 2001 From: James Mattis Date: Thu, 31 Oct 2019 14:11:40 -0700 Subject: Marking SoftApCallback methods as SystemAPI Making SoftApCallback methods available to @SystemAPI including the API for registration of a SoftApCallback. This includes updating registration to use an executor now vs a handler. Bug: 143564153 Test: atest FrameworksWifiApiTests:android.net.wifi.WifiManagerTest Also tested manually on a Hawk. Change-Id: I22b5029a8dbd7a50ad6faf0bb3b15269af839956 --- wifi/java/android/net/wifi/WifiManager.java | 30 +++++++++++++--------- .../src/android/net/wifi/WifiManagerTest.java | 21 +++++++-------- 2 files changed, 29 insertions(+), 22 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 2cf3b59c9a51..92f18ec6f065 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -3344,6 +3344,7 @@ public class WifiManager { * * @hide */ + @SystemApi public interface SoftApCallback { /** * Called when soft AP state changes. @@ -3381,11 +3382,11 @@ public class WifiManager { * @hide */ private class SoftApCallbackProxy extends ISoftApCallback.Stub { - private final Handler mHandler; + private final Executor mExecutor; private final SoftApCallback mCallback; - SoftApCallbackProxy(Looper looper, SoftApCallback callback) { - mHandler = new Handler(looper); + SoftApCallbackProxy(Executor executor, SoftApCallback callback) { + mExecutor = executor; mCallback = callback; } @@ -3396,7 +3397,8 @@ public class WifiManager { + ", failureReason=" + failureReason); } - mHandler.post(() -> { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> { mCallback.onStateChanged(state, failureReason); }); } @@ -3408,7 +3410,8 @@ public class WifiManager { + clients.size() + " clients"); } - mHandler.post(() -> { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> { mCallback.onConnectedClientsChanged(clients); }); } @@ -3418,7 +3421,9 @@ public class WifiManager { if (mVerboseLoggingEnabled) { Log.v(TAG, "SoftApCallbackProxy: onInfoChange: softApInfo=" + softApInfo); } - mHandler.post(() -> { + + Binder.clearCallingIdentity(); + mExecutor.execute(() -> { mCallback.onInfoChanged(softApInfo); }); } @@ -3437,18 +3442,19 @@ public class WifiManager { *

    * * @param callback Callback for soft AP events - * @param handler The Handler on whose thread to execute the callbacks of the {@code callback} - * object. If null, then the application's main thread will be used. + * @param executor The executor to execute the callbacks of the {@code executor} + * object. If null, then the application's main executor will be used. * * @hide */ + @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void registerSoftApCallback(@NonNull SoftApCallback callback, - @Nullable Handler handler) { + @Nullable @CallbackExecutor Executor executor) { if (callback == null) throw new IllegalArgumentException("callback cannot be null"); - Log.v(TAG, "registerSoftApCallback: callback=" + callback + ", handler=" + handler); + Log.v(TAG, "registerSoftApCallback: callback=" + callback + ", executor=" + executor); - Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper(); + executor = (executor == null) ? mContext.getMainExecutor() : executor; Binder binder = new Binder(); try { IWifiManager iWifiManager = getIWifiManager(); @@ -3456,7 +3462,7 @@ public class WifiManager { throw new RemoteException("Wifi service is not running"); } iWifiManager.registerSoftApCallback( - binder, new SoftApCallbackProxy(looper, callback), callback.hashCode()); + binder, new SoftApCallbackProxy(executor, callback), callback.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index a78cca3aefdd..b770f4e7a4c4 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -66,6 +66,7 @@ import android.net.wifi.WifiManager.TrafficStateCallback; import android.os.Binder; import android.os.Build; import android.os.Handler; +import android.os.HandlerExecutor; import android.os.IBinder; import android.os.RemoteException; import android.os.test.TestLooper; @@ -696,7 +697,7 @@ public class WifiManagerTest { @Test public void registerSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForCallback() { try { - mWifiManager.registerSoftApCallback(null, mHandler); + mWifiManager.registerSoftApCallback(null, new HandlerExecutor(mHandler)); fail("expected IllegalArgumentException"); } catch (IllegalArgumentException expected) { } @@ -721,7 +722,7 @@ public class WifiManagerTest { public void registerSoftApCallbackUsesMainLooperOnNullArgumentForHandler() { when(mContext.getMainLooper()).thenReturn(mLooper.getLooper()); mWifiManager.registerSoftApCallback(mSoftApCallback, null); - verify(mContext).getMainLooper(); + verify(mContext).getMainExecutor(); } /** @@ -729,7 +730,7 @@ public class WifiManagerTest { */ @Test public void registerSoftApCallbackCallGoesToWifiServiceImpl() throws Exception { - mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler); + mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler)); verify(mWifiService).registerSoftApCallback(any(IBinder.class), any(ISoftApCallback.Stub.class), anyInt()); } @@ -740,7 +741,7 @@ public class WifiManagerTest { @Test public void unregisterSoftApCallbackCallGoesToWifiServiceImpl() throws Exception { ArgumentCaptor callbackIdentifier = ArgumentCaptor.forClass(Integer.class); - mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler); + mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler)); verify(mWifiService).registerSoftApCallback(any(IBinder.class), any(ISoftApCallback.Stub.class), callbackIdentifier.capture()); @@ -755,7 +756,7 @@ public class WifiManagerTest { public void softApCallbackProxyCallsOnStateChanged() throws Exception { ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(ISoftApCallback.Stub.class); - mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler); + mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler)); verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -771,7 +772,7 @@ public class WifiManagerTest { public void softApCallbackProxyCallsOnConnectedClientsChanged() throws Exception { ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(ISoftApCallback.Stub.class); - mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler); + mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler)); verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -792,7 +793,7 @@ public class WifiManagerTest { testSoftApInfo.setBandwidth(TEST_AP_BANDWIDTH); ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(ISoftApCallback.Stub.class); - mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler); + mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler)); verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -811,7 +812,7 @@ public class WifiManagerTest { testSoftApInfo.setBandwidth(TEST_AP_BANDWIDTH); ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(ISoftApCallback.Stub.class); - mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler); + mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler)); verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -837,7 +838,7 @@ public class WifiManagerTest { ArgumentCaptor.forClass(ISoftApCallback.Stub.class); TestLooper altLooper = new TestLooper(); Handler altHandler = new Handler(altLooper.getLooper()); - mWifiManager.registerSoftApCallback(mSoftApCallback, altHandler); + mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(altHandler)); verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -851,7 +852,7 @@ public class WifiManagerTest { */ @Test public void testCorrectLooperIsUsedForSoftApCallbackHandler() throws Exception { - mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler); + mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler)); mLooper.dispatchAll(); verify(mWifiService).registerSoftApCallback(any(IBinder.class), any(ISoftApCallback.Stub.class), anyInt()); -- cgit v1.2.3 From dcb850c58002c807537249347f9ead188cbe0f4f Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Fri, 4 Oct 2019 08:14:38 -0700 Subject: Pipe through featureId from calling context to wifi location checking code Bug: 136595429 Test: atest FrameworksWifiTests FrameworksWifiApiTests Change-Id: I7e1090e6e618dcd9e67b64c0f4c29934c8e1a69e --- wifi/java/android/net/wifi/IWifiManager.aidl | 17 ++-- wifi/java/android/net/wifi/IWifiScanner.aidl | 2 +- wifi/java/android/net/wifi/WifiManager.java | 23 +++-- wifi/java/android/net/wifi/WifiScanner.java | 11 ++- .../android/net/wifi/aware/IWifiAwareManager.aidl | 13 +-- .../android/net/wifi/aware/WifiAwareManager.java | 8 +- wifi/java/android/net/wifi/p2p/WifiP2pManager.java | 8 ++ .../java/android/net/wifi/rtt/IWifiRttManager.aidl | 4 +- wifi/java/android/net/wifi/rtt/WifiRttManager.java | 4 +- .../com/android/server/wifi/BaseWifiService.java | 19 ++-- .../src/android/net/wifi/WifiManagerTest.java | 105 +++++++++++---------- .../src/android/net/wifi/WifiScannerTest.java | 5 +- .../net/wifi/aware/WifiAwareManagerTest.java | 54 ++++++----- .../android/net/wifi/rtt/WifiRttManagerTest.java | 10 +- 14 files changed, 164 insertions(+), 119 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index bc73a93f1e56..bbb85440f729 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -64,9 +64,9 @@ interface IWifiManager */ oneway void requestActivityInfo(in ResultReceiver result); - ParceledListSlice getConfiguredNetworks(String packageName); + ParceledListSlice getConfiguredNetworks(String packageName, String featureId); - ParceledListSlice getPrivilegedConfiguredNetworks(String packageName); + ParceledListSlice getPrivilegedConfiguredNetworks(String packageName, String featureId); Map getAllMatchingFqdnsForScanResults(in List scanResult); @@ -98,9 +98,9 @@ interface IWifiManager void allowAutojoin(int netId, boolean choice); - boolean startScan(String packageName); + boolean startScan(String packageName, String featureId); - List getScanResults(String callingPackage); + List getScanResults(String callingPackage, String callingFeatureId); boolean disconnect(String packageName); @@ -108,7 +108,7 @@ interface IWifiManager boolean reassociate(String packageName); - WifiInfo getConnectionInfo(String callingPackage); + WifiInfo getConnectionInfo(String callingPackage, String callingFeatureId); boolean setWifiEnabled(String packageName, boolean enable); @@ -145,7 +145,7 @@ interface IWifiManager boolean stopSoftAp(); int startLocalOnlyHotspot(in ILocalOnlyHotspotCallback callback, String packageName, - in SoftApConfiguration customConfig); + String featureId, in SoftApConfiguration customConfig); void stopLocalOnlyHotspot(); @@ -206,7 +206,8 @@ interface IWifiManager void unregisterNetworkRequestMatchCallback(int callbackIdentifier); - int addNetworkSuggestions(in List networkSuggestions, in String packageName); + int addNetworkSuggestions(in List networkSuggestions, in String packageName, + in String featureId); int removeNetworkSuggestions(in List networkSuggestions, in String packageName); @@ -238,7 +239,7 @@ interface IWifiManager void unregisterScanResultsListener(int listenerIdentifier); - void registerSuggestionConnectionStatusListener(in IBinder binder, in ISuggestionConnectionStatusListener listener, int listenerIdentifier, String packageName); + void registerSuggestionConnectionStatusListener(in IBinder binder, in ISuggestionConnectionStatusListener listener, int listenerIdentifier, String packageName, String featureId); void unregisterSuggestionConnectionStatusListener(int listenerIdentifier, String packageName); } diff --git a/wifi/java/android/net/wifi/IWifiScanner.aidl b/wifi/java/android/net/wifi/IWifiScanner.aidl index 114c7320bc3a..485f5ce5415e 100644 --- a/wifi/java/android/net/wifi/IWifiScanner.aidl +++ b/wifi/java/android/net/wifi/IWifiScanner.aidl @@ -26,5 +26,5 @@ interface IWifiScanner { Messenger getMessenger(); - Bundle getAvailableChannels(int band, String packageName); + Bundle getAvailableChannels(int band, String packageName, String featureId); } diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 2cf3b59c9a51..f1822043e275 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1254,7 +1254,8 @@ public class WifiManager { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) return Collections.emptyList(); ParceledListSlice parceledList = - iWifiManager.getConfiguredNetworks(mContext.getOpPackageName()); + iWifiManager.getConfiguredNetworks(mContext.getOpPackageName(), + mContext.getFeatureId()); if (parceledList == null) { return Collections.emptyList(); } @@ -1272,7 +1273,8 @@ public class WifiManager { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) return Collections.emptyList(); ParceledListSlice parceledList = - iWifiManager.getPrivilegedConfiguredNetworks(mContext.getOpPackageName()); + iWifiManager.getPrivilegedConfiguredNetworks(mContext.getOpPackageName(), + mContext.getFeatureId()); if (parceledList == null) { return Collections.emptyList(); } @@ -1764,7 +1766,7 @@ public class WifiManager { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) return STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL; return iWifiManager.addNetworkSuggestions( - networkSuggestions, mContext.getOpPackageName()); + networkSuggestions, mContext.getOpPackageName(), mContext.getFeatureId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2449,7 +2451,8 @@ public class WifiManager { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) return false; String packageName = mContext.getOpPackageName(); - return iWifiManager.startScan(packageName); + String featureId = mContext.getFeatureId(); + return iWifiManager.startScan(packageName, featureId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2480,7 +2483,8 @@ public class WifiManager { try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) return null; - return iWifiManager.getConnectionInfo(mContext.getOpPackageName()); + return iWifiManager.getConnectionInfo(mContext.getOpPackageName(), + mContext.getFeatureId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2496,7 +2500,8 @@ public class WifiManager { try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) return Collections.emptyList(); - return iWifiManager.getScanResults(mContext.getOpPackageName()); + return iWifiManager.getScanResults(mContext.getOpPackageName(), + mContext.getFeatureId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2914,7 +2919,9 @@ public class WifiManager { throw new RemoteException("Wifi service is not running"); } String packageName = mContext.getOpPackageName(); - int returnCode = iWifiManager.startLocalOnlyHotspot(proxy, packageName, config); + String featureId = mContext.getFeatureId(); + int returnCode = iWifiManager.startLocalOnlyHotspot(proxy, packageName, featureId, + config); if (returnCode != LocalOnlyHotspotCallback.REQUEST_REGISTERED) { // Send message to the proxy to make sure we call back on the correct thread proxy.onHotspotFailed(returnCode); @@ -5439,7 +5446,7 @@ public class WifiManager { } iWifiManager.registerSuggestionConnectionStatusListener(new Binder(), new SuggestionConnectionStatusListenerProxy(executor, listener), - listener.hashCode(), mContext.getOpPackageName()); + listener.hashCode(), mContext.getOpPackageName(), mContext.getFeatureId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index 0a9932624d18..7e14451332fb 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -137,7 +137,8 @@ public class WifiScanner { @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public List getAvailableChannels(@WifiBand int band) { try { - Bundle bundle = mService.getAvailableChannels(band, mContext.getOpPackageName()); + Bundle bundle = mService.getAvailableChannels(band, mContext.getOpPackageName(), + mContext.getFeatureId()); List channels = bundle.getIntegerArrayList(GET_AVAILABLE_CHANNELS_EXTRA); return channels == null ? new ArrayList<>() : channels; } catch (RemoteException e) { @@ -220,6 +221,8 @@ public class WifiScanner { public static final String SCAN_PARAMS_WORK_SOURCE_KEY = "WorkSource"; /** {@hide} */ public static final String REQUEST_PACKAGE_NAME_KEY = "PackageName"; + /** {@hide} */ + public static final String REQUEST_FEATURE_ID_KEY = "FeatureId"; /** * scan configuration parameters to be sent to {@link #startBackgroundScan} @@ -864,6 +867,7 @@ public class WifiScanner { scanParams.putParcelable(SCAN_PARAMS_SCAN_SETTINGS_KEY, settings); scanParams.putParcelable(SCAN_PARAMS_WORK_SOURCE_KEY, workSource); scanParams.putString(REQUEST_PACKAGE_NAME_KEY, mContext.getOpPackageName()); + scanParams.putString(REQUEST_FEATURE_ID_KEY, mContext.getFeatureId()); mAsyncChannel.sendMessage(CMD_START_BACKGROUND_SCAN, 0, key, scanParams); } @@ -880,6 +884,7 @@ public class WifiScanner { validateChannel(); Bundle scanParams = new Bundle(); scanParams.putString(REQUEST_PACKAGE_NAME_KEY, mContext.getOpPackageName()); + scanParams.putString(REQUEST_FEATURE_ID_KEY, mContext.getFeatureId()); mAsyncChannel.sendMessage(CMD_STOP_BACKGROUND_SCAN, 0, key, scanParams); } @@ -892,6 +897,7 @@ public class WifiScanner { validateChannel(); Bundle scanParams = new Bundle(); scanParams.putString(REQUEST_PACKAGE_NAME_KEY, mContext.getOpPackageName()); + scanParams.putString(REQUEST_FEATURE_ID_KEY, mContext.getFeatureId()); Message reply = mAsyncChannel.sendMessageSynchronously(CMD_GET_SCAN_RESULTS, 0, 0, scanParams); return reply.what == CMD_OP_SUCCEEDED; @@ -929,6 +935,7 @@ public class WifiScanner { scanParams.putParcelable(SCAN_PARAMS_SCAN_SETTINGS_KEY, settings); scanParams.putParcelable(SCAN_PARAMS_WORK_SOURCE_KEY, workSource); scanParams.putString(REQUEST_PACKAGE_NAME_KEY, mContext.getOpPackageName()); + scanParams.putString(REQUEST_FEATURE_ID_KEY, mContext.getFeatureId()); mAsyncChannel.sendMessage(CMD_START_SINGLE_SCAN, 0, key, scanParams); } @@ -945,6 +952,7 @@ public class WifiScanner { validateChannel(); Bundle scanParams = new Bundle(); scanParams.putString(REQUEST_PACKAGE_NAME_KEY, mContext.getOpPackageName()); + scanParams.putString(REQUEST_FEATURE_ID_KEY, mContext.getFeatureId()); mAsyncChannel.sendMessage(CMD_STOP_SINGLE_SCAN, 0, key, scanParams); } @@ -956,6 +964,7 @@ public class WifiScanner { validateChannel(); Bundle scanParams = new Bundle(); scanParams.putString(REQUEST_PACKAGE_NAME_KEY, mContext.getOpPackageName()); + scanParams.putString(REQUEST_FEATURE_ID_KEY, mContext.getFeatureId()); Message reply = mAsyncChannel.sendMessageSynchronously(CMD_GET_SINGLE_SCAN_RESULTS, 0, 0, scanParams); if (reply.what == WifiScanner.CMD_OP_SUCCEEDED) { diff --git a/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl b/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl index c4b24cfa2394..88f95ad4d495 100644 --- a/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl +++ b/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl @@ -38,14 +38,15 @@ interface IWifiAwareManager Characteristics getCharacteristics(); // client API - void connect(in IBinder binder, in String callingPackage, in IWifiAwareEventCallback callback, - in ConfigRequest configRequest, boolean notifyOnIdentityChanged); + void connect(in IBinder binder, in String callingPackage, in String callingFeatureId, + in IWifiAwareEventCallback callback, in ConfigRequest configRequest, + boolean notifyOnIdentityChanged); void disconnect(int clientId, in IBinder binder); - void publish(in String callingPackage, int clientId, in PublishConfig publishConfig, - in IWifiAwareDiscoverySessionCallback callback); - void subscribe(in String callingPackage, int clientId, in SubscribeConfig subscribeConfig, - in IWifiAwareDiscoverySessionCallback callback); + void publish(in String callingPackage, in String callingFeatureId, int clientId, + in PublishConfig publishConfig, in IWifiAwareDiscoverySessionCallback callback); + void subscribe(in String callingPackage, in String callingFeatureId, int clientId, + in SubscribeConfig subscribeConfig, in IWifiAwareDiscoverySessionCallback callback); // session API void updatePublish(int clientId, int discoverySessionId, in PublishConfig publishConfig); diff --git a/wifi/java/android/net/wifi/aware/WifiAwareManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java index 41a412b1d134..5aab3470d979 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java @@ -268,7 +268,7 @@ public class WifiAwareManager { try { Binder binder = new Binder(); - mService.connect(binder, mContext.getOpPackageName(), + mService.connect(binder, mContext.getOpPackageName(), mContext.getFeatureId(), new WifiAwareEventCallbackProxy(this, looper, binder, attachCallback, identityChangedListener), configRequest, identityChangedListener != null); @@ -299,7 +299,8 @@ public class WifiAwareManager { } try { - mService.publish(mContext.getOpPackageName(), clientId, publishConfig, + mService.publish(mContext.getOpPackageName(), mContext.getFeatureId(), clientId, + publishConfig, new WifiAwareDiscoverySessionCallbackProxy(this, looper, true, callback, clientId)); } catch (RemoteException e) { @@ -336,7 +337,8 @@ public class WifiAwareManager { } try { - mService.subscribe(mContext.getOpPackageName(), clientId, subscribeConfig, + mService.subscribe(mContext.getOpPackageName(), mContext.getFeatureId(), clientId, + subscribeConfig, new WifiAwareDiscoverySessionCallbackProxy(this, looper, false, callback, clientId)); } catch (RemoteException e) { diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java index d37c4a2e78db..3178519a6739 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java @@ -344,6 +344,13 @@ public class WifiP2pManager { public static final String CALLING_PACKAGE = "android.net.wifi.p2p.CALLING_PACKAGE"; + /** + * The lookup key for a calling feature id from WifiP2pManager + * @hide + */ + public static final String CALLING_FEATURE_ID = + "android.net.wifi.p2p.CALLING_FEATURE_ID"; + /** * The lookup key for a calling package binder from WifiP2pManager * @hide @@ -1159,6 +1166,7 @@ public class WifiP2pManager { == AsyncChannel.STATUS_SUCCESSFUL) { Bundle bundle = new Bundle(); bundle.putString(CALLING_PACKAGE, c.mContext.getOpPackageName()); + bundle.putString(CALLING_FEATURE_ID, c.mContext.getFeatureId()); bundle.putBinder(CALLING_BINDER, binder); c.mAsyncChannel.sendMessage(UPDATE_CHANNEL_INFO, 0, c.putListener(null), bundle); diff --git a/wifi/java/android/net/wifi/rtt/IWifiRttManager.aidl b/wifi/java/android/net/wifi/rtt/IWifiRttManager.aidl index 3e37af06ab27..7c92a6b6bdba 100644 --- a/wifi/java/android/net/wifi/rtt/IWifiRttManager.aidl +++ b/wifi/java/android/net/wifi/rtt/IWifiRttManager.aidl @@ -27,7 +27,7 @@ import android.net.wifi.rtt.RangingRequest; interface IWifiRttManager { boolean isAvailable(); - void startRanging(in IBinder binder, in String callingPackage, in WorkSource workSource, - in RangingRequest request, in IRttCallback callback); + void startRanging(in IBinder binder, in String callingPackage, in String callingFeatureId, + in WorkSource workSource, in RangingRequest request, in IRttCallback callback); void cancelRanging(in WorkSource workSource); } diff --git a/wifi/java/android/net/wifi/rtt/WifiRttManager.java b/wifi/java/android/net/wifi/rtt/WifiRttManager.java index 457e904126a2..770a12096806 100644 --- a/wifi/java/android/net/wifi/rtt/WifiRttManager.java +++ b/wifi/java/android/net/wifi/rtt/WifiRttManager.java @@ -146,8 +146,8 @@ public class WifiRttManager { Binder binder = new Binder(); try { - mService.startRanging(binder, mContext.getOpPackageName(), workSource, request, - new IRttCallback.Stub() { + mService.startRanging(binder, mContext.getOpPackageName(), mContext.getFeatureId(), + workSource, request, new IRttCallback.Stub() { @Override public void onRangingFailure(int status) throws RemoteException { clearCallingIdentity(); diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index 671708ff4c9d..6a6e7a1a202e 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -86,12 +86,12 @@ public class BaseWifiService extends IWifiManager.Stub { } @Override - public ParceledListSlice getConfiguredNetworks(String packageName) { + public ParceledListSlice getConfiguredNetworks(String packageName, String featureId) { throw new UnsupportedOperationException(); } @Override - public ParceledListSlice getPrivilegedConfiguredNetworks(String packageName) { + public ParceledListSlice getPrivilegedConfiguredNetworks(String packageName, String featureId) { throw new UnsupportedOperationException(); } @@ -175,12 +175,12 @@ public class BaseWifiService extends IWifiManager.Stub { } @Override - public boolean startScan(String packageName) { + public boolean startScan(String packageName, String featureId) { throw new UnsupportedOperationException(); } @Override - public List getScanResults(String callingPackage) { + public List getScanResults(String callingPackage, String callingFeatureId) { throw new UnsupportedOperationException(); } @@ -200,7 +200,7 @@ public class BaseWifiService extends IWifiManager.Stub { } @Override - public WifiInfo getConnectionInfo(String callingPackage) { + public WifiInfo getConnectionInfo(String callingPackage, String callingFeatureId) { throw new UnsupportedOperationException(); } @@ -298,12 +298,12 @@ public class BaseWifiService extends IWifiManager.Stub { /** @deprecated replaced by newer signature */ @Deprecated public int startLocalOnlyHotspot(ILocalOnlyHotspotCallback callback, String packageName) { - return startLocalOnlyHotspot(callback, packageName, null); + return startLocalOnlyHotspot(callback, packageName, null, null); } @Override public int startLocalOnlyHotspot(ILocalOnlyHotspotCallback callback, String packageName, - SoftApConfiguration customConfig) { + String featureId, SoftApConfiguration customConfig) { throw new UnsupportedOperationException(); } @@ -449,7 +449,8 @@ public class BaseWifiService extends IWifiManager.Stub { @Override public int addNetworkSuggestions( - List networkSuggestions, String callingPackageName) { + List networkSuggestions, String callingPackageName, + String callingFeatureId) { throw new UnsupportedOperationException(); } @@ -545,7 +546,7 @@ public class BaseWifiService extends IWifiManager.Stub { @Override public void registerSuggestionConnectionStatusListener(IBinder binder, ISuggestionConnectionStatusListener listener, - int listenerIdentifier, String packageName) { + int listenerIdentifier, String packageName, String featureId) { throw new UnsupportedOperationException(); } diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index a78cca3aefdd..6ddab93c0970 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -34,6 +34,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyList; @@ -96,6 +97,7 @@ public class WifiManagerTest { private static final int TEST_UID = 14553; private static final int TEST_NETWORK_ID = 143; private static final String TEST_PACKAGE_NAME = "TestPackage"; + private static final String TEST_FEATURE_ID = "TestFeature"; private static final String TEST_COUNTRY_CODE = "US"; private static final String[] TEST_MAC_ADDRESSES = {"da:a1:19:0:0:0"}; private static final int TEST_AP_FREQUENCY = 2412; @@ -177,8 +179,8 @@ public class WifiManagerTest { @Test public void testCreationAndCloseOfLocalOnlyHotspotReservation() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), - anyString(), eq(null))).thenReturn(REQUEST_REGISTERED); + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), + nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(mApConfig)); @@ -195,8 +197,8 @@ public class WifiManagerTest { public void testLocalOnlyHotspotReservationCallsStopProperlyInTryWithResources() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), - anyString(), eq(null))).thenReturn(REQUEST_REGISTERED); + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), + nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(mApConfig)); @@ -355,8 +357,8 @@ public class WifiManagerTest { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); mWifiManager.startLocalOnlyHotspot(callback, mHandler); - verify(mWifiService) - .startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), eq(null)); + verify(mWifiService).startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), + anyString(), nullable(String.class), eq(null)); } /** @@ -366,8 +368,9 @@ public class WifiManagerTest { @Test(expected = SecurityException.class) public void testStartLocalOnlyHotspotThrowsSecurityException() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - doThrow(new SecurityException()).when(mWifiService) - .startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), eq(null)); + doThrow(new SecurityException()).when(mWifiService).startLocalOnlyHotspot( + any(ILocalOnlyHotspotCallback.class), anyString(), nullable(String.class), + eq(null)); mWifiManager.startLocalOnlyHotspot(callback, mHandler); } @@ -378,8 +381,9 @@ public class WifiManagerTest { @Test(expected = IllegalStateException.class) public void testStartLocalOnlyHotspotThrowsIllegalStateException() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - doThrow(new IllegalStateException()).when(mWifiService) - .startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), eq(null)); + doThrow(new IllegalStateException()).when(mWifiService).startLocalOnlyHotspot( + any(ILocalOnlyHotspotCallback.class), anyString(), nullable(String.class), + eq(null)); mWifiManager.startLocalOnlyHotspot(callback, mHandler); } @@ -389,8 +393,8 @@ public class WifiManagerTest { @Test public void testCorrectLooperIsUsedForHandler() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), - anyString(), eq(null))).thenReturn(ERROR_INCOMPATIBLE_MODE); + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), + nullable(String.class), eq(null))).thenReturn(ERROR_INCOMPATIBLE_MODE); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mLooper.dispatchAll(); assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason); @@ -408,8 +412,8 @@ public class WifiManagerTest { TestLooper altLooper = new TestLooper(); when(mContext.getMainExecutor()).thenReturn(altLooper.getNewExecutor()); TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), - anyString(), eq(null))).thenReturn(ERROR_INCOMPATIBLE_MODE); + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), + nullable(String.class), eq(null))).thenReturn(ERROR_INCOMPATIBLE_MODE); mWifiManager.startLocalOnlyHotspot(callback, null); altLooper.dispatchAll(); assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason); @@ -428,8 +432,8 @@ public class WifiManagerTest { Handler callbackHandler = new Handler(callbackLooper.getLooper()); ArgumentCaptor internalCallback = ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); - when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(), eq(null))) - .thenReturn(REQUEST_REGISTERED); + when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(), + nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, callbackHandler); callbackLooper.dispatchAll(); mLooper.dispatchAll(); @@ -454,8 +458,8 @@ public class WifiManagerTest { Handler callbackHandler = new Handler(callbackLooper.getLooper()); ArgumentCaptor internalCallback = ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); - when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(), eq(null))) - .thenReturn(REQUEST_REGISTERED); + when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(), + nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, callbackHandler); callbackLooper.dispatchAll(); mLooper.dispatchAll(); @@ -479,8 +483,8 @@ public class WifiManagerTest { Handler callbackHandler = new Handler(callbackLooper.getLooper()); ArgumentCaptor internalCallback = ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); - when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(), eq(null))) - .thenReturn(REQUEST_REGISTERED); + when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(), + nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, callbackHandler); callbackLooper.dispatchAll(); mLooper.dispatchAll(); @@ -502,8 +506,8 @@ public class WifiManagerTest { Handler callbackHandler = new Handler(callbackLooper.getLooper()); ArgumentCaptor internalCallback = ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); - when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(), eq(null))) - .thenReturn(REQUEST_REGISTERED); + when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(), + nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, callbackHandler); callbackLooper.dispatchAll(); mLooper.dispatchAll(); @@ -521,8 +525,8 @@ public class WifiManagerTest { @Test public void testLocalOnlyHotspotCallbackFullOnIncompatibleMode() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), - anyString(), eq(null))).thenReturn(ERROR_INCOMPATIBLE_MODE); + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), + nullable(String.class), eq(null))).thenReturn(ERROR_INCOMPATIBLE_MODE); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mLooper.dispatchAll(); assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason); @@ -537,8 +541,8 @@ public class WifiManagerTest { @Test public void testLocalOnlyHotspotCallbackFullOnTetheringDisallowed() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), - anyString(), eq(null))).thenReturn(ERROR_TETHERING_DISALLOWED); + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), + nullable(String.class), eq(null))).thenReturn(ERROR_TETHERING_DISALLOWED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mLooper.dispatchAll(); assertEquals(ERROR_TETHERING_DISALLOWED, callback.mFailureReason); @@ -554,8 +558,9 @@ public class WifiManagerTest { @Test(expected = SecurityException.class) public void testLocalOnlyHotspotCallbackFullOnSecurityException() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - doThrow(new SecurityException()).when(mWifiService) - .startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), eq(null)); + doThrow(new SecurityException()).when(mWifiService).startLocalOnlyHotspot( + any(ILocalOnlyHotspotCallback.class), anyString(), nullable(String.class), + eq(null)); try { mWifiManager.startLocalOnlyHotspot(callback, mHandler); } catch (SecurityException e) { @@ -575,8 +580,8 @@ public class WifiManagerTest { @Test public void testLocalOnlyHotspotCallbackFullOnNoChannelError() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), - anyString(), eq(null))).thenReturn(REQUEST_REGISTERED); + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), + nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mLooper.dispatchAll(); //assertEquals(ERROR_NO_CHANNEL, callback.mFailureReason); @@ -591,8 +596,8 @@ public class WifiManagerTest { @Test public void testCancelLocalOnlyHotspotRequestCallsStopOnWifiService() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), - anyString(), eq(null))).thenReturn(REQUEST_REGISTERED); + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), + nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mWifiManager.cancelLocalOnlyHotspotRequest(); verify(mWifiService).stopLocalOnlyHotspot(); @@ -613,8 +618,8 @@ public class WifiManagerTest { @Test public void testCallbackAfterLocalOnlyHotspotWasCancelled() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), - anyString(), eq(null))).thenReturn(REQUEST_REGISTERED); + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), + nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mWifiManager.cancelLocalOnlyHotspotRequest(); verify(mWifiService).stopLocalOnlyHotspot(); @@ -632,8 +637,8 @@ public class WifiManagerTest { @Test public void testCancelAfterLocalOnlyHotspotCallbackTriggered() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), - anyString(), eq(null))).thenReturn(ERROR_INCOMPATIBLE_MODE); + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), + nullable(String.class), eq(null))).thenReturn(ERROR_INCOMPATIBLE_MODE); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mLooper.dispatchAll(); assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason); @@ -651,8 +656,8 @@ public class WifiManagerTest { .build(); TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); mWifiManager.startLocalOnlyHotspot(customConfig, mExecutor, callback); - verify(mWifiService).startLocalOnlyHotspot( - any(ILocalOnlyHotspotCallback.class), anyString(), eq(customConfig)); + verify(mWifiService).startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), + anyString(), nullable(String.class), eq(customConfig)); } /** @@ -1126,10 +1131,12 @@ public class WifiManagerTest { */ @Test public void testStartScan() throws Exception { - when(mWifiService.startScan(TEST_PACKAGE_NAME)).thenReturn(true); + when(mWifiService.startScan(eq(TEST_PACKAGE_NAME), nullable(String.class))).thenReturn( + true); assertTrue(mWifiManager.startScan()); - when(mWifiService.startScan(TEST_PACKAGE_NAME)).thenReturn(false); + when(mWifiService.startScan(eq(TEST_PACKAGE_NAME), nullable(String.class))).thenReturn( + false); assertFalse(mWifiManager.startScan()); } @@ -1335,16 +1342,17 @@ public class WifiManagerTest { @Test public void addGetRemoveNetworkSuggestions() throws Exception { List testList = new ArrayList<>(); - when(mWifiService.addNetworkSuggestions(any(List.class), anyString())) - .thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS); - when(mWifiService.removeNetworkSuggestions(any(List.class), anyString())) - .thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS); + when(mWifiService.addNetworkSuggestions(any(List.class), anyString(), + nullable(String.class))).thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS); + when(mWifiService.removeNetworkSuggestions(any(List.class), anyString())).thenReturn( + WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS); when(mWifiService.getNetworkSuggestions(anyString())) .thenReturn(testList); assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS, mWifiManager.addNetworkSuggestions(testList)); - verify(mWifiService).addNetworkSuggestions(anyList(), eq(TEST_PACKAGE_NAME)); + verify(mWifiService).addNetworkSuggestions(anyList(), eq(TEST_PACKAGE_NAME), + nullable(String.class)); assertEquals(testList, mWifiManager.getNetworkSuggestions()); verify(mWifiService).getNetworkSuggestions(eq(TEST_PACKAGE_NAME)); @@ -1604,7 +1612,8 @@ public class WifiManagerTest { @Test public void testGetConnectionInfo() throws Exception { WifiInfo wifiInfo = new WifiInfo(); - when(mWifiService.getConnectionInfo(anyString())).thenReturn(wifiInfo); + when(mWifiService.getConnectionInfo(anyString(), nullable(String.class))).thenReturn( + wifiInfo); assertEquals(wifiInfo, mWifiManager.getConnectionInfo()); } @@ -1835,7 +1844,7 @@ public class WifiManagerTest { Executor executor = new SynchronousExecutor(); mWifiManager.addSuggestionConnectionStatusListener(executor, mListener); verify(mWifiService).registerSuggestionConnectionStatusListener(any(IBinder.class), - callbackCaptor.capture(), anyInt(), anyString()); + callbackCaptor.capture(), anyInt(), anyString(), nullable(String.class)); callbackCaptor.getValue().onConnectionStatus(mWifiNetworkSuggestion, errorCode); verify(mListener).onConnectionStatus(any(WifiNetworkSuggestion.class), eq(errorCode)); } @@ -1850,7 +1859,7 @@ public class WifiManagerTest { ArgumentCaptor.forClass(ISuggestionConnectionStatusListener.Stub.class); mWifiManager.addSuggestionConnectionStatusListener(mExecutor, mListener); verify(mWifiService).registerSuggestionConnectionStatusListener(any(IBinder.class), - callbackCaptor.capture(), anyInt(), anyString()); + callbackCaptor.capture(), anyInt(), anyString(), nullable(String.class)); callbackCaptor.getValue().onConnectionStatus(any(WifiNetworkSuggestion.class), errorCode); verify(mExecutor).execute(any(Runnable.class)); } diff --git a/wifi/tests/src/android/net/wifi/WifiScannerTest.java b/wifi/tests/src/android/net/wifi/WifiScannerTest.java index ea136d62b202..f4fa38beaa40 100644 --- a/wifi/tests/src/android/net/wifi/WifiScannerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiScannerTest.java @@ -267,6 +267,8 @@ public class WifiScannerTest { assertNull(messageBundle.getParcelable(WifiScanner.SCAN_PARAMS_WORK_SOURCE_KEY)); assertEquals(mContext.getOpPackageName(), messageBundle.getParcelable(WifiScanner.REQUEST_PACKAGE_NAME_KEY)); + assertEquals(mContext.getFeatureId(), + messageBundle.getParcelable(WifiScanner.REQUEST_FEATURE_ID_KEY)); } @@ -295,7 +297,8 @@ public class WifiScannerTest { Bundle messageBundle = (Bundle) message.obj; assertEquals(mContext.getOpPackageName(), messageBundle.getParcelable(WifiScanner.REQUEST_PACKAGE_NAME_KEY)); - + assertEquals(mContext.getFeatureId(), + messageBundle.getParcelable(WifiScanner.REQUEST_FEATURE_ID_KEY)); } /** diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java index db8220b41910..3483ff8a4664 100644 --- a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java +++ b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java @@ -168,7 +168,7 @@ public class WifiAwareManagerTest { // (1) connect + success mDut.attach(mockCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).connect(binder.capture(), any(), + inOrder.verify(mockAwareService).connect(binder.capture(), any(), any(), clientProxyCallback.capture(), isNull(), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); @@ -178,7 +178,8 @@ public class WifiAwareManagerTest { // (2) publish - should succeed PublishConfig publishConfig = new PublishConfig.Builder().build(); session.publish(publishConfig, mockSessionCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).publish(any(), eq(clientId), eq(publishConfig), any()); + inOrder.verify(mockAwareService).publish(any(), any(), eq(clientId), eq(publishConfig), + any()); // (3) disconnect session.close(); @@ -190,7 +191,7 @@ public class WifiAwareManagerTest { // (5) connect mDut.attach(mockCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).connect(binder.capture(), any(), any(), isNull(), + inOrder.verify(mockAwareService).connect(binder.capture(), any(), any(), any(), isNull(), eq(false)); verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService); @@ -212,7 +213,7 @@ public class WifiAwareManagerTest { // (1) connect + failure mDut.attach(mockCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(), isNull(), eq(false)); clientProxyCallback.getValue().onConnectFail(reason); mMockLooper.dispatchAll(); @@ -220,7 +221,7 @@ public class WifiAwareManagerTest { // (2) connect + success mDut.attach(mockCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(), isNull(), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); @@ -230,7 +231,8 @@ public class WifiAwareManagerTest { // (4) subscribe: should succeed SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build(); session.subscribe(subscribeConfig, mockSessionCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).subscribe(any(), eq(clientId), eq(subscribeConfig), any()); + inOrder.verify(mockAwareService).subscribe(any(), any(), eq(clientId), eq(subscribeConfig), + any()); verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService); } @@ -249,7 +251,7 @@ public class WifiAwareManagerTest { // (1) connect + success mDut.attach(mockCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(), isNull(), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); @@ -257,7 +259,7 @@ public class WifiAwareManagerTest { // (2) connect + success mDut.attach(mockCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(), isNull(), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId + 1); mMockLooper.dispatchAll(); @@ -304,7 +306,7 @@ public class WifiAwareManagerTest { // (0) connect + success mDut.attach(mMockLooperHandler, configRequest, mockCallback, null); - inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(), eq(configRequest), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); @@ -313,7 +315,7 @@ public class WifiAwareManagerTest { // (1) publish session.publish(publishConfig, mockSessionCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).publish(any(), eq(clientId), eq(publishConfig), + inOrder.verify(mockAwareService).publish(any(), any(), eq(clientId), eq(publishConfig), sessionProxyCallback.capture()); // (2) publish session created @@ -396,7 +398,7 @@ public class WifiAwareManagerTest { // (1) connect successfully mDut.attach(mMockLooperHandler, configRequest, mockCallback, null); - inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(), eq(configRequest), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); @@ -405,7 +407,7 @@ public class WifiAwareManagerTest { // (2) publish: successfully - then terminated session.publish(publishConfig, mockSessionCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).publish(any(), eq(clientId), eq(publishConfig), + inOrder.verify(mockAwareService).publish(any(), any(), eq(clientId), eq(publishConfig), sessionProxyCallback.capture()); sessionProxyCallback.getValue().onSessionStarted(sessionId); sessionProxyCallback.getValue().onSessionTerminated(0); @@ -453,7 +455,7 @@ public class WifiAwareManagerTest { // (0) connect + success mDut.attach(mMockLooperHandler, configRequest, mockCallback, null); - inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(), eq(configRequest), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); @@ -462,7 +464,7 @@ public class WifiAwareManagerTest { // (1) subscribe session.subscribe(subscribeConfig, mockSessionCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).subscribe(any(), eq(clientId), eq(subscribeConfig), + inOrder.verify(mockAwareService).subscribe(any(), any(), eq(clientId), eq(subscribeConfig), sessionProxyCallback.capture()); // (2) subscribe session created @@ -538,7 +540,7 @@ public class WifiAwareManagerTest { // (1) connect successfully mDut.attach(mMockLooperHandler, configRequest, mockCallback, null); - inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(), eq(configRequest), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); @@ -547,7 +549,7 @@ public class WifiAwareManagerTest { // (2) subscribe: successfully - then terminated session.subscribe(subscribeConfig, mockSessionCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).subscribe(any(), eq(clientId), eq(subscribeConfig), + inOrder.verify(mockAwareService).subscribe(any(), any(), eq(clientId), eq(subscribeConfig), sessionProxyCallback.capture()); sessionProxyCallback.getValue().onSessionStarted(sessionId); sessionProxyCallback.getValue().onSessionTerminated(0); @@ -942,7 +944,7 @@ public class WifiAwareManagerTest { // (1) connect successfully mDut.attach(mMockLooperHandler, configRequest, mockCallback, null); - inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(), eq(configRequest), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); @@ -951,7 +953,7 @@ public class WifiAwareManagerTest { // (2) publish successfully session.publish(publishConfig, mockSessionCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).publish(any(), eq(clientId), eq(publishConfig), + inOrder.verify(mockAwareService).publish(any(), any(), eq(clientId), eq(publishConfig), sessionProxyCallback.capture()); sessionProxyCallback.getValue().onSessionStarted(sessionId); mMockLooper.dispatchAll(); @@ -1055,7 +1057,7 @@ public class WifiAwareManagerTest { // (1) connect successfully mDut.attach(mMockLooperHandler, configRequest, mockCallback, null); - inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(), eq(configRequest), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); @@ -1239,7 +1241,7 @@ public class WifiAwareManagerTest { // (1) connect successfully mDut.attach(mMockLooperHandler, configRequest, mockCallback, null); - inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(), eq(configRequest), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); @@ -1248,7 +1250,7 @@ public class WifiAwareManagerTest { // (2) publish successfully session.publish(publishConfig, mockSessionCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).publish(any(), eq(clientId), eq(publishConfig), + inOrder.verify(mockAwareService).publish(any(), any(), eq(clientId), eq(publishConfig), sessionProxyCallback.capture()); sessionProxyCallback.getValue().onSessionStarted(sessionId); mMockLooper.dispatchAll(); @@ -1474,7 +1476,7 @@ public class WifiAwareManagerTest { // (1) connect successfully mDut.attach(mMockLooperHandler, configRequest, mockCallback, null); - inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(), eq(configRequest), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); @@ -1514,7 +1516,7 @@ public class WifiAwareManagerTest { // (1) connect successfully mDut.attach(mMockLooperHandler, configRequest, mockCallback, null); - inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(), eq(configRequest), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); @@ -1524,7 +1526,7 @@ public class WifiAwareManagerTest { if (isPublish) { // (2) publish successfully session.publish(publishConfig, mockSessionCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).publish(any(), eq(clientId), eq(publishConfig), + inOrder.verify(mockAwareService).publish(any(), any(), eq(clientId), eq(publishConfig), sessionProxyCallback.capture()); sessionProxyCallback.getValue().onSessionStarted(sessionId); mMockLooper.dispatchAll(); @@ -1533,8 +1535,8 @@ public class WifiAwareManagerTest { } else { // (2) subscribe successfully session.subscribe(subscribeConfig, mockSessionCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).subscribe(any(), eq(clientId), eq(subscribeConfig), - sessionProxyCallback.capture()); + inOrder.verify(mockAwareService).subscribe(any(), any(), eq(clientId), + eq(subscribeConfig), sessionProxyCallback.capture()); sessionProxyCallback.getValue().onSessionStarted(sessionId); mMockLooper.dispatchAll(); inOrder.verify(mockSessionCallback).onSubscribeStarted(subscribeSession.capture()); diff --git a/wifi/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java b/wifi/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java index 53bd837d29e0..a9dcde07fd72 100644 --- a/wifi/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java +++ b/wifi/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java @@ -54,6 +54,7 @@ public class WifiRttManagerTest { private Executor mMockLooperExecutor; private final String packageName = "some.package.name.for.rtt.app"; + private final String featureId = "some.feature.id.in.rtt.app"; @Mock public Context mockContext; @@ -70,6 +71,7 @@ public class WifiRttManagerTest { mMockLooperExecutor = mMockLooper.getNewExecutor(); when(mockContext.getOpPackageName()).thenReturn(packageName); + when(mockContext.getFeatureId()).thenReturn(featureId); } /** @@ -87,8 +89,8 @@ public class WifiRttManagerTest { // verify ranging request passed to service mDut.startRanging(request, mMockLooperExecutor, callbackMock); - verify(mockRttService).startRanging(any(IBinder.class), eq(packageName), eq(null), - eq(request), callbackCaptor.capture()); + verify(mockRttService).startRanging(any(IBinder.class), eq(packageName), eq(featureId), + eq(null), eq(request), callbackCaptor.capture()); // service calls back with success callbackCaptor.getValue().onRangingResults(results); @@ -111,8 +113,8 @@ public class WifiRttManagerTest { // verify ranging request passed to service mDut.startRanging(request, mMockLooperExecutor, callbackMock); - verify(mockRttService).startRanging(any(IBinder.class), eq(packageName), eq(null), - eq(request), callbackCaptor.capture()); + verify(mockRttService).startRanging(any(IBinder.class), eq(packageName), eq(featureId), + eq(null), eq(request), callbackCaptor.capture()); // service calls back with failure code callbackCaptor.getValue().onRangingFailure(failureCode); -- cgit v1.2.3 From ee9a5ae15cc3b632615faad98f76312bec5d2e75 Mon Sep 17 00:00:00 2001 From: "Nate(Qiang) Jiang" Date: Mon, 11 Nov 2019 10:28:48 -0800 Subject: [WifiAware] fix creator from parcel creator should read all content from parcel before verify available Bug: 144286370 Test: atest android.net.wifi Change-Id: Ie0f4954f5ca6cdb0ae1f77bfd4420b75f302c0f3 --- wifi/java/android/net/wifi/aware/WifiAwareNetworkInfo.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/aware/WifiAwareNetworkInfo.java b/wifi/java/android/net/wifi/aware/WifiAwareNetworkInfo.java index fd26817bfd79..60fe60438ce7 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareNetworkInfo.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareNetworkInfo.java @@ -120,10 +120,12 @@ public final class WifiAwareNetworkInfo implements TransportInfo, Parcelable { new Creator() { @Override public WifiAwareNetworkInfo createFromParcel(Parcel in) { + byte[] addr = in.createByteArray(); + String interfaceName = in.readString(); + int port = in.readInt(); + int transportProtocol = in.readInt(); Inet6Address ipv6Addr; try { - byte[] addr = in.createByteArray(); - String interfaceName = in.readString(); NetworkInterface ni = null; if (interfaceName != null) { try { @@ -135,11 +137,8 @@ public final class WifiAwareNetworkInfo implements TransportInfo, Parcelable { ipv6Addr = Inet6Address.getByAddress(null, addr, ni); } catch (UnknownHostException e) { e.printStackTrace(); - return null; + return new WifiAwareNetworkInfo(null); } - int port = in.readInt(); - int transportProtocol = in.readInt(); - return new WifiAwareNetworkInfo(ipv6Addr, port, transportProtocol); } -- cgit v1.2.3 From 651135848dd766e3b5226f5f36c0af6b2842fab5 Mon Sep 17 00:00:00 2001 From: Hugo Benichi Date: Thu, 7 Nov 2019 12:23:00 +0900 Subject: wifi: remove @Deprecated APIs Bug: 122431221 Test: Compiled. Change-Id: Iec44112618f3bd57e3e8047edff512f741779766 --- wifi/java/com/android/server/wifi/BaseWifiService.java | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'wifi') diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index 6a6e7a1a202e..cf74ff07d2ee 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -289,18 +289,6 @@ public class BaseWifiService extends IWifiManager.Stub { throw new UnsupportedOperationException(); } - /** @deprecated replaced by {@link #startLocalOnlyHotspot(ILocalOnlyHotspotCallback, String)} */ - @Deprecated - public int startLocalOnlyHotspot(Messenger messenger, IBinder binder, String packageName) { - throw new UnsupportedOperationException(); - } - - /** @deprecated replaced by newer signature */ - @Deprecated - public int startLocalOnlyHotspot(ILocalOnlyHotspotCallback callback, String packageName) { - return startLocalOnlyHotspot(callback, packageName, null, null); - } - @Override public int startLocalOnlyHotspot(ILocalOnlyHotspotCallback callback, String packageName, String featureId, SoftApConfiguration customConfig) { @@ -312,12 +300,6 @@ public class BaseWifiService extends IWifiManager.Stub { 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(); -- cgit v1.2.3 From 0790456494461c684fa17b827e37a29de7425c05 Mon Sep 17 00:00:00 2001 From: lesl Date: Wed, 13 Nov 2019 14:17:27 +0800 Subject: wifi: remove saePasswordId from getBytesForBackup getBytesForBackup is used for Softap. Don't need saePasswordId Bug: 0 Test: unit test, atest frameworks/base/wifi/tests/ Change-Id: Ia85fa65d6a1f939ebd57c20d4c432b6303107b81 --- wifi/java/android/net/wifi/WifiConfiguration.java | 2 -- 1 file changed, 2 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 30c24d37a494..90343d4798a7 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -2627,7 +2627,6 @@ public class WifiConfiguration implements Parcelable { out.writeInt(apBand); out.writeInt(apChannel); BackupUtils.writeString(out, preSharedKey); - BackupUtils.writeString(out, saePasswordId); out.writeInt(getAuthType()); out.writeBoolean(hiddenSSID); return baos.toByteArray(); @@ -2651,7 +2650,6 @@ public class WifiConfiguration implements Parcelable { config.apBand = in.readInt(); config.apChannel = in.readInt(); config.preSharedKey = BackupUtils.readString(in); - config.saePasswordId = BackupUtils.readString(in); config.allowedKeyManagement.set(in.readInt()); if (version >= 3) { config.hiddenSSID = in.readBoolean(); -- cgit v1.2.3 From cb157e8a331d2149dee0a45252b35ba72f399c05 Mon Sep 17 00:00:00 2001 From: James Mattis Date: Tue, 12 Nov 2019 17:43:48 -0800 Subject: Swap param order in registerSoftApCallback Moving executor to be the first argument in registerSoftApCallback. Bug: 144379300 Test: atest FrameworksWifiApiTests:android.net.wifi.WifiManagerTest Manually on pixel 3 Change-Id: I7074278d16beac422ce7b29d4471b2794fa97825 --- wifi/java/android/net/wifi/WifiManager.java | 8 ++++---- wifi/tests/src/android/net/wifi/WifiManagerTest.java | 20 ++++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 93960de89d89..d6e8d6aaa5ab 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -3351,7 +3351,7 @@ public class WifiManager { /** * Base class for soft AP callback. Should be extended by applications and set when calling - * {@link WifiManager#registerSoftApCallback(SoftApCallback, Handler)}. + * {@link WifiManager#registerSoftApCallback(Executor, SoftApCallback)}. * * @hide */ @@ -3452,16 +3452,16 @@ public class WifiManager { * without the permission will trigger a {@link java.lang.SecurityException}. *

    * - * @param callback Callback for soft AP events * @param executor The executor to execute the callbacks of the {@code executor} * object. If null, then the application's main executor will be used. + * @param callback Callback for soft AP events * * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - public void registerSoftApCallback(@NonNull SoftApCallback callback, - @Nullable @CallbackExecutor Executor executor) { + public void registerSoftApCallback(@Nullable @CallbackExecutor Executor executor, + @NonNull SoftApCallback callback) { if (callback == null) throw new IllegalArgumentException("callback cannot be null"); Log.v(TAG, "registerSoftApCallback: callback=" + callback + ", executor=" + executor); diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 17f3bb2b130b..1e9bc6081fa8 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -702,7 +702,7 @@ public class WifiManagerTest { @Test public void registerSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForCallback() { try { - mWifiManager.registerSoftApCallback(null, new HandlerExecutor(mHandler)); + mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), null); fail("expected IllegalArgumentException"); } catch (IllegalArgumentException expected) { } @@ -726,7 +726,7 @@ public class WifiManagerTest { @Test public void registerSoftApCallbackUsesMainLooperOnNullArgumentForHandler() { when(mContext.getMainLooper()).thenReturn(mLooper.getLooper()); - mWifiManager.registerSoftApCallback(mSoftApCallback, null); + mWifiManager.registerSoftApCallback(null, mSoftApCallback); verify(mContext).getMainExecutor(); } @@ -735,7 +735,7 @@ public class WifiManagerTest { */ @Test public void registerSoftApCallbackCallGoesToWifiServiceImpl() throws Exception { - mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler)); + mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); verify(mWifiService).registerSoftApCallback(any(IBinder.class), any(ISoftApCallback.Stub.class), anyInt()); } @@ -746,7 +746,7 @@ public class WifiManagerTest { @Test public void unregisterSoftApCallbackCallGoesToWifiServiceImpl() throws Exception { ArgumentCaptor callbackIdentifier = ArgumentCaptor.forClass(Integer.class); - mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler)); + mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); verify(mWifiService).registerSoftApCallback(any(IBinder.class), any(ISoftApCallback.Stub.class), callbackIdentifier.capture()); @@ -761,7 +761,7 @@ public class WifiManagerTest { public void softApCallbackProxyCallsOnStateChanged() throws Exception { ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(ISoftApCallback.Stub.class); - mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler)); + mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -777,7 +777,7 @@ public class WifiManagerTest { public void softApCallbackProxyCallsOnConnectedClientsChanged() throws Exception { ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(ISoftApCallback.Stub.class); - mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler)); + mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -798,7 +798,7 @@ public class WifiManagerTest { testSoftApInfo.setBandwidth(TEST_AP_BANDWIDTH); ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(ISoftApCallback.Stub.class); - mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler)); + mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -817,7 +817,7 @@ public class WifiManagerTest { testSoftApInfo.setBandwidth(TEST_AP_BANDWIDTH); ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(ISoftApCallback.Stub.class); - mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler)); + mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -843,7 +843,7 @@ public class WifiManagerTest { ArgumentCaptor.forClass(ISoftApCallback.Stub.class); TestLooper altLooper = new TestLooper(); Handler altHandler = new Handler(altLooper.getLooper()); - mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(altHandler)); + mWifiManager.registerSoftApCallback(new HandlerExecutor(altHandler), mSoftApCallback); verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -857,7 +857,7 @@ public class WifiManagerTest { */ @Test public void testCorrectLooperIsUsedForSoftApCallbackHandler() throws Exception { - mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler)); + mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); mLooper.dispatchAll(); verify(mWifiService).registerSoftApCallback(any(IBinder.class), any(ISoftApCallback.Stub.class), anyInt()); -- cgit v1.2.3 From 35f1fcdc8d8253260ea38e43b8883167a8ac6248 Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Mon, 11 Nov 2019 10:12:15 -0800 Subject: [AWARE] Allow setPMK API Allowing configuration of the PMK is required for any PK-based protocols which operate OOB. Bug: 143956273 Bug: 111446262 Test: test android.net.wifi.aware Change-Id: Iccd9739901116399518f278e7d9c9992c1507f3f --- .../android/net/wifi/aware/WifiAwareNetworkSpecifier.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java index 0511f2411647..5a4ed3c2f5e3 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java @@ -20,7 +20,6 @@ import static android.net.wifi.aware.WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_ import android.annotation.IntRange; import android.annotation.NonNull; -import android.annotation.SystemApi; import android.net.NetworkSpecifier; import android.os.Parcel; import android.os.Parcelable; @@ -337,7 +336,8 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements * Configure the PSK Passphrase for the Wi-Fi Aware connection being requested. This method * is optional - if not called, then an Open (unencrypted) connection will be created. * - * @param pskPassphrase The (optional) passphrase to be used to encrypt the link. + * @param pskPassphrase The (optional) passphrase to be used to encrypt the link. Use the + * {@link #setPmk(byte[])} to specify a PMK. * @return the current {@link Builder} builder, enabling chaining of builder * methods. */ @@ -358,9 +358,7 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements * specify a Passphrase. * @return the current {@link Builder} builder, enabling chaining of builder * methods. - * @hide */ - @SystemApi public @NonNull Builder setPmk(@NonNull byte[] pmk) { if (!WifiAwareUtils.validatePmk(pmk)) { throw new IllegalArgumentException("PMK must 32 bytes"); @@ -377,7 +375,7 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements *

      *
    • The server device must be the Publisher device! *
    • The port information can only be specified on secure links, specified using - * {@link #setPskPassphrase(String)}. + * {@link #setPskPassphrase(String)} or {@link #setPmk(byte[])}. *
    * * @param port A positive integer indicating the port to be used for communication. @@ -400,7 +398,7 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements *
      *
    • The server device must be the Publisher device! *
    • The transport protocol information can only be specified on secure links, - * specified using {@link #setPskPassphrase(String)}. + * specified using {@link #setPskPassphrase(String)} or {@link #setPmk(byte[])}. *
    * The transport protocol number is assigned by the Internet Assigned Numbers Authority * (IANA) https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml. @@ -426,7 +424,7 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}. *

    The default builder constructor will initialize a NetworkSpecifier which requests an * open (non-encrypted) link. To request an encrypted link use the - * {@link #setPskPassphrase(String)} builder method. + * {@link #setPskPassphrase(String)} or {@link #setPmk(byte[])} builder methods. * * @return A {@link NetworkSpecifier} to be used to construct * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} to pass -- cgit v1.2.3 From 68d08c6c487518652a0a48a6abffb674ebf0cb83 Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Thu, 14 Nov 2019 14:10:53 -0800 Subject: Document permission & broadcast semantics re wifi state Bug: 26347905 Test: offline-sdk-docs Change-Id: Iceca5daa229397d2e492b72eb2b825b0b42c8dd4 --- wifi/java/android/net/wifi/WifiManager.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 93960de89d89..9b1c0a5ea223 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -447,7 +447,11 @@ public class WifiManager { /** * Broadcast intent action indicating that Wi-Fi has been enabled, disabled, * enabling, disabling, or unknown. One extra provides this state as an int. - * Another extra provides the previous state, if available. + * Another extra provides the previous state, if available. No network-related + * permissions are required to subscribe to this broadcast. + * + *

    This broadcast is not delivered to manifest receivers in + * applications that target API version 26 or later. * * @see #EXTRA_WIFI_STATE * @see #EXTRA_PREVIOUS_WIFI_STATE @@ -748,7 +752,11 @@ public class WifiManager { /** * Broadcast intent action indicating that the state of Wi-Fi connectivity * has changed. An extra provides the new state - * in the form of a {@link android.net.NetworkInfo} object. + * in the form of a {@link android.net.NetworkInfo} object. No network-related + * permissions are required to subscribe to this broadcast. + * + *

    This broadcast is not delivered to manifest receivers in + * applications that target API version 26 or later. * @see #EXTRA_NETWORK_INFO */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) -- cgit v1.2.3 From a0900344f4ea850ca9ee81fc936298f894e77f54 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Fri, 15 Nov 2019 10:06:27 +0800 Subject: p2p: check the length of the network name bytes Fixes: 144472136 Bug: 144472136 Test: atest FrameworksWifiApiTests Change-Id: I80b8e0330499e6c655efb1712811891a8e8229cb --- wifi/java/android/net/wifi/p2p/WifiP2pConfig.java | 9 +++++++++ wifi/tests/src/android/net/wifi/p2p/WifiP2pConfigTest.java | 13 +++++++++++++ 2 files changed, 22 insertions(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java index c3cfb0266328..80776fe70382 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java @@ -28,6 +28,7 @@ import android.text.TextUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.nio.charset.StandardCharsets; import java.util.regex.PatternSyntaxException; /** @@ -228,6 +229,10 @@ public class WifiP2pConfig implements Parcelable { private static final MacAddress MAC_ANY_ADDRESS = MacAddress.fromString("02:00:00:00:00:00"); + /** + * Maximum number of bytes allowed for a SSID. + */ + private static final int MAX_SSID_BYTES = 32; private MacAddress mDeviceAddress = MAC_ANY_ADDRESS; private String mNetworkName = ""; @@ -279,6 +284,10 @@ public class WifiP2pConfig implements Parcelable { throw new IllegalArgumentException( "network name must be non-empty."); } + if (networkName.getBytes(StandardCharsets.UTF_8).length > MAX_SSID_BYTES) { + throw new IllegalArgumentException( + "network name exceeds " + MAX_SSID_BYTES + " bytes."); + } try { if (!networkName.matches("^DIRECT-[a-zA-Z0-9]{2}.*")) { throw new IllegalArgumentException( diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pConfigTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pConfigTest.java index 41f109a63759..61993252c05e 100644 --- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pConfigTest.java +++ b/wifi/tests/src/android/net/wifi/p2p/WifiP2pConfigTest.java @@ -53,6 +53,13 @@ public class WifiP2pConfigTest { fail("Unexpected IllegalArgumentException"); } + // sunny case with maximum bytes for the network name + try { + b.setNetworkName("DIRECT-abcdefghijklmnopqrstuvwxy"); + } catch (IllegalArgumentException e) { + fail("Unexpected IllegalArgumentException"); + } + // less than 9 characters. try { b.setNetworkName("DIRECT-z"); @@ -77,6 +84,12 @@ public class WifiP2pConfigTest { b.setNetworkName("direct-a?"); fail("expected IllegalArgumentException"); } catch (IllegalArgumentException e) { } + + // over maximum bytes + try { + b.setNetworkName("DIRECT-abcdefghijklmnopqrstuvwxyz"); + fail("expected IllegalArgumentException"); + } catch (IllegalArgumentException e) { } } /** -- cgit v1.2.3 From c67d4f750e12acbf4c7ff46fbd5130f4c7056e03 Mon Sep 17 00:00:00 2001 From: Ahmed ElArabawy Date: Thu, 7 Nov 2019 10:13:56 -0800 Subject: Wifi: Support check on device capability for 6GHZ This commit implements support of checking whether device supports 6GHz band. Bug: 139354972 Test: atest com.android.wifi.server Change-Id: Id2c1ef085bb680b9d59ce1788147b154efc4b422 --- wifi/java/android/net/wifi/WifiManager.java | 11 +++++++++++ wifi/tests/src/android/net/wifi/WifiManagerTest.java | 1 + 2 files changed, 12 insertions(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 93960de89d89..84327e867c9b 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -2257,6 +2257,8 @@ public class WifiManager { public static final long WIFI_FEATURE_MBO = 0x800000000L; // MBO Support /** @hide */ public static final long WIFI_FEATURE_OCE = 0x1000000000L; // OCE Support + /** @hide */ + public static final long WIFI_FEATURE_INFRA_6G = 0x2000000000L; // Support 6 GHz band private long getSupportedFeatures() { try { @@ -2271,6 +2273,7 @@ public class WifiManager { private boolean isFeatureSupported(long feature) { return (getSupportedFeatures() & feature) == feature; } + /** * @return true if this adapter supports 5 GHz band */ @@ -2278,6 +2281,14 @@ public class WifiManager { return isFeatureSupported(WIFI_FEATURE_INFRA_5G); } + /** + * @return true if the device supports operating in the 6 GHz band and Wi-Fi is enabled, + * false otherwise. + */ + public boolean is6GHzBandSupported() { + return isFeatureSupported(WIFI_FEATURE_INFRA_6G); + } + /** * @return true if this adapter supports Passpoint * @hide diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 17f3bb2b130b..305149f44d1c 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -1586,6 +1586,7 @@ public class WifiManagerTest { assertTrue(mWifiManager.isP2pSupported()); assertFalse(mWifiManager.isPortableHotspotSupported()); assertFalse(mWifiManager.is5GHzBandSupported()); + assertFalse(mWifiManager.is6GHzBandSupported()); assertFalse(mWifiManager.isDeviceToDeviceRttSupported()); assertFalse(mWifiManager.isDeviceToApRttSupported()); assertFalse(mWifiManager.isPreferredNetworkOffloadSupported()); -- cgit v1.2.3 From b73c737ffc872630916c83e6a14f25aca62d6845 Mon Sep 17 00:00:00 2001 From: David Su Date: Fri, 25 Oct 2019 11:22:41 -0700 Subject: Expose Wifi P2P @hide APIs as @SystemApi These APIs are mostly used by Settings. Bug: 143892817 Test: atest FrameworksWifiApiTests Change-Id: I27061280b0c49677fa651c6f9799e48b78e4c109 --- wifi/java/android/net/wifi/p2p/WifiP2pConfig.java | 38 +++-- wifi/java/android/net/wifi/p2p/WifiP2pDevice.java | 17 ++- wifi/java/android/net/wifi/p2p/WifiP2pGroup.java | 31 +++-- .../android/net/wifi/p2p/WifiP2pGroupList.java | 25 ++-- wifi/java/android/net/wifi/p2p/WifiP2pManager.java | 155 +++++++++++++++++---- wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java | 149 +++++++++++--------- .../android/net/wifi/p2p/WifiP2pWfdInfoTest.java | 14 +- 7 files changed, 291 insertions(+), 138 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java index c3cfb0266328..767055fe6e29 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java @@ -65,12 +65,6 @@ public class WifiP2pConfig implements Parcelable { /** @hide */ public int groupOwnerBand = GROUP_OWNER_BAND_AUTO; - /** @hide */ - public static final int MAX_GROUP_OWNER_INTENT = 15; - /** @hide */ - @UnsupportedAppUsage - public static final int MIN_GROUP_OWNER_INTENT = 0; - /** @hide */ @IntDef(flag = false, prefix = { "GROUP_OWNER_BAND_" }, value = { GROUP_OWNER_BAND_AUTO, @@ -94,13 +88,35 @@ public class WifiP2pConfig implements Parcelable { public static final int GROUP_OWNER_BAND_5GHZ = 2; /** - * This is an integer value between 0 and 15 where 0 indicates the least - * inclination to be a group owner and 15 indicates the highest inclination - * to be a group owner. + * The least inclination to be a group owner, to be filled in the field + * {@link #groupOwnerIntent}. + */ + public static final int GROUP_OWNER_INTENT_MIN = 0; + + /** + * The most inclination to be a group owner, to be filled in the field + * {@link #groupOwnerIntent}. + */ + public static final int GROUP_OWNER_INTENT_MAX = 15; + + /** + * The system can choose an appropriate owner intent value, to be filled in the field + * {@link #groupOwnerIntent}. + */ + public static final int GROUP_OWNER_INTENT_AUTO = -1; + + /** + * This is an integer value between {@link #GROUP_OWNER_INTENT_MIN} and + * {@link #GROUP_OWNER_INTENT_MAX} where + * {@link #GROUP_OWNER_INTENT_MIN} indicates the least inclination to be a group owner and + * {@link #GROUP_OWNER_INTENT_MAX} indicates the highest inclination to be a group owner. + * + * A value of {@link #GROUP_OWNER_INTENT_AUTO} indicates the system can choose an appropriate + * value. * - * A value of -1 indicates the system can choose an appropriate value. + * By default this field is set to {@link #GROUP_OWNER_INTENT_AUTO}. */ - public int groupOwnerIntent = -1; + public int groupOwnerIntent = GROUP_OWNER_INTENT_AUTO; /** @hide */ @UnsupportedAppUsage diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java index c5318a9e275a..13b25209990e 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java @@ -16,6 +16,8 @@ package android.net.wifi.p2p; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; @@ -237,6 +239,12 @@ public class WifiP2pDevice implements Parcelable { } } + /** The Wifi Display information for this device, or null if unavailable. */ + @Nullable + public WifiP2pWfdInfo getWfdInfo() { + return wfdInfo; + } + /** Returns true if WPS push button configuration is supported */ public boolean wpsPbcSupported() { return (wpsConfigMethodsSupported & WPS_CONFIG_PUSHBUTTON) != 0; @@ -278,14 +286,15 @@ public class WifiP2pDevice implements Parcelable { } /** - * Update device details. This will be throw an exception if the device address - * does not match. + * Update device details. This will throw an exception if the device address does not match. + * * @param device to be updated - * @throws IllegalArgumentException if the device is null or device address does not match + * @throws IllegalArgumentException if the device is null or the device address does not match + * * @hide */ @UnsupportedAppUsage - public void update(WifiP2pDevice device) { + public void update(@NonNull WifiP2pDevice device) { updateSupplicantDetails(device); status = device.status; } diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java index 4866bd4b2ce9..f9d1266cf804 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java @@ -16,6 +16,7 @@ package android.net.wifi.p2p; +import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; @@ -36,15 +37,21 @@ import java.util.regex.Pattern; */ public class WifiP2pGroup implements Parcelable { - /** The temporary network id. - * {@hide} */ + /** + * The temporary network id. + * + * @hide + */ @UnsupportedAppUsage public static final int TEMPORARY_NET_ID = -1; - /** The persistent network id. + /** + * The persistent network id. * If a matching persistent profile is found, use it. * Otherwise, create a new persistent profile. - * {@hide} */ + * + * @hide + */ public static final int PERSISTENT_NET_ID = -2; /** The network name */ @@ -64,7 +71,7 @@ public class WifiP2pGroup implements Parcelable { private String mInterface; - /** The network id in the wpa_supplicant */ + /** The network ID in wpa_supplicant */ private int mNetId; /** The frequency (in MHz) used by this group */ @@ -225,10 +232,13 @@ public class WifiP2pGroup implements Parcelable { return mClients.size() == 0; } - /** @hide Returns {@code true} if the device is part of the group */ - public boolean contains(WifiP2pDevice device) { - if (mOwner.equals(device) || mClients.contains(device)) return true; - return false; + /** + * Returns {@code true} if the device is part of the group, {@code false} otherwise. + * + * @hide + */ + public boolean contains(@Nullable WifiP2pDevice device) { + return mOwner.equals(device) || mClients.contains(device); } /** Get the list of clients currently part of the p2p group */ @@ -261,8 +271,7 @@ public class WifiP2pGroup implements Parcelable { return mInterface; } - /** @hide */ - @UnsupportedAppUsage + /** The network ID of the P2P group in wpa_supplicant. */ public int getNetworkId() { return mNetId; } diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java index 62524d9c2bd6..10fd09aa638f 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java @@ -15,14 +15,16 @@ */ package android.net.wifi.p2p; -import java.util.Collection; -import java.util.Map; - +import android.annotation.NonNull; +import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.util.LruCache; +import java.util.Collection; +import java.util.Map; + /** * A class representing a Wi-Fi P2p group list @@ -30,7 +32,8 @@ import android.util.LruCache; * {@see WifiP2pManager} * @hide */ -public class WifiP2pGroupList implements Parcelable { +@SystemApi +public final class WifiP2pGroupList implements Parcelable { private static final int CREDENTIAL_MAX_NUM = 32; @@ -40,6 +43,7 @@ public class WifiP2pGroupList implements Parcelable { private boolean isClearCalled = false; + /** @hide */ public interface GroupDeleteListener { public void onDeleteGroup(int netId); } @@ -71,11 +75,9 @@ public class WifiP2pGroupList implements Parcelable { } /** - * Return the list of p2p group. - * - * @return the list of p2p group. + * Get the list of P2P groups. */ - @UnsupportedAppUsage + @NonNull public Collection getGroupList() { return mGroups.snapshot().values(); } @@ -206,6 +208,7 @@ public class WifiP2pGroupList implements Parcelable { return false; } + @Override public String toString() { StringBuffer sbuf = new StringBuffer(); @@ -217,12 +220,14 @@ public class WifiP2pGroupList implements Parcelable { } /** Implement the Parcelable interface */ + @Override public int describeContents() { return 0; } /** Implement the Parcelable interface */ - public void writeToParcel(Parcel dest, int flags) { + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { final Collection groups = mGroups.snapshot().values(); dest.writeInt(groups.size()); for(WifiP2pGroup group : groups) { @@ -231,7 +236,7 @@ public class WifiP2pGroupList implements Parcelable { } /** Implement the Parcelable interface */ - public static final @android.annotation.NonNull Creator CREATOR = + public static final @NonNull Creator CREATOR = new Creator() { public WifiP2pGroupList createFromParcel(Parcel in) { WifiP2pGroupList grpList = new WifiP2pGroupList(); diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java index 3178519a6739..1c2067980a79 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java @@ -22,6 +22,7 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; +import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.UnsupportedAppUsage; import android.content.Context; @@ -327,8 +328,9 @@ public class WifiP2pManager { * Broadcast intent action indicating that remembered persistent groups have changed. * @hide */ - public static final String WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION = - "android.net.wifi.p2p.PERSISTENT_GROUPS_CHANGED"; + @SystemApi + public static final String ACTION_WIFI_P2P_PERSISTENT_GROUPS_CHANGED = + "android.net.wifi.p2p.action.WIFI_P2P_PERSISTENT_GROUPS_CHANGED"; /** * The lookup key for a handover message returned by the WifiP2pService. @@ -756,13 +758,18 @@ public class WifiP2pManager { } - /** Interface for callback invocation when stored group info list is available {@hide}*/ + /** + * Interface for callback invocation when stored group info list is available + * + * @hide + */ + @SystemApi public interface PersistentGroupInfoListener { /** * The requested stored p2p group info list is available * @param groups Wi-Fi p2p group info list */ - public void onPersistentGroupInfoAvailable(WifiP2pGroupList groups); + void onPersistentGroupInfoAvailable(@NonNull WifiP2pGroupList groups); } /** @@ -1202,7 +1209,7 @@ public class WifiP2pManager { c.mAsyncChannel.sendMessage(DISCOVER_PEERS, 0, c.putListener(listener)); } - /** + /** * Stop an ongoing peer discovery * *

    The function call immediately returns after sending a stop request @@ -1347,20 +1354,36 @@ public class WifiP2pManager { * * @hide */ + @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - public void listen(Channel c, boolean enable, ActionListener listener) { + public void listen(@NonNull Channel c, boolean enable, @Nullable ActionListener listener) { checkChannel(c); c.mAsyncChannel.sendMessage(enable ? START_LISTEN : STOP_LISTEN, 0, c.putListener(listener)); } - /** @hide */ - @UnsupportedAppUsage - public void setWifiP2pChannels(Channel c, int lc, int oc, ActionListener listener) { + /** + * Set P2P listening and operating channel. + * + * @param c is the channel created at {@link #initialize} + * @param listeningChannel the listening channel's Wifi channel number. e.g. 1, 6, 11. + * @param operatingChannel the operating channel's Wifi channel number. e.g. 1, 6, 11. + * @param listener for callbacks on success or failure. Can be null. + * + * @hide + */ + @SystemApi + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_SETTINGS, + android.Manifest.permission.NETWORK_STACK, + android.Manifest.permission.OVERRIDE_WIFI_CONFIG + }) + public void setWifiP2pChannels(@NonNull Channel c, int listeningChannel, int operatingChannel, + @Nullable ActionListener listener) { checkChannel(c); Bundle p2pChannels = new Bundle(); - p2pChannels.putInt("lc", lc); - p2pChannels.putInt("oc", oc); + p2pChannels.putInt("lc", listeningChannel); + p2pChannels.putInt("oc", operatingChannel); c.mAsyncChannel.sendMessage(SET_CHANNEL, 0, c.putListener(listener), p2pChannels); } @@ -1618,23 +1641,47 @@ public class WifiP2pManager { /** * Set p2p device name. - * @hide + * * @param c is the channel created at {@link #initialize} * @param listener for callback when group info is available. Can be null. + * + * @hide */ - @UnsupportedAppUsage - public void setDeviceName(Channel c, String devName, ActionListener listener) { + @SystemApi + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_SETTINGS, + android.Manifest.permission.NETWORK_STACK, + android.Manifest.permission.OVERRIDE_WIFI_CONFIG + }) + public void setDeviceName(@NonNull Channel c, @NonNull String devName, + @Nullable ActionListener listener) { checkChannel(c); WifiP2pDevice d = new WifiP2pDevice(); d.deviceName = devName; c.mAsyncChannel.sendMessage(SET_DEVICE_NAME, 0, c.putListener(listener), d); } + /** + * Set Wifi Display information. + * + * @param c is the channel created at {@link #initialize} + * @param wfdInfo the Wifi Display information to set + * @param listener for callbacks on success or failure. Can be null. + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY) + public void setWfdInfo(@NonNull Channel c, @NonNull WifiP2pWfdInfo wfdInfo, + @Nullable ActionListener listener) { + setWFDInfo(c, wfdInfo, listener); + } + /** @hide */ @UnsupportedAppUsage - public void setWFDInfo( - Channel c, WifiP2pWfdInfo wfdInfo, - ActionListener listener) { + @RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY) + public void setWFDInfo(@NonNull Channel c, @NonNull WifiP2pWfdInfo wfdInfo, + @Nullable ActionListener listener) { checkChannel(c); try { mService.checkConfigureWifiDisplayPermission(); @@ -1658,12 +1705,19 @@ public class WifiP2pManager { * a network id can be obtained by {@link WifiP2pGroup#getNetworkId()}. * * @param c is the channel created at {@link #initialize} - * @param netId he network id of the p2p group. + * @param netId the network id of the p2p group. * @param listener for callbacks on success or failure. Can be null. + * * @hide */ - @UnsupportedAppUsage - public void deletePersistentGroup(Channel c, int netId, ActionListener listener) { + @SystemApi + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_SETTINGS, + android.Manifest.permission.NETWORK_STACK, + android.Manifest.permission.OVERRIDE_WIFI_CONFIG + }) + public void deletePersistentGroup(@NonNull Channel c, int netId, + @Nullable ActionListener listener) { checkChannel(c); c.mAsyncChannel.sendMessage(DELETE_PERSISTENT_GROUP, netId, c.putListener(listener)); } @@ -1673,23 +1727,68 @@ public class WifiP2pManager { * * @param c is the channel created at {@link #initialize} * @param listener for callback when persistent group info list is available. Can be null. + * * @hide */ - @UnsupportedAppUsage - public void requestPersistentGroupInfo(Channel c, PersistentGroupInfoListener listener) { + @SystemApi + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_SETTINGS, + android.Manifest.permission.NETWORK_STACK, + android.Manifest.permission.READ_WIFI_CREDENTIAL + }) + public void requestPersistentGroupInfo(@NonNull Channel c, + @Nullable PersistentGroupInfoListener listener) { checkChannel(c); c.mAsyncChannel.sendMessage(REQUEST_PERSISTENT_GROUP_INFO, 0, c.putListener(listener)); } /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"MIRACAST_"}, value = { + MIRACAST_DISABLED, + MIRACAST_SOURCE, + MIRACAST_SINK}) + public @interface MiracastMode {} + + /** + * Miracast is disabled. + * @hide + */ + @SystemApi public static final int MIRACAST_DISABLED = 0; - /** @hide */ + /** + * Device acts as a Miracast source. + * @hide + */ + @SystemApi public static final int MIRACAST_SOURCE = 1; - /** @hide */ + /** + * Device acts as a Miracast sink. + * @hide + */ + @SystemApi public static final int MIRACAST_SINK = 2; - /** Internal use only @hide */ - @UnsupportedAppUsage - public void setMiracastMode(int mode) { + + /** + * This is used to provide information to drivers to optimize performance depending + * on the current mode of operation. + * {@link #MIRACAST_DISABLED} - disabled + * {@link #MIRACAST_SOURCE} - source operation + * {@link #MIRACAST_SINK} - sink operation + * + * As an example, the driver could reduce the channel dwell time during scanning + * when acting as a source or sink to minimize impact on Miracast. + * + * @param mode mode of operation. One of {@link #MIRACAST_DISABLED}, {@link #MIRACAST_SOURCE}, + * or {@link #MIRACAST_SINK} + * + * @hide + */ + @SystemApi + @RequiresPermission(allOf = { + android.Manifest.permission.CONNECTIVITY_INTERNAL, + android.Manifest.permission.CONFIGURE_WIFI_DISPLAY}) + public void setMiracastMode(@MiracastMode int mode) { try { mService.setMiracastMode(mode); } catch (RemoteException e) { @@ -1778,8 +1877,10 @@ public class WifiP2pManager { * * @param c is the channel created at {@link #initialize}. * @param listener for callback on success or failure. Can be null. + * * @hide */ + @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void factoryReset(@NonNull Channel c, @Nullable ActionListener listener) { checkChannel(c); diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java index 3caa280ef62a..48b07032162b 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java @@ -16,49 +16,68 @@ package android.net.wifi.p2p; +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; -import android.os.Build; -import android.os.Parcelable; import android.os.Parcel; +import android.os.Parcelable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.Locale; /** - * A class representing Wifi Display information for a device - * @hide + * A class representing Wifi Display information for a device. + * + * See Wifi Display technical specification v1.0.0, section 5.1.2. */ -public class WifiP2pWfdInfo implements Parcelable { - - private static final String TAG = "WifiP2pWfdInfo"; +public final class WifiP2pWfdInfo implements Parcelable { private boolean mWfdEnabled; + /** Device information bitmap */ private int mDeviceInfo; - public static final int WFD_SOURCE = 0; - public static final int PRIMARY_SINK = 1; - public static final int SECONDARY_SINK = 2; - public static final int SOURCE_OR_PRIMARY_SINK = 3; - - /* Device information bitmap */ - /** One of {@link #WFD_SOURCE}, {@link #PRIMARY_SINK}, {@link #SECONDARY_SINK} - * or {@link #SOURCE_OR_PRIMARY_SINK} + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = { "DEVICE_TYPE_" }, value = { + DEVICE_TYPE_WFD_SOURCE, + DEVICE_TYPE_PRIMARY_SINK, + DEVICE_TYPE_SECONDARY_SINK, + DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK}) + public @interface DeviceType {} + + /** The device is a Wifi Display Source. */ + public static final int DEVICE_TYPE_WFD_SOURCE = 0; + /** The device is a primary sink. */ + public static final int DEVICE_TYPE_PRIMARY_SINK = 1; + /** The device is a secondary sink. */ + public static final int DEVICE_TYPE_SECONDARY_SINK = 2; + /** The device is dual-role capable i.e. either a WFD source or a primary sink. */ + public static final int DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK = 3; + + /** + * {@link #mDeviceInfo} & {@link #DEVICE_TYPE} is one of {@link #DEVICE_TYPE_WFD_SOURCE}, + * {@link #DEVICE_TYPE_PRIMARY_SINK}, {@link #DEVICE_TYPE_SECONDARY_SINK} or + * {@link #DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK}. */ - private static final int DEVICE_TYPE = 0x3; - private static final int COUPLED_SINK_SUPPORT_AT_SOURCE = 0x4; - private static final int COUPLED_SINK_SUPPORT_AT_SINK = 0x8; - private static final int SESSION_AVAILABLE = 0x30; - private static final int SESSION_AVAILABLE_BIT1 = 0x10; - private static final int SESSION_AVAILABLE_BIT2 = 0x20; + private static final int DEVICE_TYPE = 1 << 1 | 1 << 0; + private static final int COUPLED_SINK_SUPPORT_AT_SOURCE = 1 << 2; + private static final int COUPLED_SINK_SUPPORT_AT_SINK = 1 << 3; + private static final int SESSION_AVAILABLE_BIT1 = 1 << 4; + private static final int SESSION_AVAILABLE_BIT2 = 1 << 5; + private static final int SESSION_AVAILABLE = + SESSION_AVAILABLE_BIT2 | SESSION_AVAILABLE_BIT1; private int mCtrlPort; private int mMaxThroughput; - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) - public WifiP2pWfdInfo() { - } + /** Default constructor. */ + public WifiP2pWfdInfo() {} + /** @hide */ @UnsupportedAppUsage public WifiP2pWfdInfo(int devInfo, int ctrlPort, int maxTput) { mWfdEnabled = true; @@ -67,24 +86,40 @@ public class WifiP2pWfdInfo implements Parcelable { mMaxThroughput = maxTput; } - @UnsupportedAppUsage + /** Returns true is Wifi Display is enabled, false otherwise. */ public boolean isWfdEnabled() { return mWfdEnabled; } - @UnsupportedAppUsage + /** + * Sets whether Wifi Display should be enabled. + * + * @param enabled true to enable Wifi Display, false to disable + */ public void setWfdEnabled(boolean enabled) { mWfdEnabled = enabled; } - @UnsupportedAppUsage + /** + * Get the type of the device. + * One of {@link #DEVICE_TYPE_WFD_SOURCE}, {@link #DEVICE_TYPE_PRIMARY_SINK}, + * {@link #DEVICE_TYPE_SECONDARY_SINK}, {@link #DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK} + */ + @DeviceType public int getDeviceType() { - return (mDeviceInfo & DEVICE_TYPE); + return mDeviceInfo & DEVICE_TYPE; } - @UnsupportedAppUsage - public boolean setDeviceType(int deviceType) { - if (deviceType >= WFD_SOURCE && deviceType <= SOURCE_OR_PRIMARY_SINK) { + /** + * Sets the type of the device. + * + * @param deviceType One of {@link #DEVICE_TYPE_WFD_SOURCE}, {@link #DEVICE_TYPE_PRIMARY_SINK}, + * {@link #DEVICE_TYPE_SECONDARY_SINK}, {@link #DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK} + * @return true if the device type was successfully set, false otherwise + */ + public boolean setDeviceType(@DeviceType int deviceType) { + if (DEVICE_TYPE_WFD_SOURCE <= deviceType + && deviceType <= DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK) { mDeviceInfo &= ~DEVICE_TYPE; mDeviceInfo |= deviceType; return true; @@ -92,35 +127,16 @@ public class WifiP2pWfdInfo implements Parcelable { return false; } - public boolean isCoupledSinkSupportedAtSource() { - return (mDeviceInfo & COUPLED_SINK_SUPPORT_AT_SINK) != 0; - } - - public void setCoupledSinkSupportAtSource(boolean enabled) { - if (enabled ) { - mDeviceInfo |= COUPLED_SINK_SUPPORT_AT_SINK; - } else { - mDeviceInfo &= ~COUPLED_SINK_SUPPORT_AT_SINK; - } - } - - public boolean isCoupledSinkSupportedAtSink() { - return (mDeviceInfo & COUPLED_SINK_SUPPORT_AT_SINK) != 0; - } - - public void setCoupledSinkSupportAtSink(boolean enabled) { - if (enabled ) { - mDeviceInfo |= COUPLED_SINK_SUPPORT_AT_SINK; - } else { - mDeviceInfo &= ~COUPLED_SINK_SUPPORT_AT_SINK; - } - } - + /** Returns true if a session is available, false otherwise. */ public boolean isSessionAvailable() { return (mDeviceInfo & SESSION_AVAILABLE) != 0; } - @UnsupportedAppUsage + /** + * Sets whether a session is available. + * + * @param enabled true to indicate that a session is available, false otherwise. + */ public void setSessionAvailable(boolean enabled) { if (enabled) { mDeviceInfo |= SESSION_AVAILABLE_BIT1; @@ -130,29 +146,33 @@ public class WifiP2pWfdInfo implements Parcelable { } } + /** Returns the TCP port at which the WFD Device listens for RTSP messages. */ public int getControlPort() { return mCtrlPort; } - @UnsupportedAppUsage + /** Sets the TCP port at which the WFD Device listens for RTSP messages. */ public void setControlPort(int port) { mCtrlPort = port; } - @UnsupportedAppUsage + /** Sets the maximum average throughput capability of the WFD Device, in megabits/second. */ public void setMaxThroughput(int maxThroughput) { mMaxThroughput = maxThroughput; } + /** Returns the maximum average throughput capability of the WFD Device, in megabits/second. */ public int getMaxThroughput() { return mMaxThroughput; } + /** @hide */ public String getDeviceInfoHex() { return String.format( Locale.US, "%04x%04x%04x", mDeviceInfo, mCtrlPort, mMaxThroughput); } + @Override public String toString() { StringBuffer sbuf = new StringBuffer(); sbuf.append("WFD enabled: ").append(mWfdEnabled); @@ -167,9 +187,8 @@ public class WifiP2pWfdInfo implements Parcelable { return 0; } - /** copy constructor */ - @UnsupportedAppUsage - public WifiP2pWfdInfo(WifiP2pWfdInfo source) { + /** Copy constructor. */ + public WifiP2pWfdInfo(@Nullable WifiP2pWfdInfo source) { if (source != null) { mWfdEnabled = source.mWfdEnabled; mDeviceInfo = source.mDeviceInfo; @@ -179,14 +198,15 @@ public class WifiP2pWfdInfo implements Parcelable { } /** Implement the Parcelable interface */ - public void writeToParcel(Parcel dest, int flags) { + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(mWfdEnabled ? 1 : 0); dest.writeInt(mDeviceInfo); dest.writeInt(mCtrlPort); dest.writeInt(mMaxThroughput); } - public void readFromParcel(Parcel in) { + private void readFromParcel(Parcel in) { mWfdEnabled = (in.readInt() == 1); mDeviceInfo = in.readInt(); mCtrlPort = in.readInt(); @@ -194,8 +214,7 @@ public class WifiP2pWfdInfo implements Parcelable { } /** Implement the Parcelable interface */ - @UnsupportedAppUsage - public static final @android.annotation.NonNull Creator CREATOR = + public static final @NonNull Creator CREATOR = new Creator() { public WifiP2pWfdInfo createFromParcel(Parcel in) { WifiP2pWfdInfo device = new WifiP2pWfdInfo(); diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java index d2f11688e4e5..cea73efc88d0 100644 --- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java +++ b/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java @@ -43,7 +43,7 @@ public class WifiP2pWfdInfoTest { @Before public void setUp() { // initialize device info flags. - mSourceInfo.setDeviceType(WifiP2pWfdInfo.WFD_SOURCE); + mSourceInfo.setDeviceType(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE); mSourceInfo.setSessionAvailable(true); } @@ -57,14 +57,8 @@ public class WifiP2pWfdInfoTest { info.setWfdEnabled(true); assertTrue(info.isWfdEnabled()); - info.setDeviceType(WifiP2pWfdInfo.WFD_SOURCE); - assertEquals(WifiP2pWfdInfo.WFD_SOURCE, info.getDeviceType()); - - info.setCoupledSinkSupportAtSource(true); - assertTrue(info.isCoupledSinkSupportedAtSource()); - - info.setCoupledSinkSupportAtSink(true); - assertTrue(info.isCoupledSinkSupportedAtSink()); + info.setDeviceType(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE); + assertEquals(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE, info.getDeviceType()); info.setSessionAvailable(true); assertTrue(info.isSessionAvailable()); @@ -75,7 +69,7 @@ public class WifiP2pWfdInfoTest { info.setMaxThroughput(TEST_MAX_TPUT); assertEquals(TEST_MAX_TPUT, info.getMaxThroughput()); - assertEquals("0018270f0400", info.getDeviceInfoHex()); + assertEquals("0010270f0400", info.getDeviceInfoHex()); } /** -- cgit v1.2.3 From 6720b42879b8e102730d87537585d4a61c2d83fa Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Wed, 13 Nov 2019 19:02:05 -0800 Subject: [WPA3] Fix WPA3-Personal transition mode Fix WPA3-Personal in transition mode issues. Current solution will create an upgraded WPA3 connection if there is a WPA2 saved network and AP is in transition mode. Bug: 143843364 Test: Manual tests Test: atest com.android.server.wifi Change-Id: I53b278e846828198fb1953b075d86e16fac6d795 --- wifi/java/android/net/wifi/WifiConfiguration.java | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 90343d4798a7..f7d2b40e1ea0 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -384,12 +384,7 @@ public class WifiConfiguration implements Parcelable { public void setSecurityParams(@SecurityType int securityType) { // Clear all the bitsets. allowedKeyManagement.clear(); - allowedProtocols.clear(); allowedAuthAlgorithms.clear(); - allowedPairwiseCiphers.clear(); - allowedGroupCiphers.clear(); - allowedGroupManagementCiphers.clear(); - allowedSuiteBCiphers.clear(); switch (securityType) { case SECURITY_TYPE_OPEN: @@ -412,6 +407,9 @@ public class WifiConfiguration implements Parcelable { requirePMF = true; break; case SECURITY_TYPE_EAP_SUITE_B: + allowedGroupCiphers.clear(); + allowedGroupManagementCiphers.clear(); + allowedSuiteBCiphers.clear(); allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SUITE_B_192); allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256); allowedGroupManagementCiphers.set(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256); @@ -946,6 +944,12 @@ public class WifiConfiguration implements Parcelable { */ public int meteredOverride = METERED_OVERRIDE_NONE; + /** + * This Wifi configuration is a clone of another network with lower security + * @hide + */ + public String clonedNetworkConfigKey; + /** * Blend together all the various opinions to decide if the given network * should be considered metered or not. @@ -1804,6 +1808,7 @@ public class WifiConfiguration implements Parcelable { shared = true; dtimInterval = 0; mRandomizedMacAddress = MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS); + clonedNetworkConfigKey = null; } /** @@ -2371,6 +2376,7 @@ public class WifiConfiguration implements Parcelable { /** copy constructor {@hide} */ @UnsupportedAppUsage + public WifiConfiguration(WifiConfiguration source) { if (source != null) { networkId = source.networkId; @@ -2454,6 +2460,7 @@ public class WifiConfiguration implements Parcelable { requirePMF = source.requirePMF; updateIdentifier = source.updateIdentifier; carrierId = source.carrierId; + clonedNetworkConfigKey = source.clonedNetworkConfigKey; } } @@ -2529,6 +2536,7 @@ public class WifiConfiguration implements Parcelable { dest.writeInt(osu ? 1 : 0); dest.writeLong(randomizedMacExpirationTimeMs); dest.writeInt(carrierId); + dest.writeString(clonedNetworkConfigKey); } /** Implement the Parcelable interface {@hide} */ @@ -2606,6 +2614,7 @@ public class WifiConfiguration implements Parcelable { config.osu = in.readInt() != 0; config.randomizedMacExpirationTimeMs = in.readLong(); config.carrierId = in.readInt(); + config.clonedNetworkConfigKey = in.readString(); return config; } -- cgit v1.2.3 From f7ef955d9061aab091af1dd0873c4a35fa470e19 Mon Sep 17 00:00:00 2001 From: David Su Date: Tue, 5 Nov 2019 13:44:12 -0800 Subject: WifiManager/Scanner: Expose @hide APIs as @SystemApi Expose @hide APIs in WifiManager/WifiScanner as @SystemApi so that they can be referenced by external callers (mostly Settings). Bug: 143970861 Test: atest FrameworksWifiApiTests Change-Id: I956290e2a3aca3f4946da52d7e271082824dd06c --- wifi/java/android/net/wifi/WifiManager.java | 365 ++++++++++++++------- wifi/java/android/net/wifi/WifiScanner.java | 5 +- .../src/android/net/wifi/WifiManagerTest.java | 48 ++- 3 files changed, 284 insertions(+), 134 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index a61a5afc310e..8482b069616d 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -380,14 +380,6 @@ public class WifiManager { * @hide */ public static final String EXTRA_DELAY = "android.net.wifi.extra.DELAY"; - /** - * String representation of an URL. - * - * Retrieve with {@link android.content.Intent#getStringExtra(String)}. - * - * @hide - */ - public static final String EXTRA_URL = "android.net.wifi.extra.URL"; /** * Broadcast intent action indicating a Passpoint subscription remediation frame has been @@ -420,30 +412,41 @@ public class WifiManager { "android.net.wifi.extra.SUBSCRIPTION_REMEDIATION_METHOD"; /** - * Activity Action: lunch OSU (Online Sign Up) view. + * Activity Action: Receiver should launch Passpoint OSU (Online Sign Up) view. * Included extras: * * {@link #EXTRA_OSU_NETWORK}: {@link Network} instance associated with OSU AP. * {@link #EXTRA_URL}: String representation of a server URL used for OSU process. * - *

    Note: The broadcast is only delivered to registered receivers - no manifest registered - * components will be launched. - * * @hide */ + @SystemApi @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_PASSPOINT_LAUNCH_OSU_VIEW = "android.net.wifi.action.PASSPOINT_LAUNCH_OSU_VIEW"; /** - * The lookup key for a {@link android.net.Network} associated with OSU server. + * The lookup key for a {@link android.net.Network} associated with a Passpoint OSU server. + * Included in the {@link #ACTION_PASSPOINT_LAUNCH_OSU_VIEW} broadcast. * * Retrieve with {@link android.content.Intent#getParcelableExtra(String)}. * * @hide */ + @SystemApi public static final String EXTRA_OSU_NETWORK = "android.net.wifi.extra.OSU_NETWORK"; + /** + * String representation of an URL for Passpoint OSU. + * Included in the {@link #ACTION_PASSPOINT_LAUNCH_OSU_VIEW} broadcast. + * + * Retrieve with {@link android.content.Intent#getStringExtra(String)}. + * + * @hide + */ + @SystemApi + public static final String EXTRA_URL = "android.net.wifi.extra.URL"; + /** * Broadcast intent action indicating that Wi-Fi has been enabled, disabled, * enabling, disabling, or unknown. One extra provides this state as an int. @@ -656,6 +659,7 @@ public class WifiManager { * * @hide */ + @SystemApi public static final int SAP_START_FAILURE_GENERAL= 0; /** @@ -664,6 +668,7 @@ public class WifiManager { * * @hide */ + @SystemApi public static final int SAP_START_FAILURE_NO_CHANNEL = 1; /** @hide */ @@ -917,7 +922,7 @@ public class WifiManager { * The RSSI (signal strength) has changed. * * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE - * @see {@link #EXTRA_NEW_RSSI} + * @see #EXTRA_NEW_RSSI */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String RSSI_CHANGED_ACTION = "android.net.wifi.RSSI_CHANGED"; @@ -927,21 +932,37 @@ public class WifiManager { public static final String EXTRA_NEW_RSSI = "newRssi"; /** - * Broadcast intent action indicating that the link configuration - * changed on wifi. + * @see #ACTION_LINK_CONFIGURATION_CHANGED * @hide */ @UnsupportedAppUsage public static final String LINK_CONFIGURATION_CHANGED_ACTION = - "android.net.wifi.LINK_CONFIGURATION_CHANGED"; + "android.net.wifi.LINK_CONFIGURATION_CHANGED"; + + /** + * Broadcast intent action indicating that the link configuration changed on wifi. + *
    Included Extras: + *
    {@link #EXTRA_LINK_PROPERTIES}: {@link android.net.LinkProperties} object associated + * with the Wi-Fi network. + *
    No permissions are required to listen to this broadcast. + * @hide + */ + @SystemApi + public static final String ACTION_LINK_CONFIGURATION_CHANGED = + // should be android.net.wifi.action.LINK_CONFIGURATION_CHANGED, but due to + // @UnsupportedAppUsage leaving it as android.net.wifi.LINK_CONFIGURATION_CHANGED. + LINK_CONFIGURATION_CHANGED_ACTION; /** * The lookup key for a {@link android.net.LinkProperties} object associated with the - * Wi-Fi network. Retrieve with - * {@link android.content.Intent#getParcelableExtra(String)}. + * Wi-Fi network. + * Included in the {@link #ACTION_LINK_CONFIGURATION_CHANGED} broadcast. + * + * Retrieve with {@link android.content.Intent#getParcelableExtra(String)}. * @hide */ - public static final String EXTRA_LINK_PROPERTIES = "linkProperties"; + @SystemApi + public static final String EXTRA_LINK_PROPERTIES = "android.net.wifi.extra.LINK_PROPERTIES"; /** * The lookup key for a {@link android.net.NetworkCapabilities} object associated with the @@ -981,24 +1002,26 @@ public class WifiManager { public static final String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK"; /** - * Activity Action: Show UI to get user approval to enable WiFi. + * Activity Action: Receiver should show UI to get user approval to enable WiFi. *

    Input: {@link android.content.Intent#EXTRA_PACKAGE_NAME} string extra with * the name of the app requesting the action. *

    Output: Nothing. - * + *

    No permissions are required to send this action. * @hide */ + @SystemApi @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_REQUEST_ENABLE = "android.net.wifi.action.REQUEST_ENABLE"; /** - * Activity Action: Show UI to get user approval to disable WiFi. + * Activity Action: Receiver should show UI to get user approval to disable WiFi. *

    Input: {@link android.content.Intent#EXTRA_PACKAGE_NAME} string extra with * the name of the app requesting the action. *

    Output: Nothing. - * + *

    No permissions are required to send this action. * @hide */ + @SystemApi @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_REQUEST_DISABLE = "android.net.wifi.action.REQUEST_DISABLE"; @@ -1115,11 +1138,15 @@ public class WifiManager { private static final int MAX_RSSI = -55; /** - * Number of RSSI levels used in the framework to initiate - * {@link #RSSI_CHANGED_ACTION} broadcast + * Number of RSSI levels used in the framework to initiate {@link #RSSI_CHANGED_ACTION} + * broadcast, where each level corresponds to a range of RSSI values. + * The {@link #RSSI_CHANGED_ACTION} broadcast will only fire if the RSSI + * change is significant enough to change the RSSI signal level. * @hide */ @UnsupportedAppUsage + // TODO(b/140781184): need to support custom number of RSSI levels, as well as levels that are + // not evenly spaced public static final int RSSI_LEVELS = 5; /** @@ -1147,7 +1174,8 @@ public class WifiManager { /** @hide */ public static final boolean DEFAULT_POOR_NETWORK_AVOIDANCE_ENABLED = false; - /* Maximum number of active locks we allow. + /** + * Maximum number of active locks we allow. * This limit was added to prevent apps from creating a ridiculous number * of locks and crashing the system by overflowing the global ref table. */ @@ -1487,40 +1515,43 @@ public class WifiManager { * {@link #reject()} to return the user's selection back to the platform via this callback. * @hide */ + @SystemApi public interface NetworkRequestUserSelectionCallback { /** * User selected this network to connect to. * @param wifiConfiguration WifiConfiguration object corresponding to the network * user selected. */ - void select(@NonNull WifiConfiguration wifiConfiguration); + default void select(@NonNull WifiConfiguration wifiConfiguration) {} /** * User rejected the app's request. */ - void reject(); + default void reject() {} } /** * Interface for network request callback. Should be implemented by applications and passed when - * calling {@link #registerNetworkRequestMatchCallback(NetworkRequestMatchCallback, Handler)}. + * calling {@link #registerNetworkRequestMatchCallback(Executor, + * WifiManager.NetworkRequestMatchCallback)}. * * This is meant to be implemented by a UI component to present the user with a list of networks * matching the app's request. The user is allowed to pick one of these networks to connect to * or reject the request by the app. * @hide */ + @SystemApi public interface NetworkRequestMatchCallback { /** * Invoked to register a callback to be invoked to convey user selection. The callback - * object paased in this method is to be invoked by the UI component after the service sends + * object passed in this method is to be invoked by the UI component after the service sends * a list of matching scan networks using {@link #onMatch(List)} and user picks a network * from that list. * * @param userSelectionCallback Callback object to send back the user selection. */ - void onUserSelectionCallbackRegistration( - @NonNull NetworkRequestUserSelectionCallback userSelectionCallback); + default void onUserSelectionCallbackRegistration( + @NonNull NetworkRequestUserSelectionCallback userSelectionCallback) {} /** * Invoked when the active network request is aborted, either because @@ -1529,7 +1560,7 @@ public class WifiManager { * This signals the end of processing for the current request and should stop the UI * component. No subsequent calls from the UI component will be handled by the platform. */ - void onAbort(); + default void onAbort() {} /** * Invoked when a network request initiated by an app matches some networks in scan results. @@ -1539,7 +1570,7 @@ public class WifiManager { * @param scanResults List of {@link ScanResult} objects corresponding to the networks * matching the request. */ - void onMatch(@NonNull List scanResults); + default void onMatch(@NonNull List scanResults) {} /** * Invoked on a successful connection with the network that the user selected @@ -1548,7 +1579,7 @@ public class WifiManager { * @param wifiConfiguration WifiConfiguration object corresponding to the network that the * user selected. */ - void onUserSelectionConnectSuccess(@NonNull WifiConfiguration wifiConfiguration); + default void onUserSelectionConnectSuccess(@NonNull WifiConfiguration wifiConfiguration) {} /** * Invoked on failure to establish connection with the network that the user selected @@ -1557,7 +1588,7 @@ public class WifiManager { * @param wifiConfiguration WifiConfiguration object corresponding to the network * user selected. */ - void onUserSelectionConnectFailure(@NonNull WifiConfiguration wifiConfiguration); + default void onUserSelectionConnectFailure(@NonNull WifiConfiguration wifiConfiguration) {} } /** @@ -1606,11 +1637,11 @@ public class WifiManager { * @hide */ private class NetworkRequestMatchCallbackProxy extends INetworkRequestMatchCallback.Stub { - private final Handler mHandler; + private final Executor mExecutor; private final NetworkRequestMatchCallback mCallback; - NetworkRequestMatchCallbackProxy(Looper looper, NetworkRequestMatchCallback callback) { - mHandler = new Handler(looper); + NetworkRequestMatchCallbackProxy(Executor executor, NetworkRequestMatchCallback callback) { + mExecutor = executor; mCallback = callback; } @@ -1621,7 +1652,8 @@ public class WifiManager { Log.v(TAG, "NetworkRequestMatchCallbackProxy: " + "onUserSelectionCallbackRegistration callback: " + userSelectionCallback); } - mHandler.post(() -> { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> { mCallback.onUserSelectionCallbackRegistration( new NetworkRequestUserSelectionCallbackProxy(userSelectionCallback)); }); @@ -1632,7 +1664,8 @@ public class WifiManager { if (mVerboseLoggingEnabled) { Log.v(TAG, "NetworkRequestMatchCallbackProxy: onAbort"); } - mHandler.post(() -> { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> { mCallback.onAbort(); }); } @@ -1643,7 +1676,8 @@ public class WifiManager { Log.v(TAG, "NetworkRequestMatchCallbackProxy: onMatch scanResults: " + scanResults); } - mHandler.post(() -> { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> { mCallback.onMatch(scanResults); }); } @@ -1654,7 +1688,8 @@ public class WifiManager { Log.v(TAG, "NetworkRequestMatchCallbackProxy: onUserSelectionConnectSuccess " + " wificonfiguration: " + wifiConfiguration); } - mHandler.post(() -> { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> { mCallback.onUserSelectionConnectSuccess(wifiConfiguration); }); } @@ -1665,12 +1700,25 @@ public class WifiManager { Log.v(TAG, "NetworkRequestMatchCallbackProxy: onUserSelectionConnectFailure" + " wificonfiguration: " + wifiConfiguration); } - mHandler.post(() -> { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> { mCallback.onUserSelectionConnectFailure(wifiConfiguration); }); } } + /** + * Same as {@link #registerNetworkRequestMatchCallback(Executor, NetworkRequestMatchCallback)}, + * except that the callback will be executed on the application's main thread. + * @param callback Callback for network match events to register. + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) + public void registerNetworkRequestMatchCallback(@NonNull NetworkRequestMatchCallback callback) { + registerNetworkRequestMatchCallback(mContext.getMainExecutor(), callback); + } + /** * Registers a callback for NetworkRequest matches. See {@link NetworkRequestMatchCallback}. * Caller can unregister a previously registered callback using @@ -1681,19 +1729,20 @@ public class WifiManager { * without the permission will trigger a {@link java.lang.SecurityException}. *

    * - * @param callback Callback for network match events - * @param handler The Handler on whose thread to execute the callbacks of the {@code callback} - * object. If null, then the application's main thread will be used. + * @param executor The Executor on whose thread to execute the callbacks of the {@code callback} + * object. + * @param callback Callback for network match events to register. * @hide */ + @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - public void registerNetworkRequestMatchCallback(@NonNull NetworkRequestMatchCallback callback, - @Nullable Handler handler) { + public void registerNetworkRequestMatchCallback(@NonNull @CallbackExecutor Executor executor, + @NonNull NetworkRequestMatchCallback callback) { + if (executor == null) throw new IllegalArgumentException("executor cannot be null"); if (callback == null) throw new IllegalArgumentException("callback cannot be null"); Log.v(TAG, "registerNetworkRequestMatchCallback: callback=" + callback - + ", handler=" + handler); + + ", executor=" + executor); - Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper(); Binder binder = new Binder(); try { IWifiManager iWifiManager = getIWifiManager(); @@ -1701,7 +1750,7 @@ public class WifiManager { throw new RemoteException("Wifi service is not running"); } iWifiManager.registerNetworkRequestMatchCallback( - binder, new NetworkRequestMatchCallbackProxy(looper, callback), + binder, new NetworkRequestMatchCallbackProxy(executor, callback), callback.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -1716,9 +1765,10 @@ public class WifiManager { * without the permission will trigger a {@link java.lang.SecurityException}. *

    * - * @param callback Callback for network match events + * @param callback Callback for network match events to unregister. * @hide */ + @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void unregisterNetworkRequestMatchCallback( @NonNull NetworkRequestMatchCallback callback) { @@ -2561,29 +2611,30 @@ public class WifiManager { } /** - * get the country code. - * @return the country code in ISO 3166 format. - * - * @hide - */ - @UnsupportedAppUsage + * Get the country code. + * @return the country code in ISO 3166 format, or null if there is no country code configured. + * @hide + */ + @Nullable + @SystemApi + @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL) public String getCountryCode() { try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) return null; - String country = iWifiManager.getCountryCode(); - return country; + return iWifiManager.getCountryCode(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** - * Check if the chipset supports dual frequency band (2.4 GHz and 5 GHz) + * Check if the chipset supports dual frequency band (2.4 GHz and 5 GHz). + * No permissions are required to call this method. * @return {@code true} if supported, {@code false} otherwise. * @hide */ - @UnsupportedAppUsage + @SystemApi public boolean isDualBandSupported() { try { IWifiManager iWifiManager = getIWifiManager(); @@ -2595,10 +2646,20 @@ public class WifiManager { } /** - * Check if the chipset requires conversion of 5GHz Only apBand to ANY. - * @return {@code true} if required, {@code false} otherwise. + * Check if the device is dual mode capable i.e. supports concurrent STA + Soft AP. + * + * If the device is dual mode capable, it may require conversion of the user's Soft AP band + * selection {@link WifiConfiguration#apBand} from {@link WifiConfiguration#AP_BAND_5GHZ} to + * {@link WifiConfiguration#AP_BAND_ANY}, since if the device is connected to a 5GHz DFS + * channel as a STA, it may be unable to honor a request to start Soft AP on the same DFS + * channel. + * + * @return {@code true} if dual mode STA + AP is supported by this device, {@code false} + * otherwise. * @hide */ + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public boolean isDualModeSupported() { try { IWifiManager iWifiManager = getIWifiManager(); @@ -2685,6 +2746,7 @@ public class WifiManager { * * @hide for CTS test only */ + // TODO(b/144036594): add @TestApi public void getTxPacketCount(@NonNull TxPacketCountListener listener) { if (listener == null) throw new IllegalArgumentException("listener cannot be null"); Binder binder = new Binder(); @@ -3134,10 +3196,12 @@ public class WifiManager { } /** - * Method that triggers a notification to the user about a conversion to their saved AP config. + * Method that triggers a notification to the user about a band conversion + * (e.g. 5 GHz to 2.4 GHz) to their saved AP config. * * @hide */ + // TODO(b/144218444): move the notification to Settings instead of making this @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void notifyUserOfApBandConversion() { Log.d(TAG, "apBand was converted, notify the user"); @@ -3371,22 +3435,21 @@ public class WifiManager { /** * Called when soft AP state changes. * - * @param state new new AP state. One of {@link #WIFI_AP_STATE_DISABLED}, + * @param state the new AP state. One of {@link #WIFI_AP_STATE_DISABLED}, * {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED}, * {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED} * @param failureReason reason when in failed state. One of * {@link #SAP_START_FAILURE_GENERAL}, * {@link #SAP_START_FAILURE_NO_CHANNEL} */ - void onStateChanged(@WifiApState int state, - @SapStartFailure int failureReason); + default void onStateChanged(@WifiApState int state, @SapStartFailure int failureReason) {} /** * Called when the connected clients to soft AP changes. * * @param clients the currently connected clients */ - void onConnectedClientsChanged(@NonNull List clients); + default void onConnectedClientsChanged(@NonNull List clients) {} /** * Called when information of softap changes. @@ -3451,32 +3514,43 @@ public class WifiManager { } } + /** + * Same as {@link #registerSoftApCallback(Executor, SoftApCallback)}, + * except that the callback will be executed on the application's main thread. + * @param callback Callback for soft AP events + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) + public void registerSoftApCallback(@NonNull SoftApCallback callback) { + registerSoftApCallback(mContext.getMainExecutor(), callback); + } + /** * Registers a callback for Soft AP. See {@link SoftApCallback}. Caller will receive the current * soft AP state and number of connected devices immediately after a successful call to this API * via callback. Note that receiving an immediate WIFI_AP_STATE_FAILED value for soft AP state * indicates that the latest attempt to start soft AP has failed. Caller can unregister a - * previously registered callback using {@link unregisterSoftApCallback} + * previously registered callback using {@link #unregisterSoftApCallback} *

    * Applications should have the * {@link android.Manifest.permission#NETWORK_SETTINGS NETWORK_SETTINGS} permission. Callers * without the permission will trigger a {@link java.lang.SecurityException}. *

    * - * @param executor The executor to execute the callbacks of the {@code executor} - * object. If null, then the application's main executor will be used. + * @param executor The Executor on whose thread to execute the callbacks of the {@code callback} + * object. * @param callback Callback for soft AP events - * * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - public void registerSoftApCallback(@Nullable @CallbackExecutor Executor executor, - @NonNull SoftApCallback callback) { + public void registerSoftApCallback(@NonNull @CallbackExecutor Executor executor, + @NonNull SoftApCallback callback) { + if (executor == null) throw new IllegalArgumentException("executor cannot be null"); if (callback == null) throw new IllegalArgumentException("callback cannot be null"); Log.v(TAG, "registerSoftApCallback: callback=" + callback + ", executor=" + executor); - executor = (executor == null) ? mContext.getMainExecutor() : executor; Binder binder = new Binder(); try { IWifiManager iWifiManager = getIWifiManager(); @@ -3498,6 +3572,7 @@ public class WifiManager { * * @hide */ + @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void unregisterSoftApCallback(@NonNull SoftApCallback callback) { if (callback == null) throw new IllegalArgumentException("callback cannot be null"); @@ -4042,23 +4117,27 @@ public class WifiManager { } /** - * Disable ephemeral Network + * Disable an ephemeral network. + * + * @param ssid in the format of WifiConfiguration's SSID. * - * @param SSID, in the format of WifiConfiguration's SSID. * @hide */ + @SystemApi @RequiresPermission(anyOf = { android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK }) - public void disableEphemeralNetwork(String SSID) { - if (TextUtils.isEmpty(SSID)) throw new IllegalArgumentException("SSID cannot be null"); + public void disableEphemeralNetwork(@NonNull String ssid) { + if (TextUtils.isEmpty(ssid)) { + throw new IllegalArgumentException("SSID cannot be null or empty!"); + } try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) { throw new RemoteException("Wifi service is not running"); } - iWifiManager.disableEphemeralNetwork(SSID, mContext.getOpPackageName()); + iWifiManager.disableEphemeralNetwork(ssid, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4554,11 +4633,15 @@ public class WifiManager { } /** - * Set wifi verbose log. Called from developer settings. + * Set Wi-Fi verbose logging level from developer settings. + * + * @param verbose the verbose logging level to set. 0 will disable verbose logging, a positive + * integer will enable verbose logging. + * * @hide */ + @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - @UnsupportedAppUsage public void enableVerboseLogging (int verbose) { try { IWifiManager iWifiManager = getIWifiManager(); @@ -4574,11 +4657,15 @@ public class WifiManager { } /** - * Get the WiFi verbose logging level.This is used by settings - * to decide what to show within the picker. + * Get the persisted WiFi verbose logging level, set by {@link #enableVerboseLogging(int)}. + * No permissions are required to call this method. + * + * @return 0 to indicate that verbose logging is disabled, a positive integer to indicate that + * verbose logging is enabled. + * * @hide */ - @UnsupportedAppUsage + @SystemApi public int getVerboseLoggingLevel() { try { IWifiManager iWifiManager = getIWifiManager(); @@ -4590,10 +4677,13 @@ public class WifiManager { } /** - * Removes all saved wifi networks. + * Removes all saved Wi-Fi networks, Passpoint configurations, ephemeral networks, Network + * Requests, and Network Suggestions. * * @hide */ + @SystemApi + @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL) public void factoryReset() { try { IWifiManager iWifiManager = getIWifiManager(); @@ -4607,11 +4697,12 @@ public class WifiManager { } /** - * Get Network object of current wifi network - * @return Get Network object of current wifi network + * Get {@link Network} object of current wifi network, or null if not connected. * @hide */ - @UnsupportedAppUsage + @Nullable + @SystemApi + @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public Network getCurrentNetwork() { try { IWifiManager iWifiManager = getIWifiManager(); @@ -4660,13 +4751,18 @@ public class WifiManager { } /** - * Retrieve the data to be backed to save the current state. + * Returns a byte stream representing the data that needs to be backed up to save the + * current Wifi state. + * This Wifi state can be restored by calling {@link #restoreBackupData(byte[])}. * @hide */ + @NonNull + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public byte[] retrieveBackupData() { try { IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return null; + if (iWifiManager == null) return new byte[0]; return iWifiManager.retrieveBackupData(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -4675,9 +4771,12 @@ public class WifiManager { /** * Restore state from the backed up data. + * @param data byte stream in the same format produced by {@link #retrieveBackupData()} * @hide */ - public void restoreBackupData(byte[] data) { + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) + public void restoreBackupData(@NonNull byte[] data) { try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) { @@ -4694,11 +4793,16 @@ public class WifiManager { * Restore state from the older version of back up data. * The old backup data was essentially a backup of wpa_supplicant.conf * and ipconfig.txt file. + * @param supplicantData bytes representing wpa_supplicant.conf + * @param ipConfigData bytes representing ipconfig.txt * @deprecated this is no longer supported. * @hide */ @Deprecated - public void restoreSupplicantBackupData(byte[] supplicantData, byte[] ipConfigData) { + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) + public void restoreSupplicantBackupData( + @NonNull byte[] supplicantData, @NonNull byte[] ipConfigData) { try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) { @@ -4774,22 +4878,29 @@ public class WifiManager { } /** - * Base class for Traffic state callback. Should be extended by applications and set when - * calling {@link WifiManager#registerTrafficStateCallback(TrafficStateCallback, Handler)}. + * Interface for Traffic state callback. Should be extended by applications and set when + * calling {@link #registerTrafficStateCallback(Executor, WifiManager.TrafficStateCallback)}. * @hide */ + @SystemApi public interface TrafficStateCallback { - /** - * Lowest bit indicates data reception and the second lowest - * bit indicates data transmitted - */ /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"DATA_ACTIVITY_"}, value = { + DATA_ACTIVITY_NONE, + DATA_ACTIVITY_IN, + DATA_ACTIVITY_OUT, + DATA_ACTIVITY_INOUT}) + @interface DataActivity {} + + // Lowest bit indicates data reception and the second lowest bit indicates data transmitted + /** No data in or out */ int DATA_ACTIVITY_NONE = 0x00; - /** @hide */ + /** Data in, no data out */ int DATA_ACTIVITY_IN = 0x01; - /** @hide */ + /** Data out, no data in */ int DATA_ACTIVITY_OUT = 0x02; - /** @hide */ + /** Data in and out */ int DATA_ACTIVITY_INOUT = 0x03; /** @@ -4797,9 +4908,8 @@ public class WifiManager { * * @param state One of the values: {@link #DATA_ACTIVITY_NONE}, {@link #DATA_ACTIVITY_IN}, * {@link #DATA_ACTIVITY_OUT} & {@link #DATA_ACTIVITY_INOUT}. - * @hide */ - void onStateChanged(int state); + void onStateChanged(@DataActivity int state); } /** @@ -4808,11 +4918,11 @@ public class WifiManager { * @hide */ private class TrafficStateCallbackProxy extends ITrafficStateCallback.Stub { - private final Handler mHandler; + private final Executor mExecutor; private final TrafficStateCallback mCallback; - TrafficStateCallbackProxy(Looper looper, TrafficStateCallback callback) { - mHandler = new Handler(looper); + TrafficStateCallbackProxy(Executor executor, TrafficStateCallback callback) { + mExecutor = executor; mCallback = callback; } @@ -4821,12 +4931,25 @@ public class WifiManager { if (mVerboseLoggingEnabled) { Log.v(TAG, "TrafficStateCallbackProxy: onStateChanged state=" + state); } - mHandler.post(() -> { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> { mCallback.onStateChanged(state); }); } } + /** + * Same as {@link #registerTrafficStateCallback(Executor, TrafficStateCallback)}, + * except that the callback will be executed on the application's main thread. + * @param callback Callback for traffic state events + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) + public void registerTrafficStateCallback(@NonNull TrafficStateCallback callback) { + registerTrafficStateCallback(mContext.getMainExecutor(), callback); + } + /** * Registers a callback for monitoring traffic state. See {@link TrafficStateCallback}. These * callbacks will be invoked periodically by platform to inform clients about the current @@ -4838,18 +4961,19 @@ public class WifiManager { * without the permission will trigger a {@link java.lang.SecurityException}. *

    * + * @param executor The Executor on whose thread to execute the callbacks of the {@code callback} + * object. * @param callback Callback for traffic state events - * @param handler The Handler on whose thread to execute the callbacks of the {@code callback} - * object. If null, then the application's main thread will be used. * @hide */ + @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - public void registerTrafficStateCallback(@NonNull TrafficStateCallback callback, - @Nullable Handler handler) { + public void registerTrafficStateCallback(@NonNull @CallbackExecutor Executor executor, + @NonNull TrafficStateCallback callback) { + if (executor == null) throw new IllegalArgumentException("executor cannot be null"); if (callback == null) throw new IllegalArgumentException("callback cannot be null"); - Log.v(TAG, "registerTrafficStateCallback: callback=" + callback + ", handler=" + handler); + Log.v(TAG, "registerTrafficStateCallback: callback=" + callback + ", executor=" + executor); - Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper(); Binder binder = new Binder(); try { IWifiManager iWifiManager = getIWifiManager(); @@ -4857,7 +4981,7 @@ public class WifiManager { throw new RemoteException("Wifi service is not running"); } iWifiManager.registerTrafficStateCallback( - binder, new TrafficStateCallbackProxy(looper, callback), callback.hashCode()); + binder, new TrafficStateCallbackProxy(executor, callback), callback.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4870,6 +4994,7 @@ public class WifiManager { * @param callback Callback to unregister for traffic state events * @hide */ + @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void unregisterTrafficStateCallback(@NonNull TrafficStateCallback callback) { if (callback == null) throw new IllegalArgumentException("callback cannot be null"); @@ -4933,11 +5058,13 @@ public class WifiManager { * if failed. * @hide */ + @NonNull + @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public String[] getFactoryMacAddresses() { try { IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return null; + if (iWifiManager == null) return new String[0]; return iWifiManager.getFactoryMacAddresses(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index 7e14451332fb..0d36718f07f1 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -960,6 +960,9 @@ public class WifiScanner { * Retrieve the most recent scan results from a single scan request. * {@hide} */ + @NonNull + @SystemApi + @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public List getSingleScanResults() { validateChannel(); Bundle scanParams = new Bundle(); @@ -973,7 +976,7 @@ public class WifiScanner { OperationResult result = (OperationResult) reply.obj; Log.e(TAG, "Error retrieving SingleScan results reason: " + result.reason + " description: " + result.description); - return new ArrayList(); + return new ArrayList<>(); } private void startPnoScan(ScanSettings scanSettings, PnoSettings pnoSettings, int key) { diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 630527726964..06ebc1b3f6da 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -708,6 +708,18 @@ public class WifiManagerTest { } } + /** + * Verify an IllegalArgumentException is thrown if executor is null. + */ + @Test + public void registerSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForExecutor() { + try { + mWifiManager.registerSoftApCallback(null, mSoftApCallback); + fail("expected IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + } + } + /** * Verify an IllegalArgumentException is thrown if callback is not provided. */ @@ -724,9 +736,10 @@ public class WifiManagerTest { * Verify main looper is used when handler is not provided. */ @Test - public void registerSoftApCallbackUsesMainLooperOnNullArgumentForHandler() { - when(mContext.getMainLooper()).thenReturn(mLooper.getLooper()); - mWifiManager.registerSoftApCallback(null, mSoftApCallback); + public void registerSoftApCallbackUsesMainExecutorOnNoExecutorProvided() { + when(mContext.getMainExecutor()).thenReturn( + new HandlerExecutor(new Handler(mLooper.getLooper()))); + mWifiManager.registerSoftApCallback(mSoftApCallback); verify(mContext).getMainExecutor(); } @@ -1147,10 +1160,11 @@ public class WifiManagerTest { @Test public void registerTrafficStateCallbackUsesMainLooperOnNullArgumentForHandler() throws Exception { - when(mContext.getMainLooper()).thenReturn(mLooper.getLooper()); + when(mContext.getMainExecutor()).thenReturn( + new HandlerExecutor(new Handler(mLooper.getLooper()))); ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(ITrafficStateCallback.Stub.class); - mWifiManager.registerTrafficStateCallback(mTrafficStateCallback, null); + mWifiManager.registerTrafficStateCallback(mTrafficStateCallback); verify(mWifiService).registerTrafficStateCallback( any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -1166,7 +1180,8 @@ public class WifiManagerTest { @Test public void unregisterTrafficStateCallbackCallGoesToWifiServiceImpl() throws Exception { ArgumentCaptor callbackIdentifier = ArgumentCaptor.forClass(Integer.class); - mWifiManager.registerTrafficStateCallback(mTrafficStateCallback, mHandler); + mWifiManager.registerTrafficStateCallback(new HandlerExecutor(mHandler), + mTrafficStateCallback); verify(mWifiService).registerTrafficStateCallback(any(IBinder.class), any(ITrafficStateCallback.Stub.class), callbackIdentifier.capture()); @@ -1182,7 +1197,8 @@ public class WifiManagerTest { public void trafficStateCallbackProxyCallsOnMultipleUpdates() throws Exception { ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(ITrafficStateCallback.Stub.class); - mWifiManager.registerTrafficStateCallback(mTrafficStateCallback, mHandler); + mWifiManager.registerTrafficStateCallback(new HandlerExecutor(mHandler), + mTrafficStateCallback); verify(mWifiService).registerTrafficStateCallback( any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -1201,7 +1217,7 @@ public class WifiManagerTest { TrafficStateCallback.DATA_ACTIVITY_OUT); } - /* + /** * Verify client-provided callback is being called on the correct thread */ @Test @@ -1210,7 +1226,8 @@ public class WifiManagerTest { ArgumentCaptor.forClass(ITrafficStateCallback.Stub.class); TestLooper altLooper = new TestLooper(); Handler altHandler = new Handler(altLooper.getLooper()); - mWifiManager.registerTrafficStateCallback(mTrafficStateCallback, altHandler); + mWifiManager.registerTrafficStateCallback(new HandlerExecutor(altHandler), + mTrafficStateCallback); verify(mContext, never()).getMainLooper(); verify(mContext, never()).getMainExecutor(); verify(mWifiService).registerTrafficStateCallback( @@ -1228,10 +1245,11 @@ public class WifiManagerTest { @Test public void registerNetworkRequestMatchCallbackCallGoesToWifiServiceImpl() throws Exception { - when(mContext.getMainLooper()).thenReturn(mLooper.getLooper()); + when(mContext.getMainExecutor()).thenReturn( + new HandlerExecutor(new Handler(mLooper.getLooper()))); ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(INetworkRequestMatchCallback.Stub.class); - mWifiManager.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback, null); + mWifiManager.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback); verify(mWifiService).registerNetworkRequestMatchCallback( any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -1265,7 +1283,8 @@ public class WifiManagerTest { @Test public void unregisterNetworkRequestMatchCallbackCallGoesToWifiServiceImpl() throws Exception { ArgumentCaptor callbackIdentifier = ArgumentCaptor.forClass(Integer.class); - mWifiManager.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback, mHandler); + mWifiManager.registerNetworkRequestMatchCallback(new HandlerExecutor(mHandler), + mNetworkRequestMatchCallback); verify(mWifiService).registerNetworkRequestMatchCallback( any(IBinder.class), any(INetworkRequestMatchCallback.class), callbackIdentifier.capture()); @@ -1282,10 +1301,11 @@ public class WifiManagerTest { @Test public void networkRequestUserSelectionCallbackCallGoesToWifiServiceImpl() throws Exception { - when(mContext.getMainLooper()).thenReturn(mLooper.getLooper()); + when(mContext.getMainExecutor()).thenReturn( + new HandlerExecutor(new Handler(mLooper.getLooper()))); ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(INetworkRequestMatchCallback.Stub.class); - mWifiManager.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback, null); + mWifiManager.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback); verify(mWifiService).registerNetworkRequestMatchCallback( any(IBinder.class), callbackCaptor.capture(), anyInt()); -- cgit v1.2.3 From e955accd13ed70b074bb10c0bc1da234ffd40afa Mon Sep 17 00:00:00 2001 From: David Su Date: Wed, 13 Nov 2019 10:47:44 -0800 Subject: Expose ScanResult/WifiInfo @hide APIs as @SystemApi Expose @hide APIs in ScanResult/WifiInfo as @SystemApi. These APIs are mostly used by Settings. Bug: 144311098 Test: atest FrameworksWifiApiTests Change-Id: Ifdfa78ed59f6a42a3646defa5a9f164d146ceada --- wifi/java/android/net/wifi/ScanResult.java | 32 ++-- wifi/java/android/net/wifi/WifiInfo.java | 169 +++++++++++++++------ wifi/java/android/net/wifi/WifiManager.java | 5 +- wifi/java/android/net/wifi/WifiSsid.java | 62 +++++--- .../android/net/wifi/hotspot2/OsuProvider.java | 9 ++ wifi/tests/src/android/net/wifi/WifiInfoTest.java | 4 +- .../android/net/wifi/hotspot2/OsuProviderTest.java | 4 +- 7 files changed, 197 insertions(+), 88 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java index ed1a2f9f16ca..9956901434d0 100644 --- a/wifi/java/android/net/wifi/ScanResult.java +++ b/wifi/java/android/net/wifi/ScanResult.java @@ -585,6 +585,7 @@ public class ScanResult implements Parcelable { * * @hide */ + // TODO(b/144431927): remove once migrated to Suggestions public boolean isCarrierAp; /** @@ -592,6 +593,7 @@ public class ScanResult implements Parcelable { * * @hide */ + // TODO(b/144431927): remove once migrated to Suggestions public int carrierApEapType; /** @@ -599,13 +601,14 @@ public class ScanResult implements Parcelable { * * @hide */ + // TODO(b/144431927): remove once migrated to Suggestions public String carrierName; /** {@hide} */ public ScanResult(WifiSsid wifiSsid, String BSSID, long hessid, int anqpDomainId, byte[] osuProviders, String caps, int level, int frequency, long tsf) { this.wifiSsid = wifiSsid; - this.SSID = (wifiSsid != null) ? wifiSsid.toString() : WifiSsid.NONE; + this.SSID = (wifiSsid != null) ? wifiSsid.toString() : WifiManager.UNKNOWN_SSID; this.BSSID = BSSID; this.hessid = hessid; this.anqpDomainId = anqpDomainId; @@ -636,7 +639,7 @@ public class ScanResult implements Parcelable { public ScanResult(WifiSsid wifiSsid, String BSSID, String caps, int level, int frequency, long tsf, int distCm, int distSdCm) { this.wifiSsid = wifiSsid; - this.SSID = (wifiSsid != null) ? wifiSsid.toString() : WifiSsid.NONE; + this.SSID = (wifiSsid != null) ? wifiSsid.toString() : WifiManager.UNKNOWN_SSID; this.BSSID = BSSID; this.capabilities = caps; this.level = level; @@ -740,19 +743,18 @@ public class ScanResult implements Parcelable { StringBuffer sb = new StringBuffer(); String none = ""; - sb.append("SSID: "). - append(wifiSsid == null ? WifiSsid.NONE : wifiSsid). - append(", BSSID: "). - append(BSSID == null ? none : BSSID). - append(", capabilities: "). - append(capabilities == null ? none : capabilities). - append(", level: "). - append(level). - append(", frequency: "). - append(frequency). - append(", timestamp: "). - append(timestamp); - + sb.append("SSID: ") + .append(wifiSsid == null ? WifiManager.UNKNOWN_SSID : wifiSsid) + .append(", BSSID: ") + .append(BSSID == null ? none : BSSID) + .append(", capabilities: ") + .append(capabilities == null ? none : capabilities) + .append(", level: ") + .append(level) + .append(", frequency: ") + .append(frequency) + .append(", timestamp: ") + .append(timestamp); sb.append(", distance: ").append((distanceCm != UNSPECIFIED ? distanceCm : "?")). append("(cm)"); sb.append(", distanceSd: ").append((distanceSdCm != UNSPECIFIED ? distanceSdCm : "?")). diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java index 86e51227575b..f3f873b4ead8 100644 --- a/wifi/java/android/net/wifi/WifiInfo.java +++ b/wifi/java/android/net/wifi/WifiInfo.java @@ -53,7 +53,7 @@ public class WifiInfo implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @SystemApi public static final String DEFAULT_MAC_ADDRESS = "02:00:00:00:00:00"; static { @@ -79,8 +79,12 @@ public class WifiInfo implements Parcelable { private WifiSsid mWifiSsid; private int mNetworkId; - /** @hide **/ - @UnsupportedAppUsage + /** + * Used to indicate that the RSSI is invalid, for example if no RSSI measurements are available + * yet. + * @hide + */ + @SystemApi public static final int INVALID_RSSI = -127; /** @hide **/ @@ -161,7 +165,7 @@ public class WifiInfo implements Parcelable { * If connected to a network suggestion or specifier, store the package name of the app, * else null. */ - private String mNetworkSuggestionOrSpecifierPackageName; + private String mAppPackageName; /** * Running total count of lost (not ACKed) transmitted unicast data packets. @@ -184,32 +188,89 @@ public class WifiInfo implements Parcelable { */ public long rxSuccess; + private double mTxBadRate; + /** * Average rate of lost transmitted packets, in units of packets per second. * @hide */ - public double txBadRate; + @SystemApi + public double getTxBadRate() { + return mTxBadRate; + } + + /** @hide */ + public void setTxBadRate(double txBadRate) { + mTxBadRate = txBadRate; + } + + private double mTxRetriesRate; + /** * Average rate of transmitted retry packets, in units of packets per second. * @hide */ - public double txRetriesRate; + @SystemApi + public double getTxRetriesRate() { + return mTxRetriesRate; + } + + /** @hide */ + public void setTxRetriesRate(double txRetriesRate) { + mTxRetriesRate = txRetriesRate; + } + + private double mTxSuccessRate; + /** * Average rate of successfully transmitted unicast packets, in units of packets per second. * @hide */ - public double txSuccessRate; + @SystemApi + public double getTxSuccessRate() { + return mTxSuccessRate; + } + + /** @hide */ + public void setTxSuccessRate(double txSuccessRate) { + mTxSuccessRate = txSuccessRate; + } + + private double mRxSuccessRate; + /** * Average rate of received unicast data packets, in units of packets per second. * @hide */ - public double rxSuccessRate; + @SystemApi + public double getRxSuccessRate() { + return mRxSuccessRate; + } + + /** @hide */ + public void setRxSuccessRate(double rxSuccessRate) { + mRxSuccessRate = rxSuccessRate; + } + + /** @hide */ + @UnsupportedAppUsage + public int score; /** + * The current Wifi score. + * NOTE: this value should only be used for debugging purposes. Do not rely on this value for + * any computations. The meaning of this value can and will change at any time without warning. * @hide */ - @UnsupportedAppUsage - public int score; + @SystemApi + public int getScore() { + return score; + } + + /** @hide */ + public void setScore(int score) { + this.score = score; + } /** * Flag indicating that AP has hinted that upstream connection is metered, @@ -243,17 +304,17 @@ public class WifiInfo implements Parcelable { setMeteredHint(false); setEphemeral(false); setOsuAp(false); - setNetworkSuggestionOrSpecifierPackageName(null); + setAppPackageName(null); setFQDN(null); setProviderFriendlyName(null); txBad = 0; txSuccess = 0; rxSuccess = 0; txRetries = 0; - txBadRate = 0; - txSuccessRate = 0; - rxSuccessRate = 0; - txRetriesRate = 0; + mTxBadRate = 0; + mTxSuccessRate = 0; + mRxSuccessRate = 0; + mTxRetriesRate = 0; score = 0; } @@ -277,8 +338,8 @@ public class WifiInfo implements Parcelable { mMeteredHint = source.mMeteredHint; mEphemeral = source.mEphemeral; mTrusted = source.mTrusted; - mNetworkSuggestionOrSpecifierPackageName = - source.mNetworkSuggestionOrSpecifierPackageName; + mAppPackageName = + source.mAppPackageName; mOsuAp = source.mOsuAp; mFqdn = source.mFqdn; mProviderFriendlyName = source.mProviderFriendlyName; @@ -286,10 +347,10 @@ public class WifiInfo implements Parcelable { txRetries = source.txRetries; txSuccess = source.txSuccess; rxSuccess = source.rxSuccess; - txBadRate = source.txBadRate; - txRetriesRate = source.txRetriesRate; - txSuccessRate = source.txSuccessRate; - rxSuccessRate = source.rxSuccessRate; + mTxBadRate = source.mTxBadRate; + mTxRetriesRate = source.mTxRetriesRate; + mTxSuccessRate = source.mTxSuccessRate; + mRxSuccessRate = source.mRxSuccessRate; score = source.score; mWifiStandard = source.mWifiStandard; } @@ -323,10 +384,10 @@ public class WifiInfo implements Parcelable { return "\"" + unicode + "\""; } else { String hex = mWifiSsid.getHexString(); - return (hex != null) ? hex : WifiSsid.NONE; + return (hex != null) ? hex : WifiManager.UNKNOWN_SSID; } } - return WifiSsid.NONE; + return WifiManager.UNKNOWN_SSID; } /** @hide */ @@ -523,8 +584,15 @@ public class WifiInfo implements Parcelable { mEphemeral = ephemeral; } - /** {@hide} */ - @UnsupportedAppUsage + /** + * Returns true if the current Wifi network is ephemeral, false otherwise. + * An ephemeral network is a network that is temporary and not persisted in the system. + * Ephemeral networks cannot be forgotten, only disabled with + * {@link WifiManager#disableEphemeralNetwork(String)}. + * + * @hide + */ + @SystemApi public boolean isEphemeral() { return mEphemeral; } @@ -581,13 +649,19 @@ public class WifiInfo implements Parcelable { } /** {@hide} */ - public void setNetworkSuggestionOrSpecifierPackageName(@Nullable String packageName) { - mNetworkSuggestionOrSpecifierPackageName = packageName; + public void setAppPackageName(@Nullable String packageName) { + mAppPackageName = packageName; } - /** {@hide} */ - public @Nullable String getNetworkSuggestionOrSpecifierPackageName() { - return mNetworkSuggestionOrSpecifierPackageName; + /** + * If this network was created in response to an app request (e.g. through Network Suggestion + * or Network Specifier), return the package name of the app that made the request. + * Null otherwise. + * @hide + */ + @SystemApi + public @Nullable String getAppPackageName() { + return mAppPackageName; } @@ -648,7 +722,7 @@ public class WifiInfo implements Parcelable { return mWifiSsid.isHidden(); } - /** + /** * Map a supplicant state into a fine-grained network connectivity state. * @param suppState the supplicant state * @return the corresponding {@link DetailedState} @@ -680,9 +754,14 @@ public class WifiInfo implements Parcelable { } } - /** {@hide} */ - @UnsupportedAppUsage - public static String removeDoubleQuotes(String string) { + /** + * Remove double quotes (") surrounding a SSID string, if present. Otherwise, return the + * string unmodified. Return null if the input string was null. + * @hide + */ + @Nullable + @SystemApi + public static String removeDoubleQuotes(@Nullable String string) { if (string == null) return null; final int length = string.length(); if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) { @@ -696,7 +775,7 @@ public class WifiInfo implements Parcelable { StringBuffer sb = new StringBuffer(); String none = ""; - sb.append("SSID: ").append(mWifiSsid == null ? WifiSsid.NONE : mWifiSsid) + sb.append("SSID: ").append(mWifiSsid == null ? WifiManager.UNKNOWN_SSID : mWifiSsid) .append(", BSSID: ").append(mBSSID == null ? none : mBSSID) .append(", MAC: ").append(mMacAddress == null ? none : mMacAddress) .append(", Supplicant state: ") @@ -745,16 +824,16 @@ public class WifiInfo implements Parcelable { dest.writeInt(mTrusted ? 1 : 0); dest.writeInt(score); dest.writeLong(txSuccess); - dest.writeDouble(txSuccessRate); + dest.writeDouble(mTxSuccessRate); dest.writeLong(txRetries); - dest.writeDouble(txRetriesRate); + dest.writeDouble(mTxRetriesRate); dest.writeLong(txBad); - dest.writeDouble(txBadRate); + dest.writeDouble(mTxBadRate); dest.writeLong(rxSuccess); - dest.writeDouble(rxSuccessRate); + dest.writeDouble(mRxSuccessRate); mSupplicantState.writeToParcel(dest, flags); dest.writeInt(mOsuAp ? 1 : 0); - dest.writeString(mNetworkSuggestionOrSpecifierPackageName); + dest.writeString(mAppPackageName); dest.writeString(mFqdn); dest.writeString(mProviderFriendlyName); dest.writeInt(mWifiStandard); @@ -787,16 +866,16 @@ public class WifiInfo implements Parcelable { info.mTrusted = in.readInt() != 0; info.score = in.readInt(); info.txSuccess = in.readLong(); - info.txSuccessRate = in.readDouble(); + info.mTxSuccessRate = in.readDouble(); info.txRetries = in.readLong(); - info.txRetriesRate = in.readDouble(); + info.mTxRetriesRate = in.readDouble(); info.txBad = in.readLong(); - info.txBadRate = in.readDouble(); + info.mTxBadRate = in.readDouble(); info.rxSuccess = in.readLong(); - info.rxSuccessRate = in.readDouble(); + info.mRxSuccessRate = in.readDouble(); info.mSupplicantState = SupplicantState.CREATOR.createFromParcel(in); info.mOsuAp = in.readInt() != 0; - info.mNetworkSuggestionOrSpecifierPackageName = in.readString(); + info.mAppPackageName = in.readString(); info.mFqdn = in.readString(); info.mProviderFriendlyName = in.readString(); info.mWifiStandard = in.readInt(); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 8482b069616d..1a01f6a4ec9d 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1181,6 +1181,9 @@ public class WifiManager { */ private static final int MAX_ACTIVE_LOCKS = 50; + /** Indicates an invalid SSID. */ + public static final String UNKNOWN_SSID = ""; + /* Number of currently active WifiLocks and MulticastLocks */ @UnsupportedAppUsage private int mActiveLockCount; @@ -2539,7 +2542,7 @@ public class WifiManager { *

    * In the connected state, access to the SSID and BSSID requires * the same permissions as {@link #getScanResults}. If such access is not allowed, - * {@link WifiInfo#getSSID} will return {@code ""} and + * {@link WifiInfo#getSSID} will return {@link #UNKNOWN_SSID} and * {@link WifiInfo#getBSSID} will return {@code "02:00:00:00:00:00"}. * * @return the Wi-Fi information, contained in {@link WifiInfo}. diff --git a/wifi/java/android/net/wifi/WifiSsid.java b/wifi/java/android/net/wifi/WifiSsid.java index 70ca0882d7da..90756d860a21 100644 --- a/wifi/java/android/net/wifi/WifiSsid.java +++ b/wifi/java/android/net/wifi/WifiSsid.java @@ -16,6 +16,8 @@ package android.net.wifi; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; @@ -40,23 +42,29 @@ import java.util.Locale; * * @hide */ -public class WifiSsid implements Parcelable { +public final class WifiSsid implements Parcelable { private static final String TAG = "WifiSsid"; @UnsupportedAppUsage public final ByteArrayOutputStream octets = new ByteArrayOutputStream(32); private static final int HEX_RADIX = 16; + @UnsupportedAppUsage - public static final String NONE = ""; + public static final String NONE = WifiManager.UNKNOWN_SSID; private WifiSsid() { } - public static WifiSsid createFromByteArray(byte ssid[]) { + /** + * Create a WifiSsid from a raw byte array. If the byte array is null, return an empty WifiSsid + * object. + */ + @NonNull + public static WifiSsid createFromByteArray(@Nullable byte[] ssid) { WifiSsid wifiSsid = new WifiSsid(); if (ssid != null) { - wifiSsid.octets.write(ssid, 0/* the start offset */, ssid.length);; + wifiSsid.octets.write(ssid, 0 /* the start offset */, ssid.length); } return wifiSsid; } @@ -174,6 +182,10 @@ public class WifiSsid implements Parcelable { } } + /** + * Converts this SSID to an unquoted UTF-8 String representation. + * @return the SSID string, or {@link WifiManager#UNKNOWN_SSID} if there was an error. + */ @Override public String toString() { byte[] ssidBytes = octets.toByteArray(); @@ -191,7 +203,7 @@ public class WifiSsid implements Parcelable { CoderResult result = decoder.decode(ByteBuffer.wrap(ssidBytes), out, true); out.flip(); if (result.isError()) { - return NONE; + return WifiManager.UNKNOWN_SSID; } return out.toString(); } @@ -241,32 +253,36 @@ public class WifiSsid implements Parcelable { return (octets.size() > 0) ? out : null; } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ + @Override public int describeContents() { return 0; } - /** Implement the Parcelable interface {@hide} */ - public void writeToParcel(Parcel dest, int flags) { + /** Implement the Parcelable interface */ + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(octets.size()); dest.writeByteArray(octets.toByteArray()); } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ @UnsupportedAppUsage - public static final @android.annotation.NonNull Creator CREATOR = - new Creator() { - public WifiSsid createFromParcel(Parcel in) { - WifiSsid ssid = new WifiSsid(); - int length = in.readInt(); - byte b[] = new byte[length]; - in.readByteArray(b); - ssid.octets.write(b, 0, length); - return ssid; - } + public static final @NonNull Creator CREATOR = + new Creator() { + @Override + public WifiSsid createFromParcel(Parcel in) { + WifiSsid ssid = new WifiSsid(); + int length = in.readInt(); + byte[] b = new byte[length]; + in.readByteArray(b); + ssid.octets.write(b, 0, length); + return ssid; + } - public WifiSsid[] newArray(int size) { - return new WifiSsid[size]; - } - }; + @Override + public WifiSsid[] newArray(int size) { + return new WifiSsid[size]; + } + }; } diff --git a/wifi/java/android/net/wifi/hotspot2/OsuProvider.java b/wifi/java/android/net/wifi/hotspot2/OsuProvider.java index a32bd547e1e2..3bef50211015 100644 --- a/wifi/java/android/net/wifi/hotspot2/OsuProvider.java +++ b/wifi/java/android/net/wifi/hotspot2/OsuProvider.java @@ -27,6 +27,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -90,6 +91,14 @@ public final class OsuProvider implements Parcelable { */ private final Icon mIcon; + /** @hide */ + public OsuProvider(String osuSsid, Map friendlyNames, + String serviceDescription, Uri serverUri, String nai, List methodList, + Icon icon) { + this(WifiSsid.createFromByteArray(osuSsid.getBytes(StandardCharsets.UTF_8)), + friendlyNames, serviceDescription, serverUri, nai, methodList, icon); + } + /** @hide */ public OsuProvider(WifiSsid osuSsid, Map friendlyNames, String serviceDescription, Uri serverUri, String nai, List methodList, diff --git a/wifi/tests/src/android/net/wifi/WifiInfoTest.java b/wifi/tests/src/android/net/wifi/WifiInfoTest.java index 22a5faaac112..f7612341d4b3 100644 --- a/wifi/tests/src/android/net/wifi/WifiInfoTest.java +++ b/wifi/tests/src/android/net/wifi/WifiInfoTest.java @@ -54,7 +54,7 @@ public class WifiInfoTest { writeWifiInfo.setOsuAp(true); writeWifiInfo.setFQDN(TEST_FQDN); writeWifiInfo.setProviderFriendlyName(TEST_PROVIDER_NAME); - writeWifiInfo.setNetworkSuggestionOrSpecifierPackageName(TEST_PACKAGE_NAME); + writeWifiInfo.setAppPackageName(TEST_PACKAGE_NAME); writeWifiInfo.setWifiStandard(TEST_WIFI_STANDARD); Parcel parcel = Parcel.obtain(); @@ -71,7 +71,7 @@ public class WifiInfoTest { assertTrue(readWifiInfo.isTrusted()); assertTrue(readWifiInfo.isOsuAp()); assertTrue(readWifiInfo.isPasspointAp()); - assertEquals(TEST_PACKAGE_NAME, readWifiInfo.getNetworkSuggestionOrSpecifierPackageName()); + assertEquals(TEST_PACKAGE_NAME, readWifiInfo.getAppPackageName()); assertEquals(TEST_FQDN, readWifiInfo.getPasspointFqdn()); assertEquals(TEST_PROVIDER_NAME, readWifiInfo.getPasspointProviderFriendlyName()); assertEquals(TEST_WIFI_STANDARD, readWifiInfo.getWifiStandard()); diff --git a/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java b/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java index c7e009ee9864..43ee24943e12 100644 --- a/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java +++ b/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java @@ -82,7 +82,7 @@ public class OsuProviderTest { */ @Test public void verifyParcelWithEmptyProviderInfo() throws Exception { - verifyParcel(new OsuProvider(null, null, null, null, null, null, null)); + verifyParcel(new OsuProvider((WifiSsid) null, null, null, null, null, null, null)); } /** @@ -102,7 +102,7 @@ public class OsuProviderTest { */ @Test public void verifyCopyConstructorWithNullSource() throws Exception { - OsuProvider expected = new OsuProvider(null, null, null, null, null, null, null); + OsuProvider expected = new OsuProvider((WifiSsid) null, null, null, null, null, null, null); assertEquals(expected, new OsuProvider(null)); } -- cgit v1.2.3 From c278f80c282e1ec4563b75b2c3f7c169e3d26023 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Thu, 14 Nov 2019 07:19:12 -0800 Subject: NetworkScoreManager: Add @SystemApi for wifi mainline module Add formal API's for API's that the wifi mainline module uses: a) NetworkScoreManager.requestNetworkScores - Request new network scores. b) NetworkScoreManager.registerNetworkScoreCallback - @SystemApi wrapper over the existing registerNetworkScoreCache. c) NetworkKey.createFromScanResult - Create NetworkKey from ScanResult. Also, a) Converted the existing WifiNetworkScoreCache callback implementation to support both the new @SystemApi (used by wifi) and the old @hide API (used by settings). b) Stopped invoking dump on all the callbacks from NetworkScoreService. The dump of each callback should be invoked at their client site (i.e wifi service should dump state of the callback it registers with the service). c) Added a helper method |dumpWithLatestScanResults| to help dump the state of the WifiNetworkScoreCache from wifi service. Bug: 144487252 Test: a) Device boots up and connects to wifi network. b) Manually verified that network scores are being requested & updated with the new interface. Change-Id: Id5a66189150e7a088127519373a832f63bdd12ac --- wifi/java/android/net/wifi/WifiNetworkScoreCache.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiNetworkScoreCache.java b/wifi/java/android/net/wifi/WifiNetworkScoreCache.java index b22ae07015c8..5a212a824452 100755 --- a/wifi/java/android/net/wifi/WifiNetworkScoreCache.java +++ b/wifi/java/android/net/wifi/WifiNetworkScoreCache.java @@ -22,6 +22,7 @@ import android.annotation.Nullable; import android.content.Context; import android.net.INetworkScoreCache; import android.net.NetworkKey; +import android.net.NetworkScoreManager; import android.net.ScoredNetwork; import android.os.Handler; import android.os.Process; @@ -40,7 +41,8 @@ import java.util.List; * * @hide */ -public class WifiNetworkScoreCache extends INetworkScoreCache.Stub { +public class WifiNetworkScoreCache extends INetworkScoreCache.Stub + implements NetworkScoreManager.NetworkScoreCallback { private static final String TAG = "WifiNetworkScoreCache"; private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG); @@ -246,6 +248,17 @@ public class WifiNetworkScoreCache extends INetworkScoreCache.Stub { } @Override protected final void dump(FileDescriptor fd, PrintWriter writer, String[] args) { + WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); + dumpWithLatestScanResults(fd, writer, args, wifiManager.getScanResults()); + } + + /** + * This is directly invoked from within Wifi-Service (on it's instance of this class), hence + * avoid making the WifiManager.getScanResults() call to avoid a deadlock. + */ + public final void dumpWithLatestScanResults( + FileDescriptor fd, PrintWriter writer, String[] args, + List latestScanResults) { mContext.enforceCallingOrSelfPermission(permission.DUMP, TAG); String header = String.format("WifiNetworkScoreCache (%s/%d)", mContext.getPackageName(), Process.myUid()); @@ -256,8 +269,7 @@ public class WifiNetworkScoreCache extends INetworkScoreCache.Stub { writer.println(" " + score); } writer.println(" Network scores for latest ScanResults:"); - WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); - for (ScanResult scanResult : wifiManager.getScanResults()) { + for (ScanResult scanResult : latestScanResults) { writer.println( " " + buildNetworkKey(scanResult) + ": " + getNetworkScore(scanResult)); } -- cgit v1.2.3 From f7cffa7aaf801a2dac6de05fdcc6d881714b8e2f Mon Sep 17 00:00:00 2001 From: Suprabh Shukla Date: Fri, 8 Nov 2019 17:03:03 -0800 Subject: Exposing WorkSource hidden APIs as system APIs Users of these APIs are planning to move to apex. Test: atest FrameworksCoreTests:android.os.WorkSourceTest atest CtsOsTestCases:android.os.cts.WorkSourceTest Bug: 143551137 Change-Id: I2e97a8b469254ea92e3ee21571ee8ae3cbb9abbe --- wifi/java/android/net/wifi/WifiManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 93960de89d89..6610683da2d4 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -4226,7 +4226,7 @@ public class WifiManager { if (ws == null) { mWorkSource = null; } else { - ws.clearNames(); + ws = ws.withoutNames(); if (mWorkSource == null) { changed = mWorkSource != null; mWorkSource = new WorkSource(ws); -- cgit v1.2.3 From 72a333a1823ab69f1c4d2b8f0aa9ca5857449afb Mon Sep 17 00:00:00 2001 From: David Su Date: Wed, 20 Nov 2019 18:16:40 -0800 Subject: Remove WifiManager.notifyUserOfApBandConversion() Removed this API since the notification should be handled elsewhere, not in Wifi service. Thus, moved to SettingsBackupAgent. Bug: 144218444 Test: atest FrameworksWifiApiTests Change-Id: Ifc0eafac2e61a5434daa20a29a5b22fba3fbc561 --- wifi/java/android/net/wifi/IWifiManager.aidl | 2 -- wifi/java/android/net/wifi/WifiManager.java | 21 --------------------- .../com/android/server/wifi/BaseWifiService.java | 2 -- 3 files changed, 25 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index bbb85440f729..b4e72abfa201 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -161,8 +161,6 @@ interface IWifiManager boolean setWifiApConfiguration(in WifiConfiguration wifiConfig, String packageName); - void notifyUserOfApBandConversion(String packageName); - void enableTdls(String remoteIPAddress, boolean enable); void enableTdlsWithMacAddress(String remoteMacAddress, boolean enable); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 56f152eebb3e..5b70e79959b3 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -3206,27 +3206,6 @@ public class WifiManager { } } - /** - * Method that triggers a notification to the user about a band conversion - * (e.g. 5 GHz to 2.4 GHz) to their saved AP config. - * - * @hide - */ - // TODO(b/144218444): move the notification to Settings instead of making this @SystemApi - @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - public void notifyUserOfApBandConversion() { - Log.d(TAG, "apBand was converted, notify the user"); - try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.notifyUserOfApBandConversion(mContext.getOpPackageName()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - /** * Enable/Disable TDLS on a specific local route. * diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index cf74ff07d2ee..d740c363f889 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -42,7 +42,6 @@ import android.net.wifi.hotspot2.IProvisioningCallback; import android.net.wifi.hotspot2.OsuProvider; import android.net.wifi.hotspot2.PasspointConfiguration; import android.os.IBinder; -import android.os.Messenger; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.WorkSource; @@ -325,7 +324,6 @@ public class BaseWifiService extends IWifiManager.Stub { throw new UnsupportedOperationException(); } - @Override public void notifyUserOfApBandConversion(String packageName) { throw new UnsupportedOperationException(); } -- cgit v1.2.3 From 3c9241075a7ae2e5e4197018ef1ef12a6c94f1fe Mon Sep 17 00:00:00 2001 From: David Su Date: Mon, 18 Nov 2019 12:49:59 -0800 Subject: Add new WifiManager API to calculate signal levels New calculateSignalLevel() overload allows RSSI level thresholds to be potentially overlaid. Bug: 140781184 Test: compiles Change-Id: Ic6c84885dbe17ca39600dc8d8eb5aeff641a0ad3 --- wifi/java/android/net/wifi/IWifiManager.aidl | 2 ++ wifi/java/android/net/wifi/WifiManager.java | 40 ++++++++++++++++++---- .../com/android/server/wifi/BaseWifiService.java | 6 +++- .../src/android/net/wifi/WifiManagerTest.java | 19 +++++++++- 4 files changed, 59 insertions(+), 8 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index bbb85440f729..8d5f5be02f1a 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -242,4 +242,6 @@ interface IWifiManager void registerSuggestionConnectionStatusListener(in IBinder binder, in ISuggestionConnectionStatusListener listener, int listenerIdentifier, String packageName, String featureId); void unregisterSuggestionConnectionStatusListener(int listenerIdentifier, String packageName); + + int calculateSignalLevel(int rssi); } diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 56f152eebb3e..11cee4a10c7e 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1153,8 +1153,6 @@ public class WifiManager { * @hide */ @UnsupportedAppUsage - // TODO(b/140781184): need to support custom number of RSSI levels, as well as levels that are - // not evenly spaced public static final int RSSI_LEVELS = 5; /** @@ -2782,11 +2780,13 @@ public class WifiManager { * is being shown. * * @param rssi The power of the signal measured in RSSI. - * @param numLevels The number of levels to consider in the calculated - * level. - * @return A level of the signal, given in the range of 0 to numLevels-1 - * (both inclusive). + * @param numLevels The number of levels to consider in the calculated level. + * @return A level of the signal, given in the range of 0 to numLevels-1 (both inclusive). + * @deprecated Callers should use {@link #calculateSignalLevel(int)} instead to get the + * signal level using the system default RSSI thresholds, or otherwise compute the RSSI level + * themselves using their own formula. */ + @Deprecated public static int calculateSignalLevel(int rssi, int numLevels) { if (rssi <= MIN_RSSI) { return 0; @@ -2799,6 +2799,34 @@ public class WifiManager { } } + /** + * Given a raw RSSI, return the RSSI signal quality rating using the system default RSSI + * quality rating thresholds. + * @param rssi a raw RSSI value, in dBm, usually between -55 and -90 + * @return the RSSI signal quality rating, in the range + * [0, {@link #getMaxSignalLevel()}], where 0 is the lowest (worst signal) RSSI + * rating and {@link #getMaxSignalLevel()} is the highest (best signal) RSSI rating. + */ + public int calculateSignalLevel(int rssi) { + try { + IWifiManager iWifiManager = getIWifiManager(); + if (iWifiManager == null) { + throw new RemoteException("Wifi service is not running"); + } + return iWifiManager.calculateSignalLevel(rssi); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Get the system default maximum signal level. + * This is the maximum RSSI level returned by {@link #calculateSignalLevel(int)}. + */ + public int getMaxSignalLevel() { + return calculateSignalLevel(Integer.MAX_VALUE); + } + /** * Compares two signal strengths. * diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index cf74ff07d2ee..e547379ac716 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -42,7 +42,6 @@ import android.net.wifi.hotspot2.IProvisioningCallback; import android.net.wifi.hotspot2.OsuProvider; import android.net.wifi.hotspot2.PasspointConfiguration; import android.os.IBinder; -import android.os.Messenger; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.WorkSource; @@ -537,4 +536,9 @@ public class BaseWifiService extends IWifiManager.Stub { String packageName) { throw new UnsupportedOperationException(); } + + @Override + public int calculateSignalLevel(int rssi) { + throw new UnsupportedOperationException(); + } } diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 06ebc1b3f6da..507d50295d86 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -1899,8 +1899,25 @@ public class WifiManagerTest { */ @Test public void testRemoveSuggestionConnectionListener() throws Exception { - mWifiManager.removeSuggestionConnectionStatusListener(mListener); verify(mWifiService).unregisterSuggestionConnectionStatusListener(anyInt(), anyString()); } + + /** Test {@link WifiManager#calculateSignalLevel(int)} */ + @Test + public void testCalculateSignalLevel() throws Exception { + when(mWifiService.calculateSignalLevel(anyInt())).thenReturn(3); + int actual = mWifiManager.calculateSignalLevel(-60); + verify(mWifiService).calculateSignalLevel(-60); + assertEquals(3, actual); + } + + /** Test {@link WifiManager#getMaxSignalLevel()} */ + @Test + public void testGetMaxSignalLevel() throws Exception { + when(mWifiService.calculateSignalLevel(anyInt())).thenReturn(4); + int actual = mWifiManager.getMaxSignalLevel(); + verify(mWifiService).calculateSignalLevel(Integer.MAX_VALUE); + assertEquals(4, actual); + } } -- cgit v1.2.3 From 5579604a1d061115bf3cfa8de2c87d87cf21a8f7 Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Thu, 21 Nov 2019 19:25:52 +0000 Subject: Revert submission Reason for revert: Incomplete fix that causes additional issues which were not anticipated earlier. Change-Id: Iff36d5a10e6c8ee8978a5842af8f19efc10c0a91 --- wifi/java/android/net/wifi/WifiConfiguration.java | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index f7d2b40e1ea0..90343d4798a7 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -384,7 +384,12 @@ public class WifiConfiguration implements Parcelable { public void setSecurityParams(@SecurityType int securityType) { // Clear all the bitsets. allowedKeyManagement.clear(); + allowedProtocols.clear(); allowedAuthAlgorithms.clear(); + allowedPairwiseCiphers.clear(); + allowedGroupCiphers.clear(); + allowedGroupManagementCiphers.clear(); + allowedSuiteBCiphers.clear(); switch (securityType) { case SECURITY_TYPE_OPEN: @@ -407,9 +412,6 @@ public class WifiConfiguration implements Parcelable { requirePMF = true; break; case SECURITY_TYPE_EAP_SUITE_B: - allowedGroupCiphers.clear(); - allowedGroupManagementCiphers.clear(); - allowedSuiteBCiphers.clear(); allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SUITE_B_192); allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256); allowedGroupManagementCiphers.set(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256); @@ -944,12 +946,6 @@ public class WifiConfiguration implements Parcelable { */ public int meteredOverride = METERED_OVERRIDE_NONE; - /** - * This Wifi configuration is a clone of another network with lower security - * @hide - */ - public String clonedNetworkConfigKey; - /** * Blend together all the various opinions to decide if the given network * should be considered metered or not. @@ -1808,7 +1804,6 @@ public class WifiConfiguration implements Parcelable { shared = true; dtimInterval = 0; mRandomizedMacAddress = MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS); - clonedNetworkConfigKey = null; } /** @@ -2376,7 +2371,6 @@ public class WifiConfiguration implements Parcelable { /** copy constructor {@hide} */ @UnsupportedAppUsage - public WifiConfiguration(WifiConfiguration source) { if (source != null) { networkId = source.networkId; @@ -2460,7 +2454,6 @@ public class WifiConfiguration implements Parcelable { requirePMF = source.requirePMF; updateIdentifier = source.updateIdentifier; carrierId = source.carrierId; - clonedNetworkConfigKey = source.clonedNetworkConfigKey; } } @@ -2536,7 +2529,6 @@ public class WifiConfiguration implements Parcelable { dest.writeInt(osu ? 1 : 0); dest.writeLong(randomizedMacExpirationTimeMs); dest.writeInt(carrierId); - dest.writeString(clonedNetworkConfigKey); } /** Implement the Parcelable interface {@hide} */ @@ -2614,7 +2606,6 @@ public class WifiConfiguration implements Parcelable { config.osu = in.readInt() != 0; config.randomizedMacExpirationTimeMs = in.readLong(); config.carrierId = in.readInt(); - config.clonedNetworkConfigKey = in.readString(); return config; } -- cgit v1.2.3 From 409f371488d2ed97101dfb0e42852e89a19147db Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 24 Oct 2019 11:18:41 -0700 Subject: Removed references to Manager AIDL from constructors Converted constructors of Wifi Managers to not reference their AIDL interfaces since they are @hide and cannot be referenced by the platform. Bug: 140299412 Test: atest FrameworksWifiApiTests Change-Id: If43ce6916ddee5357cdcc8cd27d5620a67d21165 --- wifi/java/android/net/wifi/RttManager.java | 2 +- .../android/net/wifi/WifiFrameworkInitializer.java | 119 +++++++++++++++++++++ wifi/java/android/net/wifi/WifiManager.java | 8 +- wifi/java/android/net/wifi/WifiScanner.java | 7 +- .../android/net/wifi/aware/WifiAwareManager.java | 2 +- wifi/java/android/net/wifi/rtt/WifiRttManager.java | 2 +- 6 files changed, 132 insertions(+), 8 deletions(-) create mode 100644 wifi/java/android/net/wifi/WifiFrameworkInitializer.java (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/RttManager.java b/wifi/java/android/net/wifi/RttManager.java index 6a03c73bc3f9..73c52ab0ab1b 100644 --- a/wifi/java/android/net/wifi/RttManager.java +++ b/wifi/java/android/net/wifi/RttManager.java @@ -1212,7 +1212,7 @@ public class RttManager { * * @hide */ - public RttManager(Context context, WifiRttManager service) { + public RttManager(@NonNull Context context, @NonNull WifiRttManager service) { mNewService = service; mContext = context; diff --git a/wifi/java/android/net/wifi/WifiFrameworkInitializer.java b/wifi/java/android/net/wifi/WifiFrameworkInitializer.java new file mode 100644 index 000000000000..775043ae3291 --- /dev/null +++ b/wifi/java/android/net/wifi/WifiFrameworkInitializer.java @@ -0,0 +1,119 @@ +/* + * 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.annotation.SystemApi; +import android.app.SystemServiceRegistry; +import android.content.Context; +import android.net.wifi.aware.IWifiAwareManager; +import android.net.wifi.aware.WifiAwareManager; +import android.net.wifi.p2p.IWifiP2pManager; +import android.net.wifi.p2p.WifiP2pManager; +import android.net.wifi.rtt.IWifiRttManager; +import android.net.wifi.rtt.WifiRttManager; +import android.os.HandlerThread; +import android.os.Looper; + +/** + * Class for performing registration for all Wifi services. + * + * @hide + */ +@SystemApi +public class WifiFrameworkInitializer { + + /** + * A class implementing the lazy holder idiom: the unique static instance + * of {@link #INSTANCE} is instantiated in a thread-safe way (guaranteed by + * the language specs) the first time that NoPreloadHolder is referenced in getInstanceLooper(). + * + * This is necessary because we can't spawn a new thread in {@link #registerServiceWrappers()}. + * {@link #registerServiceWrappers()} is called during the Zygote phase, which disallows + * spawning new threads. Naming the class "NoPreloadHolder" ensures that the classloader will + * not preload this class, inadvertently spawning the thread too early. + */ + private static class NoPreloadHolder { + private static final HandlerThread INSTANCE = createInstance(); + + private static HandlerThread createInstance() { + HandlerThread thread = new HandlerThread("WifiManagerThread"); + thread.start(); + return thread; + } + } + + private static Looper getInstanceLooper() { + return NoPreloadHolder.INSTANCE.getLooper(); + } + + private WifiFrameworkInitializer() {} + + /** + * Called by {@link SystemServiceRegistry}'s static initializer and registers all Wifi services + * to {@link Context}, so that {@link Context#getSystemService} can return them. + * + * @throws IllegalStateException if this is called from anywhere besides + * {@link SystemServiceRegistry} + */ + public static void registerServiceWrappers() { + SystemServiceRegistry.registerContextAwareService( + Context.WIFI_SERVICE, + WifiManager.class, + context -> new WifiManager(context, getInstanceLooper()) + ); + SystemServiceRegistry.registerStaticService( + Context.WIFI_P2P_SERVICE, + WifiP2pManager.class, + serviceBinder -> { + IWifiP2pManager service = IWifiP2pManager.Stub.asInterface(serviceBinder); + return new WifiP2pManager(service); + } + ); + SystemServiceRegistry.registerContextAwareService( + Context.WIFI_AWARE_SERVICE, + WifiAwareManager.class, + (context, serviceBinder) -> { + IWifiAwareManager service = IWifiAwareManager.Stub.asInterface(serviceBinder); + return new WifiAwareManager(context, service); + } + ); + SystemServiceRegistry.registerContextAwareService( + Context.WIFI_SCANNING_SERVICE, + WifiScanner.class, + (context, serviceBinder) -> { + IWifiScanner service = IWifiScanner.Stub.asInterface(serviceBinder); + return new WifiScanner(context, service, getInstanceLooper()); + } + ); + SystemServiceRegistry.registerContextAwareService( + Context.WIFI_RTT_SERVICE, + RttManager.class, + (context, serviceBinder) -> { + IWifiRttManager service = IWifiRttManager.Stub.asInterface(serviceBinder); + WifiRttManager wifiRttManager = new WifiRttManager(context, service); + return new RttManager(context, wifiRttManager); + } + ); + SystemServiceRegistry.registerContextAwareService( + Context.WIFI_RTT_RANGING_SERVICE, + WifiRttManager.class, + (context, serviceBinder) -> { + IWifiRttManager service = IWifiRttManager.Stub.asInterface(serviceBinder); + return new WifiRttManager(context, service); + } + ); + } +} diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 6c2a08c14082..342f043d5801 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1215,11 +1215,13 @@ public class WifiManager { * Applications will almost always want to use * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve * the standard {@link android.content.Context#WIFI_SERVICE Context.WIFI_SERVICE}. + * * @param context the application context - * @hide - hide this because it takes in a parameter of type IWifiManager, which - * is a system private class. + * @param looper the Looper used to deliver callbacks + * + * @hide */ - public WifiManager(Context context, Looper looper) { + public WifiManager(@NonNull Context context, @NonNull Looper looper) { mContext = context; mLooper = looper; mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion; diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index 0d36718f07f1..771f3b819498 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -1291,12 +1291,15 @@ public class WifiScanner { * Applications will almost always want to use * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve * the standard {@link android.content.Context#WIFI_SERVICE Context.WIFI_SERVICE}. + * * @param context the application context - * @param service the Binder interface + * @param service the Binder interface for {@link Context#WIFI_SCANNING_SERVICE} * @param looper the Looper used to deliver callbacks + * * @hide */ - public WifiScanner(Context context, IWifiScanner service, Looper looper) { + public WifiScanner(@NonNull Context context, @NonNull IWifiScanner service, + @NonNull Looper looper) { mContext = context; mService = service; diff --git a/wifi/java/android/net/wifi/aware/WifiAwareManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java index 5aab3470d979..7b37d652426d 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java @@ -158,7 +158,7 @@ public class WifiAwareManager { private final Object mLock = new Object(); // lock access to the following vars /** @hide */ - public WifiAwareManager(Context context, IWifiAwareManager service) { + public WifiAwareManager(@NonNull Context context, @NonNull IWifiAwareManager service) { mContext = context; mService = service; } diff --git a/wifi/java/android/net/wifi/rtt/WifiRttManager.java b/wifi/java/android/net/wifi/rtt/WifiRttManager.java index 770a12096806..cb0c5d41df90 100644 --- a/wifi/java/android/net/wifi/rtt/WifiRttManager.java +++ b/wifi/java/android/net/wifi/rtt/WifiRttManager.java @@ -77,7 +77,7 @@ public class WifiRttManager { "android.net.wifi.rtt.action.WIFI_RTT_STATE_CHANGED"; /** @hide */ - public WifiRttManager(Context context, IWifiRttManager service) { + public WifiRttManager(@NonNull Context context, @NonNull IWifiRttManager service) { mContext = context; mService = service; } -- cgit v1.2.3 From c9f242dad329c5f7c42b4be592bd2b1d094a4864 Mon Sep 17 00:00:00 2001 From: Ahmed ElArabawy Date: Wed, 20 Nov 2019 14:02:00 -0800 Subject: Wifi: Make setScanningEnabled() a system API This commit makes the the API WifiScanner.setScanningEnabled() a System API to allow priviliged apps to use it. Bug: 140541571 Test: atest com.android.wifi.server Change-Id: Id7377415699f2d8a8aea396889716dca1e23ecd5 --- wifi/java/android/net/wifi/WifiScanner.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index 771f3b819498..0de506610ec1 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -789,12 +789,11 @@ public class WifiScanner { /** * Enable/Disable wifi scanning. - * Note: WifiService calls this after any client interface mode changes (i.e. a new interface - * set up or an existing interface torn down) - * If there are >= 1 active client interface, invoke setScanningEnabled(true) - * If there are 0 active client interface, invoke setScanningEnabled(false) + * + * @param enable set to true to enable scanning, set to false to disable all types of scanning. * {@hide} */ + @SystemApi @RequiresPermission(Manifest.permission.NETWORK_STACK) public void setScanningEnabled(boolean enable) { validateChannel(); -- cgit v1.2.3 From 36491ea3e1fa3d61dc5e969d2fabba7b63316231 Mon Sep 17 00:00:00 2001 From: David Su Date: Mon, 28 Oct 2019 14:50:28 -0700 Subject: Expose WifiConfiguration @hide APIs as @SystemApi These APIs are mostly used by Settings. Bug: 143892601 Bug: 129482052 Bug: 115717178 Test: atest FrameworksWifiApiTests Change-Id: Ie801fdc6ed716007802fe77b8db3decd37813c58 --- wifi/java/android/net/wifi/WifiConfiguration.java | 733 +++++++++++++-------- .../android/net/wifi/WifiEnterpriseConfig.java | 56 +- .../android/net/wifi/WifiConfigurationTest.java | 46 +- 3 files changed, 504 insertions(+), 331 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 90343d4798a7..dfdc075043f6 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -38,6 +38,7 @@ import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.BackupUtils; import android.util.Log; +import android.util.SparseArray; import android.util.TimeUtils; import java.io.ByteArrayOutputStream; @@ -86,7 +87,12 @@ public class WifiConfiguration implements Parcelable { public static final String pmfVarName = "ieee80211w"; /** {@hide} */ public static final String updateIdentiferVarName = "update_identifier"; - /** {@hide} */ + /** + * The network ID for an invalid network. + * + * @hide + */ + @SystemApi public static final int INVALID_NETWORK_ID = -1; /** {@hide} */ public static final int LOCAL_ONLY_NETWORK_ID = -2; @@ -102,20 +108,41 @@ public class WifiConfiguration implements Parcelable { public static class KeyMgmt { private KeyMgmt() { } + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(value = { + NONE, + WPA_PSK, + WPA_EAP, + IEEE8021X, + WPA2_PSK, + OSEN, + FT_PSK, + FT_EAP, + SAE, + OWE, + SUITE_B_192, + WPA_PSK_SHA256, + WPA_EAP_SHA256}) + public @interface KeyMgmtScheme {} + /** WPA is not used; plaintext or static WEP could be used. */ public static final int NONE = 0; /** WPA pre-shared key (requires {@code preSharedKey} to be specified). */ public static final int WPA_PSK = 1; /** WPA using EAP authentication. Generally used with an external authentication server. */ public static final int WPA_EAP = 2; - /** IEEE 802.1X using EAP authentication and (optionally) dynamically - * generated WEP keys. */ + /** + * IEEE 802.1X using EAP authentication and (optionally) dynamically + * generated WEP keys. + */ public static final int IEEE8021X = 3; - /** WPA2 pre-shared key for use with soft access point - * (requires {@code preSharedKey} to be specified). - * @hide - */ + /** + * WPA2 pre-shared key for use with soft access point + * (requires {@code preSharedKey} to be specified). + * @hide + */ @SystemApi public static final int WPA2_PSK = 4; /** @@ -462,16 +489,26 @@ public class WifiConfiguration implements Parcelable { */ public String BSSID; + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"AP_BAND_"}, value = { + AP_BAND_2GHZ, + AP_BAND_5GHZ, + AP_BAND_ANY}) + public @interface ApBand {} + /** * 2GHz band. * @hide */ + @SystemApi public static final int AP_BAND_2GHZ = 0; /** * 5GHz band. * @hide */ + @SystemApi public static final int AP_BAND_5GHZ = 1; /** @@ -479,15 +516,18 @@ public class WifiConfiguration implements Parcelable { * operating country code and current radio conditions. * @hide */ + @SystemApi public static final int AP_BAND_ANY = -1; /** - * The band which AP resides on - * -1:Any 0:2G 1:5G - * By default, 2G is chosen + * The band which the AP resides on. + * One of {@link #AP_BAND_2GHZ}, {@link #AP_BAND_5GHZ}, or {@link #AP_BAND_ANY}. + * By default, {@link #AP_BAND_2GHZ} is chosen. + * * @hide */ - @UnsupportedAppUsage + @SystemApi + @ApBand public int apBand = AP_BAND_2GHZ; /** @@ -515,6 +555,7 @@ public class WifiConfiguration implements Parcelable { * Optional SAE Password Id for use with WPA3-SAE. It is an ASCII string. * @hide */ + @SystemApi public @Nullable String saePasswordId; /** @@ -553,9 +594,10 @@ public class WifiConfiguration implements Parcelable { public boolean hiddenSSID; /** - * This is a network that requries Protected Management Frames (PMF). + * True if the network requires Protected Management Frames (PMF), false otherwise. * @hide */ + @SystemApi public boolean requirePMF; /** @@ -643,11 +685,12 @@ public class WifiConfiguration implements Parcelable { public long[] roamingConsortiumIds; /** + * True if this network configuration is visible to and usable by other users on the + * same device, false otherwise. + * * @hide - * This network configuration is visible to and usable by other users on the - * same device. */ - @UnsupportedAppUsage + @SystemApi public boolean shared; /** @@ -738,12 +781,6 @@ public class WifiConfiguration implements Parcelable { @SystemApi public int carrierId = TelephonyManager.UNKNOWN_CARRIER_ID; - /** - * @hide - * Status of user approval for connection - */ - public int userApproved = USER_UNSPECIFIED; - /** * @hide * Auto-join is allowed by user for this network. @@ -752,42 +789,10 @@ public class WifiConfiguration implements Parcelable { @SystemApi public boolean allowAutojoin = true; - /** The Below RSSI thresholds are used to configure AutoJoin - * - GOOD/LOW/BAD thresholds are used so as to calculate link score - * - UNWANTED_SOFT are used by the blacklisting logic so as to handle - * the unwanted network message coming from CS - * - UNBLACKLIST thresholds are used so as to tweak the speed at which - * the network is unblacklisted (i.e. if - * it is seen with good RSSI, it is blacklisted faster) - * - INITIAL_AUTOJOIN_ATTEMPT, used to determine how close from - * the network we need to be before autojoin kicks in - */ /** @hide **/ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public static int INVALID_RSSI = -127; - // States for the userApproved field - /** - * @hide - * User hasn't specified if connection is okay - */ - public static final int USER_UNSPECIFIED = 0; - /** - * @hide - * User has approved this for connection - */ - public static final int USER_APPROVED = 1; - /** - * @hide - * User has banned this from connection - */ - public static final int USER_BANNED = 2; - /** - * @hide - * Waiting for user input - */ - public static final int USER_PENDING = 3; - /** * @hide * Number of reports indicating no Internet Access @@ -861,20 +866,12 @@ public class WifiConfiguration implements Parcelable { * This boolean is cleared if we get a connect/save/ update or * any wifiManager command that indicate the user interacted with the configuration * since we will now consider that the configuration belong to him. + * @deprecated only kept for @UnsupportedAppUsage * @hide */ @UnsupportedAppUsage public boolean selfAdded; - /** - * Set if the configuration was self added by the framework - * This boolean is set once and never cleared. It is used - * so as we never loose track of who created the - * configuration in the first place. - * @hide - */ - public boolean didSelfAdd; - /** * Peer WifiConfiguration this WifiConfiguration was added for * @hide @@ -906,44 +903,77 @@ public class WifiConfiguration implements Parcelable { public boolean trusted; /** - * This Wifi configuration is created from a {@link WifiNetworkSuggestion} + * True if this Wifi configuration is created from a {@link WifiNetworkSuggestion}, + * false otherwise. + * * @hide */ + @SystemApi public boolean fromWifiNetworkSuggestion; /** - * This Wifi configuration is created from a {@link WifiNetworkSpecifier} + * True if this Wifi configuration is created from a {@link WifiNetworkSpecifier}, + * false otherwise. + * * @hide */ + @SystemApi public boolean fromWifiNetworkSpecifier; /** - * Indicates if the creator of this configuration has expressed that it - * should be considered metered. + * True if the creator of this configuration has expressed that it + * should be considered metered, false otherwise. * * @see #isMetered(WifiConfiguration, WifiInfo) + * * @hide */ @SystemApi public boolean meteredHint; - /** {@hide} */ + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"METERED_OVERRIDE_"}, value = { + METERED_OVERRIDE_NONE, + METERED_OVERRIDE_METERED, + METERED_OVERRIDE_NOT_METERED}) + public @interface MeteredOverride {} + + /** + * No metered override. + * @hide + */ + @SystemApi public static final int METERED_OVERRIDE_NONE = 0; - /** {@hide} */ + /** + * Override network to be metered. + * @hide + */ + @SystemApi public static final int METERED_OVERRIDE_METERED = 1; - /** {@hide} */ + /** + * Override network to be unmetered. + * @hide + */ + @SystemApi public static final int METERED_OVERRIDE_NOT_METERED = 2; /** * Indicates if the end user has expressed an explicit opinion about the * meteredness of this network, such as through the Settings app. + * This value is one of {@link #METERED_OVERRIDE_NONE}, {@link #METERED_OVERRIDE_METERED}, + * or {@link #METERED_OVERRIDE_NOT_METERED}. *

    * This should always override any values from {@link #meteredHint} or * {@link WifiInfo#getMeteredHint()}. * + * By default this field is set to {@link #METERED_OVERRIDE_NONE}. + * * @see #isMetered(WifiConfiguration, WifiInfo) * @hide */ + @SystemApi + @MeteredOverride public int meteredOverride = METERED_OVERRIDE_NONE; /** @@ -952,7 +982,8 @@ public class WifiConfiguration implements Parcelable { * * @hide */ - public static boolean isMetered(WifiConfiguration config, WifiInfo info) { + @SystemApi + public static boolean isMetered(@Nullable WifiConfiguration config, @Nullable WifiInfo info) { boolean metered = false; if (info != null && info.getMeteredHint()) { metered = true; @@ -1029,21 +1060,34 @@ public class WifiConfiguration implements Parcelable { @SystemApi public int numAssociation; + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"RANDOMIZATION_"}, value = { + RANDOMIZATION_NONE, + RANDOMIZATION_PERSISTENT}) + public @interface MacRandomizationSetting {} + /** - * @hide * Use factory MAC when connecting to this network + * @hide */ + @SystemApi public static final int RANDOMIZATION_NONE = 0; /** - * @hide * Generate a randomized MAC once and reuse it for all connections to this network + * @hide */ + @SystemApi public static final int RANDOMIZATION_PERSISTENT = 1; /** + * Level of MAC randomization for this network. + * One of {@link #RANDOMIZATION_NONE} or {@link #RANDOMIZATION_PERSISTENT}. + * By default this field is set to {@link #RANDOMIZATION_PERSISTENT}. * @hide - * Level of MAC randomization for this network */ + @SystemApi + @MacRandomizationSetting public int macRandomizationSetting = RANDOMIZATION_PERSISTENT; /** @@ -1107,145 +1151,250 @@ public class WifiConfiguration implements Parcelable { public static final int HOME_NETWORK_RSSI_BOOST = 5; /** + * This class is used to contain all the information and API used for quality network selection. * @hide - * This class is used to contain all the information and API used for quality network selection */ + @SystemApi public static class NetworkSelectionStatus { - /** - * Quality Network Selection Status enable, temporary disabled, permanently disabled - */ + // Quality Network Selection Status enable, temporary disabled, permanently disabled /** * This network is allowed to join Quality Network Selection + * @hide */ public static final int NETWORK_SELECTION_ENABLED = 0; /** * network was temporary disabled. Can be re-enabled after a time period expire + * @hide */ public static final int NETWORK_SELECTION_TEMPORARY_DISABLED = 1; /** * network was permanently disabled. + * @hide */ public static final int NETWORK_SELECTION_PERMANENTLY_DISABLED = 2; /** * Maximum Network selection status + * @hide */ public static final int NETWORK_SELECTION_STATUS_MAX = 3; /** * Quality network selection status String (for debug purpose). Use Quality network * selection status value as index to extec the corresponding debug string + * @hide */ public static final String[] QUALITY_NETWORK_SELECTION_STATUS = { "NETWORK_SELECTION_ENABLED", "NETWORK_SELECTION_TEMPORARY_DISABLED", "NETWORK_SELECTION_PERMANENTLY_DISABLED"}; - //Quality Network disabled reasons - /** - * Default value. Means not disabled - */ + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(value = { + NETWORK_SELECTION_ENABLE, + DISABLED_ASSOCIATION_REJECTION, + DISABLED_AUTHENTICATION_FAILURE, + DISABLED_DHCP_FAILURE, + DISABLED_NO_INTERNET_TEMPORARY, + DISABLED_AUTHENTICATION_NO_CREDENTIALS, + DISABLED_NO_INTERNET_PERMANENT, + DISABLED_BY_WIFI_MANAGER, + DISABLED_BY_WRONG_PASSWORD, + DISABLED_AUTHENTICATION_NO_SUBSCRIPTION}) + public @interface NetworkSelectionDisableReason {} + + // Quality Network disabled reasons + /** Default value. Means not disabled. */ public static final int NETWORK_SELECTION_ENABLE = 0; /** - * The starting index for network selection disabled reasons + * The starting index for network selection disabled reasons. + * @hide */ public static final int NETWORK_SELECTION_DISABLED_STARTING_INDEX = 1; /** - * @deprecated it is not used any more. - * This network is disabled because higher layer (>2) network is bad - */ - public static final int DISABLED_BAD_LINK = 1; - /** - * This network is disabled because multiple association rejects - */ - public static final int DISABLED_ASSOCIATION_REJECTION = 2; - /** - * This network is disabled because multiple authentication failure - */ - public static final int DISABLED_AUTHENTICATION_FAILURE = 3; - /** - * This network is disabled because multiple DHCP failure - */ - public static final int DISABLED_DHCP_FAILURE = 4; - /** - * This network is disabled because of security network but no credentials - */ - public static final int DISABLED_DNS_FAILURE = 5; - /** - * This network is temporarily disabled because it has no Internet access. - */ - public static final int DISABLED_NO_INTERNET_TEMPORARY = 6; - /** - * This network is disabled because we started WPS - */ - public static final int DISABLED_WPS_START = 7; - /** - * This network is disabled because EAP-TLS failure - */ - public static final int DISABLED_TLS_VERSION_MISMATCH = 8; - // Values above are for temporary disablement; values below are for permanent disablement. - /** - * This network is disabled due to absence of user credentials - */ - public static final int DISABLED_AUTHENTICATION_NO_CREDENTIALS = 9; - /** - * This network is permanently disabled because it has no Internet access and user does not - * want to stay connected. - */ - public static final int DISABLED_NO_INTERNET_PERMANENT = 10; - /** - * This network is disabled due to WifiManager disable it explicitly - */ - public static final int DISABLED_BY_WIFI_MANAGER = 11; - /** - * This network is disabled due to user switching + * The starting index for network selection temporarily disabled reasons. + * @hide */ - public static final int DISABLED_DUE_TO_USER_SWITCH = 12; - /** - * This network is disabled due to wrong password + public static final int TEMPORARILY_DISABLED_STARTING_INDEX = 1; + /** This network is disabled because of multiple association rejections. */ + public static final int DISABLED_ASSOCIATION_REJECTION = 1; + /** This network is disabled because of multiple authentication failure. */ + public static final int DISABLED_AUTHENTICATION_FAILURE = 2; + /** This network is disabled because of multiple DHCP failure. */ + public static final int DISABLED_DHCP_FAILURE = 3; + /** This network is temporarily disabled because it has no Internet access. */ + public static final int DISABLED_NO_INTERNET_TEMPORARY = 4; + /** + * The starting index for network selection permanently disabled reasons. + * @hide */ - public static final int DISABLED_BY_WRONG_PASSWORD = 13; + public static final int PERMANENTLY_DISABLED_STARTING_INDEX = 5; + /** This network is disabled due to absence of user credentials */ + public static final int DISABLED_AUTHENTICATION_NO_CREDENTIALS = 5; /** - * This network is disabled because service is not subscribed + * This network is permanently disabled because it has no Internet access and the user does + * not want to stay connected. */ - public static final int DISABLED_AUTHENTICATION_NO_SUBSCRIPTION = 14; + public static final int DISABLED_NO_INTERNET_PERMANENT = 6; + /** This network is disabled due to WifiManager disabling it explicitly. */ + public static final int DISABLED_BY_WIFI_MANAGER = 7; + /** This network is disabled due to wrong password. */ + public static final int DISABLED_BY_WRONG_PASSWORD = 8; + /** This network is disabled because service is not subscribed. */ + public static final int DISABLED_AUTHENTICATION_NO_SUBSCRIPTION = 9; + /** All other disable reasons should be strictly less than this value. */ + public static final int NETWORK_SELECTION_DISABLED_MAX = 10; + /** - * This Maximum disable reason value + * Contains info about disable reasons. + * @hide */ - public static final int NETWORK_SELECTION_DISABLED_MAX = 15; + public static final class DisableReasonInfo { + /** + * String representation for the disable reason. + * Note that these strings are persisted in + * {@link + * com.android.server.wifi.util.XmlUtil.NetworkSelectionStatusXmlUtil#writeToXml}, + * so do not change the string values to maintain backwards compatibility. + */ + public final String mReasonStr; + /** + * Network Selection disable reason threshold, used to debounce network failures before + * we disable them. + */ + public final int mDisableThreshold; + /** + * Network Selection disable timeout for the error. After the timeout milliseconds, + * enable the network again. + */ + public final int mDisableTimeoutMillis; + + /** + * Constructor + * @param reasonStr string representation of the error + * @param disableThreshold number of failures before we disable the network + * @param disableTimeoutMillis the timeout, in milliseconds, before we re-enable the + * network after disabling it + */ + public DisableReasonInfo(String reasonStr, int disableThreshold, + int disableTimeoutMillis) { + mReasonStr = reasonStr; + mDisableThreshold = disableThreshold; + mDisableTimeoutMillis = disableTimeoutMillis; + } + } /** - * Quality network selection disable reason String (for debug purpose) + * Quality network selection disable reason infos. + * @hide */ - public static final String[] QUALITY_NETWORK_SELECTION_DISABLE_REASON = { - "NETWORK_SELECTION_ENABLE", - "NETWORK_SELECTION_DISABLED_BAD_LINK", // deprecated - "NETWORK_SELECTION_DISABLED_ASSOCIATION_REJECTION ", - "NETWORK_SELECTION_DISABLED_AUTHENTICATION_FAILURE", - "NETWORK_SELECTION_DISABLED_DHCP_FAILURE", - "NETWORK_SELECTION_DISABLED_DNS_FAILURE", - "NETWORK_SELECTION_DISABLED_NO_INTERNET_TEMPORARY", - "NETWORK_SELECTION_DISABLED_WPS_START", - "NETWORK_SELECTION_DISABLED_TLS_VERSION", - "NETWORK_SELECTION_DISABLED_AUTHENTICATION_NO_CREDENTIALS", - "NETWORK_SELECTION_DISABLED_NO_INTERNET_PERMANENT", - "NETWORK_SELECTION_DISABLED_BY_WIFI_MANAGER", - "NETWORK_SELECTION_DISABLED_BY_USER_SWITCH", - "NETWORK_SELECTION_DISABLED_BY_WRONG_PASSWORD", - "NETWORK_SELECTION_DISABLED_AUTHENTICATION_NO_SUBSCRIPTION" - }; + public static final SparseArray DISABLE_REASON_INFOS = + buildDisableReasonInfos(); + + private static SparseArray buildDisableReasonInfos() { + SparseArray reasons = new SparseArray<>(); + + reasons.append(NETWORK_SELECTION_ENABLE, + new DisableReasonInfo( + // Note that these strings are persisted in + // XmlUtil.NetworkSelectionStatusXmlUtil#writeToXml, + // so do not change the string values to maintain backwards + // compatibility. + "NETWORK_SELECTION_ENABLE", + -1, + Integer.MAX_VALUE)); + + reasons.append(DISABLED_ASSOCIATION_REJECTION, + new DisableReasonInfo( + // Note that there is a space at the end of this string. Cannot fix + // since this string is persisted. + "NETWORK_SELECTION_DISABLED_ASSOCIATION_REJECTION ", + 5, + 5 * 60 * 1000)); + + reasons.append(DISABLED_AUTHENTICATION_FAILURE, + new DisableReasonInfo( + "NETWORK_SELECTION_DISABLED_AUTHENTICATION_FAILURE", + 5, + 5 * 60 * 1000)); + + reasons.append(DISABLED_DHCP_FAILURE, + new DisableReasonInfo( + "NETWORK_SELECTION_DISABLED_DHCP_FAILURE", + 5, + 5 * 60 * 1000)); + + reasons.append(DISABLED_NO_INTERNET_TEMPORARY, + new DisableReasonInfo( + "NETWORK_SELECTION_DISABLED_NO_INTERNET_TEMPORARY", + 1, + 10 * 60 * 1000)); + + reasons.append(DISABLED_AUTHENTICATION_NO_CREDENTIALS, + new DisableReasonInfo( + "NETWORK_SELECTION_DISABLED_AUTHENTICATION_NO_CREDENTIALS", + 1, + Integer.MAX_VALUE)); + + reasons.append(DISABLED_NO_INTERNET_PERMANENT, + new DisableReasonInfo( + "NETWORK_SELECTION_DISABLED_NO_INTERNET_PERMANENT", + 1, + Integer.MAX_VALUE)); + + reasons.append(DISABLED_BY_WIFI_MANAGER, + new DisableReasonInfo( + "NETWORK_SELECTION_DISABLED_BY_WIFI_MANAGER", + 1, + Integer.MAX_VALUE)); + + reasons.append(DISABLED_BY_WRONG_PASSWORD, + new DisableReasonInfo( + "NETWORK_SELECTION_DISABLED_BY_WRONG_PASSWORD", + 1, + Integer.MAX_VALUE)); + + reasons.append(DISABLED_AUTHENTICATION_NO_SUBSCRIPTION, + new DisableReasonInfo( + "NETWORK_SELECTION_DISABLED_AUTHENTICATION_NO_SUBSCRIPTION", + 1, + Integer.MAX_VALUE)); + + return reasons; + } + + /** + * Get the {@link NetworkSelectionDisableReason} int code by its string value. + * @return the NetworkSelectionDisableReason int code corresponding to the reason string, + * or -1 if the reason string is unrecognized. + * @hide + */ + @NetworkSelectionDisableReason + public static int getDisableReasonByString(@NonNull String reasonString) { + for (int i = 0; i < DISABLE_REASON_INFOS.size(); i++) { + int key = DISABLE_REASON_INFOS.keyAt(i); + DisableReasonInfo value = DISABLE_REASON_INFOS.valueAt(i); + if (value != null && TextUtils.equals(reasonString, value.mReasonStr)) { + return key; + } + } + Log.e(TAG, "Unrecognized network disable reason: " + reasonString); + return -1; + } /** * Invalid time stamp for network selection disable + * @hide */ public static final long INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP = -1L; /** - * This constant indicates the current configuration has connect choice set + * This constant indicates the current configuration has connect choice set */ private static final int CONNECT_CHOICE_EXISTS = 1; /** - * This constant indicates the current configuration does not have connect choice set + * This constant indicates the current configuration does not have connect choice set */ private static final int CONNECT_CHOICE_NOT_EXISTS = -1; @@ -1259,6 +1408,7 @@ public class WifiConfiguration implements Parcelable { /** * Reason for disable this network */ + @NetworkSelectionDisableReason private int mNetworkSelectionDisableReason; /** @@ -1318,31 +1468,10 @@ public class WifiConfiguration implements Parcelable { */ private boolean mHasEverConnected; - /** - * Boolean indicating whether {@link com.android.server.wifi.RecommendedNetworkEvaluator} - * chose not to connect to this network in the last qualified network selection process. - */ - private boolean mNotRecommended; - - /** - * Set whether {@link com.android.server.wifi.RecommendedNetworkEvaluator} does not - * recommend connecting to this network. - */ - public void setNotRecommended(boolean notRecommended) { - mNotRecommended = notRecommended; - } - - /** - * Returns whether {@link com.android.server.wifi.RecommendedNetworkEvaluator} does not - * recommend connecting to this network. - */ - public boolean isNotRecommended() { - return mNotRecommended; - } - /** * set whether this network is visible in latest Qualified Network Selection * @param seen value set to candidate + * @hide */ public void setSeenInLastQualifiedNetworkSelection(boolean seen) { mSeenInLastQualifiedNetworkSelection = seen; @@ -1352,6 +1481,7 @@ public class WifiConfiguration implements Parcelable { * get whether this network is visible in latest Qualified Network Selection * @return returns true -- network is visible in latest Qualified Network Selection * false -- network is invisible in latest Qualified Network Selection + * @hide */ public boolean getSeenInLastQualifiedNetworkSelection() { return mSeenInLastQualifiedNetworkSelection; @@ -1359,6 +1489,7 @@ public class WifiConfiguration implements Parcelable { /** * set the temporary candidate of current network selection procedure * @param scanCandidate {@link ScanResult} the candidate set to mCandidate + * @hide */ public void setCandidate(ScanResult scanCandidate) { mCandidate = scanCandidate; @@ -1368,6 +1499,7 @@ public class WifiConfiguration implements Parcelable { * get the temporary candidate of current network selection procedure * @return returns {@link ScanResult} temporary candidate of current network selection * procedure + * @hide */ public ScanResult getCandidate() { return mCandidate; @@ -1376,6 +1508,7 @@ public class WifiConfiguration implements Parcelable { /** * set the score of the temporary candidate of current network selection procedure * @param score value set to mCandidateScore + * @hide */ public void setCandidateScore(int score) { mCandidateScore = score; @@ -1384,6 +1517,7 @@ public class WifiConfiguration implements Parcelable { /** * get the score of the temporary candidate of current network selection procedure * @return returns score of the temporary candidate of current network selection procedure + * @hide */ public int getCandidateScore() { return mCandidateScore; @@ -1391,7 +1525,8 @@ public class WifiConfiguration implements Parcelable { /** * get user preferred choice over this configuration - *@return returns configKey of user preferred choice over this configuration + * @return returns configKey of user preferred choice over this configuration + * @hide */ public String getConnectChoice() { return mConnectChoice; @@ -1400,6 +1535,7 @@ public class WifiConfiguration implements Parcelable { /** * set user preferred choice over this configuration * @param newConnectChoice, the configKey of user preferred choice over this configuration + * @hide */ public void setConnectChoice(String newConnectChoice) { mConnectChoice = newConnectChoice; @@ -1408,6 +1544,7 @@ public class WifiConfiguration implements Parcelable { /** * get the timeStamp when user select a choice over this configuration * @return returns when current connectChoice is set (time from System.currentTimeMillis) + * @hide */ public long getConnectChoiceTimestamp() { return mConnectChoiceTimestamp; @@ -1417,82 +1554,90 @@ public class WifiConfiguration implements Parcelable { * set the timeStamp when user select a choice over this configuration * @param timeStamp, the timestamp set to connectChoiceTimestamp, expected timestamp should * be obtained from System.currentTimeMillis + * @hide */ public void setConnectChoiceTimestamp(long timeStamp) { mConnectChoiceTimestamp = timeStamp; } - /** - * get current Quality network selection status - * @return returns current Quality network selection status in String (for debug purpose) - */ + /** Get the current Quality network selection status as a String (for debugging). */ + @NonNull public String getNetworkStatusString() { return QUALITY_NETWORK_SELECTION_STATUS[mStatus]; } + /** @hide */ public void setHasEverConnected(boolean value) { mHasEverConnected = value; } + /** True if the device has ever connected to this network, false otherwise. */ public boolean getHasEverConnected() { return mHasEverConnected; } + /** @hide */ public NetworkSelectionStatus() { // previously stored configs will not have this parameter, so we default to false. mHasEverConnected = false; - }; + } /** - * @param reason specific error reason - * @return corresponding network disable reason String (for debug purpose) + * Get the network disable reason string for a reason code (for debugging). + * @param reason specific error reason. One of the {@link #NETWORK_SELECTION_ENABLE} or + * DISABLED_* constants e.g. {@link #DISABLED_ASSOCIATION_REJECTION}. + * @return network disable reason string, or null if the reason is invalid. */ - public static String getNetworkDisableReasonString(int reason) { - if (reason >= NETWORK_SELECTION_ENABLE && reason < NETWORK_SELECTION_DISABLED_MAX) { - return QUALITY_NETWORK_SELECTION_DISABLE_REASON[reason]; - } else { + @Nullable + public static String getNetworkDisableReasonString( + @NetworkSelectionDisableReason int reason) { + DisableReasonInfo info = DISABLE_REASON_INFOS.get(reason); + if (info == null) { return null; + } else { + return info.mReasonStr; } } /** * get current network disable reason * @return current network disable reason in String (for debug purpose) + * @hide */ public String getNetworkDisableReasonString() { - return QUALITY_NETWORK_SELECTION_DISABLE_REASON[mNetworkSelectionDisableReason]; + return getNetworkDisableReasonString(mNetworkSelectionDisableReason); } /** * get current network network selection status * @return return current network network selection status + * @hide */ public int getNetworkSelectionStatus() { return mStatus; } - /** - * @return whether current network is enabled to join network selection - */ + + /** True if the current network is enabled to join network selection, false otherwise. */ public boolean isNetworkEnabled() { return mStatus == NETWORK_SELECTION_ENABLED; } /** * @return whether current network is temporary disabled + * @hide */ public boolean isNetworkTemporaryDisabled() { return mStatus == NETWORK_SELECTION_TEMPORARY_DISABLED; } - /** - * @return returns whether current network is permanently disabled - */ + /** True if the current network is permanently disabled, false otherwise. */ public boolean isNetworkPermanentlyDisabled() { return mStatus == NETWORK_SELECTION_PERMANENTLY_DISABLED; } /** - * set current networ work selection status + * set current network selection status * @param status network selection status to set + * @hide */ public void setNetworkSelectionStatus(int status) { if (status >= 0 && status < NETWORK_SELECTION_STATUS_MAX) { @@ -1501,17 +1646,21 @@ public class WifiConfiguration implements Parcelable { } /** - * @return returns current network's disable reason + * Returns the current network's disable reason. + * One of the {@link #NETWORK_SELECTION_ENABLE} or DISABLED_* constants + * e.g. {@link #DISABLED_ASSOCIATION_REJECTION}. */ + @NetworkSelectionDisableReason public int getNetworkSelectionDisableReason() { return mNetworkSelectionDisableReason; } /** * set Network disable reason - * @param reason Network disable reason + * @param reason Network disable reason + * @hide */ - public void setNetworkSelectionDisableReason(int reason) { + public void setNetworkSelectionDisableReason(@NetworkSelectionDisableReason int reason) { if (reason >= 0 && reason < NETWORK_SELECTION_DISABLED_MAX) { mNetworkSelectionDisableReason = reason; } else { @@ -1519,39 +1668,31 @@ public class WifiConfiguration implements Parcelable { } } - /** - * check whether network is disabled by this reason - * @param reason a specific disable reason - * @return true -- network is disabled for this reason - * false -- network is not disabled for this reason - */ - public boolean isDisabledByReason(int reason) { - return mNetworkSelectionDisableReason == reason; - } - /** * @param timeStamp Set when current network is disabled in millisecond since January 1, * 1970 00:00:00.0 UTC + * @hide */ public void setDisableTime(long timeStamp) { mTemporarilyDisabledTimestamp = timeStamp; } /** - * @return returns when current network is disabled in millisecond since January 1, - * 1970 00:00:00.0 UTC + * Returns when the current network was disabled, in milliseconds since January 1, + * 1970 00:00:00.0 UTC. */ public long getDisableTime() { return mTemporarilyDisabledTimestamp; } /** - * get the disable counter of a specific reason - * @param reason specific failure reason - * @exception throw IllegalArgumentException for illegal input + * Get the disable counter of a specific reason. + * @param reason specific failure reason. One of the {@link #NETWORK_SELECTION_ENABLE} or + * DISABLED_* constants e.g. {@link #DISABLED_ASSOCIATION_REJECTION}. + * @exception IllegalArgumentException for invalid reason * @return counter number for specific error reason. */ - public int getDisableReasonCounter(int reason) { + public int getDisableReasonCounter(@NetworkSelectionDisableReason int reason) { if (reason >= NETWORK_SELECTION_ENABLE && reason < NETWORK_SELECTION_DISABLED_MAX) { return mNetworkSeclectionDisableCounter[reason]; } else { @@ -1564,6 +1705,7 @@ public class WifiConfiguration implements Parcelable { * @param reason reason for disable error * @param value the counter value for this specific reason * @exception throw IllegalArgumentException for illegal input + * @hide */ public void setDisableReasonCounter(int reason, int value) { if (reason >= NETWORK_SELECTION_ENABLE && reason < NETWORK_SELECTION_DISABLED_MAX) { @@ -1577,6 +1719,7 @@ public class WifiConfiguration implements Parcelable { * increment the counter of a specific failure reason * @param reason a specific failure reason * @exception throw IllegalArgumentException for illegal input + * @hide */ public void incrementDisableReasonCounter(int reason) { if (reason >= NETWORK_SELECTION_ENABLE && reason < NETWORK_SELECTION_DISABLED_MAX) { @@ -1588,9 +1731,9 @@ public class WifiConfiguration implements Parcelable { /** * clear the counter of a specific failure reason - * @hide * @param reason a specific failure reason * @exception throw IllegalArgumentException for illegal input + * @hide */ public void clearDisableReasonCounter(int reason) { if (reason >= NETWORK_SELECTION_ENABLE && reason < NETWORK_SELECTION_DISABLED_MAX) { @@ -1602,6 +1745,7 @@ public class WifiConfiguration implements Parcelable { /** * clear all the failure reason counters + * @hide */ public void clearDisableReasonCounter() { Arrays.fill(mNetworkSeclectionDisableCounter, NETWORK_SELECTION_ENABLE); @@ -1615,6 +1759,7 @@ public class WifiConfiguration implements Parcelable { /** * get current network Selection BSSID * @return current network Selection BSSID + * @hide */ public String getNetworkSelectionBSSID() { return mNetworkSelectionBSSID; @@ -1623,11 +1768,13 @@ public class WifiConfiguration implements Parcelable { /** * set network Selection BSSID * @param bssid The target BSSID for assocaition + * @hide */ public void setNetworkSelectionBSSID(String bssid) { mNetworkSelectionBSSID = bssid; } + /** @hide */ public void copy(NetworkSelectionStatus source) { mStatus = source.mStatus; mNetworkSelectionDisableReason = source.mNetworkSelectionDisableReason; @@ -1644,9 +1791,9 @@ public class WifiConfiguration implements Parcelable { setConnectChoice(source.getConnectChoice()); setConnectChoiceTimestamp(source.getConnectChoiceTimestamp()); setHasEverConnected(source.getHasEverConnected()); - setNotRecommended(source.isNotRecommended()); } + /** @hide */ public void writeToParcel(Parcel dest) { dest.writeInt(getNetworkSelectionStatus()); dest.writeInt(getNetworkSelectionDisableReason()); @@ -1664,9 +1811,9 @@ public class WifiConfiguration implements Parcelable { dest.writeInt(CONNECT_CHOICE_NOT_EXISTS); } dest.writeInt(getHasEverConnected() ? 1 : 0); - dest.writeInt(isNotRecommended() ? 1 : 0); } + /** @hide */ public void readFromParcel(Parcel in) { setNetworkSelectionStatus(in.readInt()); setNetworkSelectionDisableReason(in.readInt()); @@ -1684,7 +1831,6 @@ public class WifiConfiguration implements Parcelable { setConnectChoiceTimestamp(INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP); } setHasEverConnected(in.readInt() != 0); - setNotRecommended(in.readInt() != 0); } } @@ -1699,8 +1845,16 @@ public class WifiConfiguration implements Parcelable { * This class is intended to store extra failure reason information for the most recent * connection attempt, so that it may be surfaced to the settings UI */ + @SystemApi public static class RecentFailure { + private RecentFailure() {} + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(value = {NONE, STATUS_AP_UNABLE_TO_HANDLE_NEW_STA}) + public @interface AssociationStatus {} + /** * No recent failure, or no specific reason given for the recent connection failure */ @@ -1713,38 +1867,47 @@ public class WifiConfiguration implements Parcelable { /** * Association Rejection Status code (NONE for success/non-association-rejection-fail) */ + @AssociationStatus private int mAssociationStatus = NONE; /** * @param status the association status code for the recent failure + * @hide */ - public void setAssociationStatus(int status) { + public void setAssociationStatus(@AssociationStatus int status) { mAssociationStatus = status; } /** * Sets the RecentFailure to NONE + * @hide */ public void clear() { mAssociationStatus = NONE; } /** - * Get the recent failure code + * Get the recent failure code. One of {@link #NONE} or + * {@link #STATUS_AP_UNABLE_TO_HANDLE_NEW_STA}. */ + @AssociationStatus public int getAssociationStatus() { return mAssociationStatus; } } /** - * @hide * RecentFailure member + * @hide */ - final public RecentFailure recentFailure = new RecentFailure(); + @NonNull + @SystemApi + public final RecentFailure recentFailure = new RecentFailure(); /** + * Get the network selection status. * @hide - * @return network selection status */ + @NonNull + @SystemApi public NetworkSelectionStatus getNetworkSelectionStatus() { return mNetworkSelectionStatus; } @@ -1787,8 +1950,6 @@ public class WifiConfiguration implements Parcelable { wepKeys[i] = null; } enterpriseConfig = new WifiEnterpriseConfig(); - selfAdded = false; - didSelfAdd = false; ephemeral = false; osu = false; trusted = true; // Networks are considered trusted by default. @@ -1900,8 +2061,6 @@ public class WifiConfiguration implements Parcelable { if (this.creationTime != null) { sbuf.append(" creation ").append(this.creationTime).append("\n"); } - if (this.didSelfAdd) sbuf.append(" didSelfAdd"); - if (this.selfAdded) sbuf.append(" selfAdded"); if (this.validatedInternetAccess) sbuf.append(" validatedInternetAccess"); if (this.ephemeral) sbuf.append(" ephemeral"); if (this.osu) sbuf.append(" osu"); @@ -1910,9 +2069,9 @@ public class WifiConfiguration implements Parcelable { if (this.fromWifiNetworkSpecifier) sbuf.append(" fromWifiNetworkSpecifier"); if (this.meteredHint) sbuf.append(" meteredHint"); if (this.useExternalScores) sbuf.append(" useExternalScores"); - if (this.didSelfAdd || this.selfAdded || this.validatedInternetAccess - || this.ephemeral || this.trusted || this.fromWifiNetworkSuggestion - || this.fromWifiNetworkSpecifier || this.meteredHint || this.useExternalScores) { + if (this.validatedInternetAccess || this.ephemeral || this.trusted + || this.fromWifiNetworkSuggestion || this.fromWifiNetworkSpecifier + || this.meteredHint || this.useExternalScores) { sbuf.append("\n"); } if (this.meteredOverride != METERED_OVERRIDE_NONE) { @@ -2040,7 +2199,6 @@ public class WifiConfiguration implements Parcelable { if (lastUpdateName != null) sbuf.append(" lname=" + lastUpdateName); if (updateIdentifier != null) sbuf.append(" updateIdentifier=" + updateIdentifier); sbuf.append(" lcuid=" + lastConnectUid); - sbuf.append(" userApproved=" + userApprovedAsString(userApproved)); sbuf.append(" allowAutojoin=" + allowAutojoin); sbuf.append(" noInternetAccessExpected=" + noInternetAccessExpected); sbuf.append(" "); @@ -2062,8 +2220,13 @@ public class WifiConfiguration implements Parcelable { return sbuf.toString(); } - /** {@hide} */ - @UnsupportedAppUsage + /** + * Get the SSID in a human-readable format, with all additional formatting removed + * e.g. quotation marks around the SSID, "P" prefix + * @hide + */ + @NonNull + @SystemApi public String getPrintableSsid() { if (SSID == null) return ""; final int length = SSID.length(); @@ -2071,7 +2234,7 @@ public class WifiConfiguration implements Parcelable { return SSID.substring(1, length - 1); } - /** The ascii-encoded string format is P"" + /* The ascii-encoded string format is P"" * The decoding is implemented in the supplicant for a newly configured * network. */ @@ -2084,20 +2247,6 @@ public class WifiConfiguration implements Parcelable { return SSID; } - /** @hide **/ - public static String userApprovedAsString(int userApproved) { - switch (userApproved) { - case USER_APPROVED: - return "USER_APPROVED"; - case USER_BANNED: - return "USER_BANNED"; - case USER_UNSPECIFIED: - return "USER_UNSPECIFIED"; - default: - return "INVALID"; - } - } - /** * Get an identifier for associating credentials with this config * @param current configuration contains values for additional fields @@ -2166,8 +2315,13 @@ public class WifiConfiguration implements Parcelable { } } - /** @hide */ - @UnsupportedAppUsage + /** + * Get the authentication type of the network. + * @return One of the {@link KeyMgmt} constants. e.g. {@link KeyMgmt#WPA2_PSK}. + * @hide + */ + @SystemApi + @KeyMgmt.KeyMgmtScheme public int getAuthType() { if (allowedKeyManagement.cardinality() > 1) { throw new IllegalStateException("More than one auth type set"); @@ -2256,15 +2410,25 @@ public class WifiConfiguration implements Parcelable { return mIpConfiguration; } - /** @hide */ - @UnsupportedAppUsage - public void setIpConfiguration(IpConfiguration ipConfiguration) { + /** + * Set the {@link IpConfiguration} for this network. + * @param ipConfiguration the {@link IpConfiguration} to set, or null to use the default + * constructor {@link IpConfiguration#IpConfiguration()}. + * @hide + */ + @SystemApi + public void setIpConfiguration(@Nullable IpConfiguration ipConfiguration) { if (ipConfiguration == null) ipConfiguration = new IpConfiguration(); mIpConfiguration = ipConfiguration; } - /** @hide */ - @UnsupportedAppUsage + /** + * Get the {@link StaticIpConfiguration} for this network. + * @return the {@link StaticIpConfiguration}, or null if unset. + * @hide + */ + @Nullable + @SystemApi public StaticIpConfiguration getStaticIpConfiguration() { return mIpConfiguration.getStaticIpConfiguration(); } @@ -2275,8 +2439,12 @@ public class WifiConfiguration implements Parcelable { mIpConfiguration.setStaticIpConfiguration(staticIpConfiguration); } - /** @hide */ - @UnsupportedAppUsage + /** + * Get the {@link IpConfiguration.IpAssignment} for this network. + * @hide + */ + @NonNull + @SystemApi public IpConfiguration.IpAssignment getIpAssignment() { return mIpConfiguration.ipAssignment; } @@ -2287,8 +2455,12 @@ public class WifiConfiguration implements Parcelable { mIpConfiguration.ipAssignment = ipAssignment; } - /** @hide */ - @UnsupportedAppUsage + /** + * Get the {@link IpConfiguration.ProxySettings} for this network. + * @hide + */ + @NonNull + @SystemApi public IpConfiguration.ProxySettings getProxySettings() { return mIpConfiguration.proxySettings; } @@ -2347,9 +2519,12 @@ public class WifiConfiguration implements Parcelable { mIpConfiguration.setHttpProxy(httpProxyCopy); } - /** @hide */ - @UnsupportedAppUsage - public void setProxy(ProxySettings settings, ProxyInfo proxy) { + /** + * Set the {@link ProxySettings} and {@link ProxyInfo} for this network. + * @hide + */ + @SystemApi + public void setProxy(@NonNull ProxySettings settings, @NonNull ProxyInfo proxy) { mIpConfiguration.proxySettings = settings; mIpConfiguration.httpProxy = proxy; } @@ -2415,7 +2590,6 @@ public class WifiConfiguration implements Parcelable { linkedConfigurations.putAll(source.linkedConfigurations); } mCachedConfigKey = null; //force null configKey - selfAdded = source.selfAdded; validatedInternetAccess = source.validatedInternetAccess; isLegacyPasspointConfig = source.isLegacyPasspointConfig; ephemeral = source.ephemeral; @@ -2427,7 +2601,6 @@ public class WifiConfiguration implements Parcelable { meteredOverride = source.meteredOverride; useExternalScores = source.useExternalScores; - didSelfAdd = source.didSelfAdd; lastConnectUid = source.lastConnectUid; lastUpdateUid = source.lastUpdateUid; creatorUid = source.creatorUid; @@ -2440,7 +2613,6 @@ public class WifiConfiguration implements Parcelable { numScorerOverride = source.numScorerOverride; numScorerOverrideAndSwitchedNetwork = source.numScorerOverrideAndSwitchedNetwork; numAssociation = source.numAssociation; - userApproved = source.userApproved; allowAutojoin = source.allowAutojoin; numNoInternetAccessReports = source.numNoInternetAccessReports; noInternetAccessExpected = source.noInternetAccessExpected; @@ -2498,8 +2670,6 @@ public class WifiConfiguration implements Parcelable { dest.writeParcelable(mIpConfiguration, flags); dest.writeString(dhcpServer); dest.writeString(defaultGwMacAddress); - dest.writeInt(selfAdded ? 1 : 0); - dest.writeInt(didSelfAdd ? 1 : 0); dest.writeInt(validatedInternetAccess ? 1 : 0); dest.writeInt(isLegacyPasspointConfig ? 1 : 0); dest.writeInt(ephemeral ? 1 : 0); @@ -2517,7 +2687,6 @@ public class WifiConfiguration implements Parcelable { dest.writeInt(numScorerOverride); dest.writeInt(numScorerOverrideAndSwitchedNetwork); dest.writeInt(numAssociation); - dest.writeInt(userApproved); dest.writeBoolean(allowAutojoin); dest.writeInt(numNoInternetAccessReports); dest.writeInt(noInternetAccessExpected ? 1 : 0); @@ -2575,8 +2744,6 @@ public class WifiConfiguration implements Parcelable { config.setIpConfiguration(in.readParcelable(null)); config.dhcpServer = in.readString(); config.defaultGwMacAddress = in.readString(); - config.selfAdded = in.readInt() != 0; - config.didSelfAdd = in.readInt() != 0; config.validatedInternetAccess = in.readInt() != 0; config.isLegacyPasspointConfig = in.readInt() != 0; config.ephemeral = in.readInt() != 0; @@ -2594,7 +2761,6 @@ public class WifiConfiguration implements Parcelable { config.numScorerOverride = in.readInt(); config.numScorerOverrideAndSwitchedNetwork = in.readInt(); config.numAssociation = in.readInt(); - config.userApproved = in.readInt(); config.allowAutojoin = in.readBoolean(); config.numNoInternetAccessReports = in.readInt(); config.noInternetAccessExpected = in.readInt() != 0; @@ -2615,9 +2781,11 @@ public class WifiConfiguration implements Parcelable { }; /** - * Serializes the object for backup + * Serialize the Soft AP configuration contained in this object for backup. * @hide */ + @NonNull + // TODO(b/144368124): this method should be removed once we migrate to SoftApConfiguration public byte[] getBytesForBackup() throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream out = new DataOutputStream(baos); @@ -2633,11 +2801,16 @@ public class WifiConfiguration implements Parcelable { } /** - * Deserializes a byte array into the WiFiConfiguration Object + * Deserialize a byte array containing Soft AP configuration into a WifiConfiguration object. + * @return The deserialized WifiConfiguration containing Soft AP configuration, or null if + * the version contains a bad dataset e.g. Version 1 + * @throws BackupUtils.BadVersionException if the version is unrecognized * @hide */ - public static WifiConfiguration getWifiConfigFromBackup(DataInputStream in) throws IOException, - BackupUtils.BadVersionException { + @Nullable + // TODO(b/144368124): this method should be removed once we migrate to SoftApConfiguration + public static WifiConfiguration getWifiConfigFromBackup(@NonNull DataInputStream in) + throws IOException, BackupUtils.BadVersionException { WifiConfiguration config = new WifiConfiguration(); int version = in.readInt(); if (version < 1 || version > BACKUP_VERSION) { diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java index 7b99a2b5502f..449f95e8a161 100644 --- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java +++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java @@ -16,7 +16,9 @@ package android.net.wifi; import android.annotation.IntDef; +import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; @@ -118,18 +120,21 @@ public class WifiEnterpriseConfig implements Parcelable { * Do not use OCSP stapling (TLS certificate status extension) * @hide */ + @SystemApi public static final int OCSP_NONE = 0; /** * Try to use OCSP stapling, but not require response * @hide */ + @SystemApi public static final int OCSP_REQUEST_CERT_STATUS = 1; /** * Require valid OCSP stapling response * @hide */ + @SystemApi public static final int OCSP_REQUIRE_CERT_STATUS = 2; /** @@ -137,6 +142,7 @@ public class WifiEnterpriseConfig implements Parcelable { * certificate chain * @hide */ + @SystemApi public static final int OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS = 3; /** @hide */ @@ -147,8 +153,7 @@ public class WifiEnterpriseConfig implements Parcelable { OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS }) @Retention(RetentionPolicy.SOURCE) - public @interface Ocsp { - } + public @interface Ocsp {} /** * Whether to use/require OCSP (Online Certificate Status Protocol) to check server certificate. @@ -636,9 +641,11 @@ public class WifiEnterpriseConfig implements Parcelable { *

    See the {@link android.security.KeyChain} for details on installing or choosing * a certificate. *

    - * @param aliases identifies the certificate + * @param aliases identifies the certificate. Can be null to indicate the absence of a + * certificate. * @hide */ + @SystemApi public void setCaCertificateAliases(@Nullable String[] aliases) { if (aliases == null) { setFieldValue(CA_CERT_KEY, null, CA_CERT_PREFIX); @@ -669,11 +676,13 @@ public class WifiEnterpriseConfig implements Parcelable { } /** - * Get CA certificate aliases - * @return alias to the CA certificate + * Get CA certificate aliases. + * @return alias to the CA certificate, or null if unset. * @hide */ - @Nullable public String[] getCaCertificateAliases() { + @Nullable + @SystemApi + public String[] getCaCertificateAliases() { String value = getFieldValue(CA_CERT_KEY); if (value.startsWith(CA_CERT_PREFIX)) { // Backwards compatibility: parse the original alias prefix. @@ -792,32 +801,36 @@ public class WifiEnterpriseConfig implements Parcelable { * like /etc/ssl/certs. If configured, these certificates are added to the * list of trusted CAs. ca_cert may also be included in that case, but it is * not required. - * @param domain The path for CA certificate files + * @param path The path for CA certificate files, or null/empty string to clear. * @hide */ - public void setCaPath(String path) { + @SystemApi + public void setCaPath(@Nullable String path) { setFieldValue(CA_PATH_KEY, path); } /** * Get the domain_suffix_match value. See setDomSuffixMatch. - * @return The path for CA certificate files. + * @return The path for CA certificate files, or an empty string if unset. * @hide */ + @NonNull + @SystemApi public String getCaPath() { return getFieldValue(CA_PATH_KEY); } - /** Set Client certificate alias. + /** + * Set Client certificate alias. * *

    See the {@link android.security.KeyChain} for details on installing or choosing * a certificate *

    - * @param alias identifies the certificate + * @param alias identifies the certificate, or null/empty string to clear. * @hide */ - @UnsupportedAppUsage - public void setClientCertificateAlias(String alias) { + @SystemApi + public void setClientCertificateAlias(@Nullable String alias) { setFieldValue(CLIENT_CERT_KEY, alias, CLIENT_CERT_PREFIX); setFieldValue(PRIVATE_KEY_ID_KEY, alias, Credentials.USER_PRIVATE_KEY); // Also, set engine parameters @@ -831,11 +844,12 @@ public class WifiEnterpriseConfig implements Parcelable { } /** - * Get client certificate alias - * @return alias to the client certificate + * Get client certificate alias. + * @return alias to the client certificate, or an empty string if unset. * @hide */ - @UnsupportedAppUsage + @NonNull + @SystemApi public String getClientCertificateAlias() { return getFieldValue(CLIENT_CERT_KEY, CLIENT_CERT_PREFIX); } @@ -1241,12 +1255,14 @@ public class WifiEnterpriseConfig implements Parcelable { } /** - * Set the ocsp type. - * @param ocsp is one {@link ##OCSP_NONE}, {@link #OCSP_REQUEST_CERT_STATUS}, + * Set the OCSP type. + * @param ocsp is one of {@link ##OCSP_NONE}, {@link #OCSP_REQUEST_CERT_STATUS}, * {@link #OCSP_REQUIRE_CERT_STATUS} or * {@link #OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS} + * @throws IllegalArgumentException if the OCSP type is invalid * @hide */ + @SystemApi public void setOcsp(@Ocsp int ocsp) { if (ocsp >= OCSP_NONE && ocsp <= OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS) { mOcsp = ocsp; @@ -1256,10 +1272,10 @@ public class WifiEnterpriseConfig implements Parcelable { } /** - * Get the ocsp type. - * @return ocsp type + * Get the OCSP type. * @hide */ + @SystemApi public @Ocsp int getOcsp() { return mOcsp; } diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java index 6d7e621a9bc2..7e38e147427f 100644 --- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java @@ -19,6 +19,7 @@ package android.net.wifi; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import android.net.MacAddress; @@ -89,37 +90,6 @@ public class WifiConfigurationTest { assertArrayEquals(bytes, rebytes); } - @Test - public void testNetworkSelectionStatusCopy() { - NetworkSelectionStatus networkSelectionStatus = new NetworkSelectionStatus(); - networkSelectionStatus.setNotRecommended(true); - - NetworkSelectionStatus copy = new NetworkSelectionStatus(); - copy.copy(networkSelectionStatus); - - assertEquals(networkSelectionStatus.isNotRecommended(), copy.isNotRecommended()); - } - - @Test - public void testNetworkSelectionStatusParcel() { - NetworkSelectionStatus networkSelectionStatus = new NetworkSelectionStatus(); - networkSelectionStatus.setNotRecommended(true); - - Parcel parcelW = Parcel.obtain(); - networkSelectionStatus.writeToParcel(parcelW); - byte[] bytes = parcelW.marshall(); - parcelW.recycle(); - - Parcel parcelR = Parcel.obtain(); - parcelR.unmarshall(bytes, 0, bytes.length); - parcelR.setDataPosition(0); - - NetworkSelectionStatus copy = new NetworkSelectionStatus(); - copy.readFromParcel(parcelR); - - assertEquals(networkSelectionStatus.isNotRecommended(), copy.isNotRecommended()); - } - @Test public void testIsOpenNetwork_IsOpen_NullWepKeys() { WifiConfiguration config = new WifiConfiguration(); @@ -348,4 +318,18 @@ public class WifiConfigurationTest { config.allowedKeyManagement.set(KeyMgmt.NONE); assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.NONE], config.getSsidAndSecurityTypeString()); } + + /** + * Ensure that the {@link NetworkSelectionStatus.DisableReasonInfo}s are populated in + * {@link NetworkSelectionStatus#DISABLE_REASON_INFOS} for reason codes from 0 to + * {@link NetworkSelectionStatus#NETWORK_SELECTION_DISABLED_MAX} - 1. + */ + @Test + public void testNetworkSelectionDisableReasonInfosPopulated() { + assertEquals(NetworkSelectionStatus.NETWORK_SELECTION_DISABLED_MAX, + NetworkSelectionStatus.DISABLE_REASON_INFOS.size()); + for (int i = 0; i < NetworkSelectionStatus.NETWORK_SELECTION_DISABLED_MAX; i++) { + assertNotNull(NetworkSelectionStatus.DISABLE_REASON_INFOS.get(i)); + } + } } -- cgit v1.2.3 From 10bc5db45af67d017b06814b9993815eec78694a Mon Sep 17 00:00:00 2001 From: "Nate(Qiang) Jiang" Date: Wed, 20 Nov 2019 10:23:23 -0800 Subject: User binder as identifier for scanResultcallback Bug: 143138047 Test: atest android.net.wifi Test: atest com.android.server.wifi Change-Id: I91d68b247490ac33656decc519c39c77bfe786a4 --- .../android/net/wifi/IScanResultsCallback.aidl | 27 +++++ .../android/net/wifi/IScanResultsListener.aidl | 7 +- wifi/java/android/net/wifi/IWifiManager.aidl | 6 +- wifi/java/android/net/wifi/WifiManager.java | 113 ++++++++++++++------- .../com/android/server/wifi/BaseWifiService.java | 17 +++- .../src/android/net/wifi/WifiManagerTest.java | 87 ++++++++++------ 6 files changed, 178 insertions(+), 79 deletions(-) create mode 100644 wifi/java/android/net/wifi/IScanResultsCallback.aidl (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IScanResultsCallback.aidl b/wifi/java/android/net/wifi/IScanResultsCallback.aidl new file mode 100644 index 000000000000..56f602510fd9 --- /dev/null +++ b/wifi/java/android/net/wifi/IScanResultsCallback.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 IScanResultsCallback +{ + void onScanResultsAvailable(); +} diff --git a/wifi/java/android/net/wifi/IScanResultsListener.aidl b/wifi/java/android/net/wifi/IScanResultsListener.aidl index bec74a620380..e7eaddd712c9 100644 --- a/wifi/java/android/net/wifi/IScanResultsListener.aidl +++ b/wifi/java/android/net/wifi/IScanResultsListener.aidl @@ -16,11 +16,8 @@ package android.net.wifi; -/** - * Interface for Wi-Fi scan result available callback. - * - * @hide - */ +/** @hide */ + oneway interface IScanResultsListener { void onScanResultsAvailable(); diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 4619372e2258..4a89c66dd0a0 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -28,7 +28,7 @@ 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.IScanResultsCallback; import android.net.wifi.ISoftApCallback; import android.net.wifi.ISuggestionConnectionStatusListener; import android.net.wifi.ITrafficStateCallback; @@ -233,9 +233,9 @@ interface IWifiManager oneway void getTxPacketCount(String packageName, in IBinder binder, in ITxPacketCountListener listener, int callbackIdentifier); - void registerScanResultsListener(in IBinder binder, in IScanResultsListener Listener, int listenerIdentifier); + void registerScanResultsCallback(in IScanResultsCallback callback); - void unregisterScanResultsListener(int listenerIdentifier); + void unregisterScanResultsCallback(in IScanResultsCallback callback); void registerSuggestionConnectionStatusListener(in IBinder binder, in ISuggestionConnectionStatusListener listener, int listenerIdentifier, String packageName, String featureId); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 942d795a45ca..2a0211b77450 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -5453,40 +5453,76 @@ public class WifiManager { } /** - * Interface for scan results listener. Should be implemented by applications and set when - * calling {@link WifiManager#addScanResultsListener(Executor, ScanResultsListener)}. + * Abstract class for scan results callback. Should be extended by applications and set when + * calling {@link WifiManager#registerScanResultsCallback(Executor, ScanResultsCallback)}. */ - public interface ScanResultsListener { + public abstract static class ScanResultsCallback { + private final ScanResultsCallbackProxy mScanResultsCallbackProxy; + + public ScanResultsCallback() { + mScanResultsCallbackProxy = new ScanResultsCallbackProxy(); + } /** - * Called when new scan results available. - * Caller should use {@link WifiManager#getScanResults()} to get the scan results. + * Called when new scan results are available. + * Clients 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; + public abstract void onScanResultsAvailable(); - ScanResultsListenerProxy(Executor executor, ScanResultsListener listener) { - mExecutor = executor; - mListener = listener; + /*package*/ @NonNull ScanResultsCallbackProxy getProxy() { + return mScanResultsCallbackProxy; } - @Override - public void onScanResultsAvailable() { - mExecutor.execute(mListener::onScanResultsAvailable); + private static class ScanResultsCallbackProxy extends IScanResultsCallback.Stub { + private final Object mLock = new Object(); + @Nullable @GuardedBy("mLock") private Executor mExecutor; + @Nullable @GuardedBy("mLock") private ScanResultsCallback mCallback; + + ScanResultsCallbackProxy() { + mCallback = null; + mExecutor = null; + } + + /*package*/ void initProxy(@NonNull Executor executor, + @NonNull ScanResultsCallback callback) { + synchronized (mLock) { + mExecutor = executor; + mCallback = callback; + } + } + + /*package*/ void cleanUpProxy() { + synchronized (mLock) { + mExecutor = null; + mCallback = null; + } + } + + @Override + public void onScanResultsAvailable() { + ScanResultsCallback callback; + Executor executor; + synchronized (mLock) { + executor = mExecutor; + callback = mCallback; + } + if (callback == null || executor == null) { + return; + } + Binder.clearCallingIdentity(); + executor.execute(callback::onScanResultsAvailable); + } } + } /** - * Add a listener for Scan Results. See {@link ScanResultsListener}. + * Register a callback for Scan Results. See {@link ScanResultsCallback}. * Caller will receive the event when scan results are available. * Caller should use {@link WifiManager#getScanResults()} requires * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} to get the scan results. - * Caller can remove a previously registered listener using - * {@link WifiManager#removeScanResultsListener(ScanResultsListener)} + * Caller can remove a previously registered callback using + * {@link WifiManager#unregisterScanResultsCallback(ScanResultsCallback)} * Same caller can add multiple listeners. *

    * Applications should have the @@ -5494,49 +5530,52 @@ public class WifiManager { * without the permission will trigger a {@link java.lang.SecurityException}. *

    * - * @param executor The executor to execute the listener of the {@code listener} object. - * @param listener listener for Scan Results events + * @param executor The executor to execute the callback of the {@code callback} object. + * @param callback callback 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"); + public void registerScanResultsCallback(@NonNull @CallbackExecutor Executor executor, + @NonNull ScanResultsCallback callback) { if (executor == null) throw new IllegalArgumentException("executor cannot be null"); - Log.v(TAG, "addScanResultsListener: listener=" + listener + ", executor=" + executor); + if (callback == null) throw new IllegalArgumentException("callback cannot be null"); + + Log.v(TAG, "registerScanResultsCallback: callback=" + callback + + ", executor=" + executor); + ScanResultsCallback.ScanResultsCallbackProxy proxy = callback.getProxy(); + proxy.initProxy(executor, callback); try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) { throw new RemoteException("Wifi service is not running"); } - iWifiManager.registerScanResultsListener( - new Binder(), - new ScanResultsListenerProxy(executor, listener), - listener.hashCode()); + iWifiManager.registerScanResultsCallback(proxy); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** - * Allow callers to remove a previously added listener. After calling this method, + * Allow callers to unregister a previously registered callback. After calling this method, * applications will no longer receive Scan Results events. * - * @param listener listener to remove for Scan Results events + * @param callback callback to unregister 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); - + public void unregisterScanResultsCallback(@NonNull ScanResultsCallback callback) { + if (callback == null) throw new IllegalArgumentException("callback cannot be null"); + Log.v(TAG, "unregisterScanResultsCallback: Callback=" + callback); + ScanResultsCallback.ScanResultsCallbackProxy proxy = callback.getProxy(); try { IWifiManager iWifiManager = getIWifiManager(); if (iWifiManager == null) { throw new RemoteException("Wifi service is not running"); } - iWifiManager.unregisterScanResultsListener(listener.hashCode()); + iWifiManager.unregisterScanResultsCallback(proxy); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); + } finally { + proxy.cleanUpProxy(); } } diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index ee03c11c826a..534e609f9af4 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -26,6 +26,7 @@ import android.net.wifi.IDppCallback; import android.net.wifi.ILocalOnlyHotspotCallback; import android.net.wifi.INetworkRequestMatchCallback; import android.net.wifi.IOnWifiUsabilityStatsListener; +import android.net.wifi.IScanResultsCallback; import android.net.wifi.IScanResultsListener; import android.net.wifi.ISoftApCallback; import android.net.wifi.ISuggestionConnectionStatusListener; @@ -512,17 +513,29 @@ public class BaseWifiService extends IWifiManager.Stub { throw new UnsupportedOperationException(); } - @Override + /** @deprecated replaced by {@link #registerScanResultsCallback(IScanResultsCallback)} */ + @Deprecated public void registerScanResultsListener( IBinder binder, IScanResultsListener listener, int listenerIdentifier) { throw new UnsupportedOperationException(); } - @Override + /** @deprecated replaced by {@link #unregisterScanResultsCallback(IScanResultsCallback)} */ + @Deprecated public void unregisterScanResultsListener(int listenerIdentifier) { throw new UnsupportedOperationException(); } + @Override + public void registerScanResultsCallback(IScanResultsCallback callback) { + throw new UnsupportedOperationException(); + } + + @Override + public void unregisterScanResultsCallback(IScanResultsCallback callback) { + throw new UnsupportedOperationException(); + } + @Override public void registerSuggestionConnectionStatusListener(IBinder binder, ISuggestionConnectionStatusListener listener, diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 507d50295d86..8cdcba67386b 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -60,7 +60,7 @@ import android.net.wifi.WifiManager.LocalOnlyHotspotSubscription; import android.net.wifi.WifiManager.NetworkRequestMatchCallback; import android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback; import android.net.wifi.WifiManager.OnWifiUsabilityStatsListener; -import android.net.wifi.WifiManager.ScanResultsListener; +import android.net.wifi.WifiManager.ScanResultsCallback; import android.net.wifi.WifiManager.SoftApCallback; import android.net.wifi.WifiManager.SuggestionConnectionStatusListener; import android.net.wifi.WifiManager.TrafficStateCallback; @@ -112,15 +112,16 @@ public class WifiManagerTest { @Mock TrafficStateCallback mTrafficStateCallback; @Mock NetworkRequestMatchCallback mNetworkRequestMatchCallback; @Mock OnWifiUsabilityStatsListener mOnWifiUsabilityStatsListener; - @Mock ScanResultsListener mScanResultListener; @Mock SuggestionConnectionStatusListener mListener; - @Mock Executor mCallbackExecutor; + @Mock Runnable mRunnable; @Mock Executor mExecutor; + @Mock Executor mAnotherExecutor; private Handler mHandler; private TestLooper mLooper; private WifiManager mWifiManager; private WifiNetworkSuggestion mWifiNetworkSuggestion; + private ScanResultsCallback mScanResultsCallback; @Before public void setUp() throws Exception { @@ -133,6 +134,12 @@ public class WifiManagerTest { mWifiManager = new WifiManager(mContext, mWifiService, mLooper.getLooper()); verify(mWifiService).getVerboseLoggingLevel(); mWifiNetworkSuggestion = new WifiNetworkSuggestion(); + mScanResultsCallback = new ScanResultsCallback() { + @Override + public void onScanResultsAvailable() { + mRunnable.run(); + } + }; } /** @@ -1778,65 +1785,81 @@ public class WifiManagerTest { } /** - * Verify an IllegalArgumentException is thrown if listener is not provided. + * Verify an IllegalArgumentException is thrown if callback is not provided. */ @Test(expected = IllegalArgumentException.class) - public void testAddScanResultsListenerWithNullListener() throws Exception { - mWifiManager.addScanResultsListener(mCallbackExecutor, null); + public void testRegisterScanResultsCallbackWithNullCallback() throws Exception { + mWifiManager.registerScanResultsCallback(mExecutor, null); } /** * Verify an IllegalArgumentException is thrown if executor is not provided. */ @Test(expected = IllegalArgumentException.class) - public void testAddScanResultsListenerWithNullExecutor() throws Exception { - mWifiManager.addScanResultsListener(null, mScanResultListener); + public void testRegisterCallbackWithNullExecutor() throws Exception { + mWifiManager.registerScanResultsCallback(null, mScanResultsCallback); } /** - * Verify client provided listener is being called to the right listener. + * Verify client provided callback is being called to the right callback. */ @Test - public void testAddScanResultsListenerAndReceiveEvent() throws Exception { - ArgumentCaptor callbackCaptor = - ArgumentCaptor.forClass(IScanResultsListener.Stub.class); - Executor executor = new SynchronousExecutor(); - mWifiManager.addScanResultsListener(executor, mScanResultListener); - verify(mWifiService).registerScanResultsListener(any(IBinder.class), - callbackCaptor.capture(), anyInt()); + public void testAddScanResultsCallbackAndReceiveEvent() throws Exception { + ArgumentCaptor callbackCaptor = + ArgumentCaptor.forClass(IScanResultsCallback.Stub.class); + mWifiManager.registerScanResultsCallback(new SynchronousExecutor(), mScanResultsCallback); + verify(mWifiService).registerScanResultsCallback(callbackCaptor.capture()); callbackCaptor.getValue().onScanResultsAvailable(); - verify(mScanResultListener).onScanResultsAvailable(); + verify(mRunnable).run(); } /** - * Verify client provided listener is being called on the right executor. + * Verify client provided callback is being called to the right executor. */ @Test - public void testAddScanResultsListenerWithTheTargetExecutor() throws Exception { - ArgumentCaptor callbackCaptor = - ArgumentCaptor.forClass(IScanResultsListener.Stub.class); - mWifiManager.addScanResultsListener(mExecutor, mScanResultListener); - verify(mWifiService).registerScanResultsListener(any(IBinder.class), - callbackCaptor.capture(), anyInt()); + public void testRegisterScanResultsCallbackWithTheTargetExecutor() throws Exception { + ArgumentCaptor callbackCaptor = + ArgumentCaptor.forClass(IScanResultsCallback.Stub.class); + mWifiManager.registerScanResultsCallback(mExecutor, mScanResultsCallback); + verify(mWifiService).registerScanResultsCallback(callbackCaptor.capture()); + mWifiManager.registerScanResultsCallback(mAnotherExecutor, mScanResultsCallback); callbackCaptor.getValue().onScanResultsAvailable(); - verify(mExecutor).execute(any(Runnable.class)); + verify(mExecutor, never()).execute(any(Runnable.class)); + verify(mAnotherExecutor).execute(any(Runnable.class)); + } + + /** + * Verify client register unregister then register again, to ensure callback still works. + */ + @Test + public void testRegisterUnregisterThenRegisterAgainWithScanResultCallback() throws Exception { + ArgumentCaptor callbackCaptor = + ArgumentCaptor.forClass(IScanResultsCallback.Stub.class); + mWifiManager.registerScanResultsCallback(new SynchronousExecutor(), mScanResultsCallback); + verify(mWifiService).registerScanResultsCallback(callbackCaptor.capture()); + mWifiManager.unregisterScanResultsCallback(mScanResultsCallback); + callbackCaptor.getValue().onScanResultsAvailable(); + verify(mRunnable, never()).run(); + mWifiManager.registerScanResultsCallback(new SynchronousExecutor(), mScanResultsCallback); + callbackCaptor.getValue().onScanResultsAvailable(); + verify(mRunnable).run(); } /** - * Verify client removeScanResultsListener. + * Verify client unregisterScanResultsCallback. */ @Test - public void testRemoveScanResultsListener() throws Exception { - mWifiManager.removeScanResultsListener(mScanResultListener); - verify(mWifiService).unregisterScanResultsListener(anyInt()); + public void testUnregisterScanResultsCallback() throws Exception { + mWifiManager.unregisterScanResultsCallback(mScanResultsCallback); + verify(mWifiService).unregisterScanResultsCallback(any()); } /** - * Verify client removeScanResultsListener with null listener will cause an exception. + * Verify client unregisterScanResultsCallback with null callback will cause an exception. */ @Test(expected = IllegalArgumentException.class) - public void testRemoveScanResultsListenerWithNullListener() throws Exception { - mWifiManager.removeScanResultsListener(null); + public void testUnregisterScanResultsCallbackWithNullCallback() throws Exception { + mWifiManager.unregisterScanResultsCallback(null); } /** -- cgit v1.2.3 From ff488b07097c94b47525fdcdc4f1279286e4858a Mon Sep 17 00:00:00 2001 From: David Su Date: Mon, 25 Nov 2019 18:27:49 -0800 Subject: Promote WifiConfiguration.configKey() to @SystemApi Bug: 143614759 Test: atest FrameworksWifiApiTests Change-Id: I08c201add76545d64a75b16375afcb072367c7aa --- wifi/java/android/net/wifi/WifiConfiguration.java | 47 +++++++---------------- 1 file changed, 13 insertions(+), 34 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index dfdc075043f6..e08a11e0b924 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -1984,8 +1984,8 @@ public class WifiConfiguration implements Parcelable { public boolean isLinked(WifiConfiguration config) { if (config != null) { if (config.linkedConfigurations != null && linkedConfigurations != null) { - if (config.linkedConfigurations.get(configKey()) != null - && linkedConfigurations.get(config.configKey()) != null) { + if (config.linkedConfigurations.get(getKey()) != null + && linkedConfigurations.get(config.getKey()) != null) { return true; } } @@ -2344,31 +2344,18 @@ public class WifiConfiguration implements Parcelable { return KeyMgmt.NONE; } - /* @hide - * Cache the config key, this seems useful as a speed up since a lot of - * lookups in the config store are done and based on this key. - */ - String mCachedConfigKey; - - /** @hide - * return the string used to calculate the hash in WifiConfigStore - * and uniquely identify this WifiConfiguration + /** + * Return a String that can be used to uniquely identify this WifiConfiguration. + *
    + * Note: Do not persist this value! This value is not guaranteed to remain backwards compatible. */ - public String configKey(boolean allowCached) { - String key; - if (allowCached && mCachedConfigKey != null) { - key = mCachedConfigKey; - } else if (providerFriendlyName != null) { - key = FQDN + KeyMgmt.strings[KeyMgmt.WPA_EAP]; - if (!shared) { - key += "-" + Integer.toString(UserHandle.getUserId(creatorUid)); - } - } else { - key = getSsidAndSecurityTypeString(); - if (!shared) { - key += "-" + Integer.toString(UserHandle.getUserId(creatorUid)); - } - mCachedConfigKey = key; + @NonNull + public String getKey() { + String key = providerFriendlyName == null + ? getSsidAndSecurityTypeString() + : FQDN + KeyMgmt.strings[KeyMgmt.WPA_EAP]; + if (!shared) { + key += "-" + UserHandle.getUserId(creatorUid); } return key; } @@ -2397,13 +2384,6 @@ public class WifiConfiguration implements Parcelable { return key; } - /** @hide - * get configKey, force calculating the config string - */ - public String configKey() { - return configKey(false); - } - /** @hide */ @UnsupportedAppUsage public IpConfiguration getIpConfiguration() { @@ -2589,7 +2569,6 @@ public class WifiConfiguration implements Parcelable { linkedConfigurations = new HashMap(); linkedConfigurations.putAll(source.linkedConfigurations); } - mCachedConfigKey = null; //force null configKey validatedInternetAccess = source.validatedInternetAccess; isLegacyPasspointConfig = source.isLegacyPasspointConfig; ephemeral = source.ephemeral; -- cgit v1.2.3 From d1260cf9f3b101cab9590906f4a1887296b4dbd3 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Tue, 19 Nov 2019 06:25:50 -0800 Subject: Revert "WifiManager: Retrieve IWifiManager service lazily" Couple of reverts in the CL: a) Revert "WifiManager: Return dummy values when wifi service is not up" This reverts commit dfb747ef8dc8ddced934ffa1d5e4b2897ad6bc20. b) Revert "WifiManager: Retrieve IWifiManager service lazily" This reverts commit 2161b39d386a38214181907f0cbfd36dafdfb933. Reason for revert: Wifi services no longer plan to be a separate APK/process for mainline. Will instead become a jar loaded from Apex. Bug: 144722612 Test: Device boots up & connects to wifi networks. Change-Id: Ic0bd8392f3c8e85b72dd62460c540e8cf58fc705 --- .../android/net/wifi/WifiFrameworkInitializer.java | 5 +- wifi/java/android/net/wifi/WifiManager.java | 507 ++++----------------- 2 files changed, 104 insertions(+), 408 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiFrameworkInitializer.java b/wifi/java/android/net/wifi/WifiFrameworkInitializer.java index 775043ae3291..002820b1bcc8 100644 --- a/wifi/java/android/net/wifi/WifiFrameworkInitializer.java +++ b/wifi/java/android/net/wifi/WifiFrameworkInitializer.java @@ -72,7 +72,10 @@ public class WifiFrameworkInitializer { SystemServiceRegistry.registerContextAwareService( Context.WIFI_SERVICE, WifiManager.class, - context -> new WifiManager(context, getInstanceLooper()) + (context, serviceBinder) -> { + IWifiManager service = IWifiManager.Stub.asInterface(serviceBinder); + return new WifiManager(context, service, getInstanceLooper()); + } ); SystemServiceRegistry.registerStaticService( Context.WIFI_P2P_SERVICE, diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 2a0211b77450..9f866f75c003 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -50,7 +50,6 @@ import android.os.HandlerExecutor; import android.os.IBinder; import android.os.Looper; import android.os.RemoteException; -import android.os.ServiceManager; import android.os.WorkSource; import android.text.TextUtils; import android.util.Log; @@ -58,7 +57,6 @@ import android.util.Pair; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.util.ArrayUtils; import com.android.server.net.NetworkPinner; import dalvik.system.CloseGuard; @@ -69,6 +67,7 @@ import java.lang.ref.WeakReference; import java.net.InetAddress; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -1211,46 +1210,24 @@ public class WifiManager { /** * Create a new WifiManager instance. * Applications will almost always want to use - * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve + * {@link android.content.Context#getSystemService Context.getSystemService} to retrieve * the standard {@link android.content.Context#WIFI_SERVICE Context.WIFI_SERVICE}. * * @param context the application context + * @param service the Binder interface * @param looper the Looper used to deliver callbacks - * - * @hide + * @hide - hide this because it takes in a parameter of type IWifiManager, which + * is a system private class. */ - public WifiManager(@NonNull Context context, @NonNull Looper looper) { + public WifiManager(@NonNull Context context, @NonNull IWifiManager service, + @NonNull Looper looper) { mContext = context; + mService = service; mLooper = looper; mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion; - } - - /** - * This is used only for unit testing. - * @hide - */ - @VisibleForTesting - public WifiManager(Context context, IWifiManager service, Looper looper) { - this(context, looper); - mService = service; updateVerboseLoggingEnabledFromService(); } - private IWifiManager getIWifiManager() { - if (mService == null) { - synchronized (this) { - mService = IWifiManager.Stub.asInterface( - ServiceManager.getService(Context.WIFI_SERVICE)); - if (mService != null) { - updateVerboseLoggingEnabledFromService(); - } else { - Log.e(TAG, "Wifi Service not running yet, ignoring WifiManager API call"); - } - } - } - return mService; - } - /** * Return a list of all the networks configured for the current foreground * user. @@ -1290,10 +1267,8 @@ public class WifiManager { @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE}) public List getConfiguredNetworks() { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return Collections.emptyList(); ParceledListSlice parceledList = - iWifiManager.getConfiguredNetworks(mContext.getOpPackageName(), + mService.getConfiguredNetworks(mContext.getOpPackageName(), mContext.getFeatureId()); if (parceledList == null) { return Collections.emptyList(); @@ -1309,10 +1284,8 @@ public class WifiManager { @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE, READ_WIFI_CREDENTIAL}) public List getPrivilegedConfiguredNetworks() { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return Collections.emptyList(); ParceledListSlice parceledList = - iWifiManager.getPrivilegedConfiguredNetworks(mContext.getOpPackageName(), + mService.getPrivilegedConfiguredNetworks(mContext.getOpPackageName(), mContext.getFeatureId()); if (parceledList == null) { return Collections.emptyList(); @@ -1344,16 +1317,14 @@ public class WifiManager { @NonNull List scanResults) { List>>> configs = new ArrayList<>(); try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return Collections.emptyList(); Map>> results = - iWifiManager.getAllMatchingFqdnsForScanResults( + mService.getAllMatchingFqdnsForScanResults( scanResults); if (results.isEmpty()) { return configs; } List wifiConfigurations = - iWifiManager.getWifiConfigsForPasspointProfiles( + mService.getWifiConfigsForPasspointProfiles( new ArrayList<>(results.keySet())); for (WifiConfiguration configuration : wifiConfigurations) { Map> scanResultsPerNetworkType = results.get( @@ -1388,12 +1359,10 @@ public class WifiManager { public Map> getMatchingOsuProviders( @Nullable List scanResults) { if (scanResults == null) { - return Collections.emptyMap(); + return new HashMap<>(); } try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return Collections.emptyMap(); - return iWifiManager.getMatchingOsuProviders(scanResults); + return mService.getMatchingOsuProviders(scanResults); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1420,9 +1389,7 @@ public class WifiManager { public Map getMatchingPasspointConfigsForOsuProviders( @NonNull Set osuProviders) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return Collections.emptyMap(); - return iWifiManager.getMatchingPasspointConfigsForOsuProviders( + return mService.getMatchingPasspointConfigsForOsuProviders( new ArrayList<>(osuProviders)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -1507,9 +1474,7 @@ public class WifiManager { */ private int addOrUpdateNetwork(WifiConfiguration config) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return -1; - return iWifiManager.addOrUpdateNetwork(config, mContext.getOpPackageName()); + return mService.addOrUpdateNetwork(config, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1756,11 +1721,7 @@ public class WifiManager { Binder binder = new Binder(); try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.registerNetworkRequestMatchCallback( + mService.registerNetworkRequestMatchCallback( binder, new NetworkRequestMatchCallbackProxy(executor, callback), callback.hashCode()); } catch (RemoteException e) { @@ -1787,11 +1748,7 @@ public class WifiManager { Log.v(TAG, "unregisterNetworkRequestMatchCallback: callback=" + callback); try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.unregisterNetworkRequestMatchCallback(callback.hashCode()); + mService.unregisterNetworkRequestMatchCallback(callback.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1824,9 +1781,7 @@ public class WifiManager { public @NetworkSuggestionsStatusCode int addNetworkSuggestions( @NonNull List networkSuggestions) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL; - return iWifiManager.addNetworkSuggestions( + return mService.addNetworkSuggestions( networkSuggestions, mContext.getOpPackageName(), mContext.getFeatureId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -1850,9 +1805,7 @@ public class WifiManager { public @NetworkSuggestionsStatusCode int removeNetworkSuggestions( @NonNull List networkSuggestions) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL; - return iWifiManager.removeNetworkSuggestions( + return mService.removeNetworkSuggestions( networkSuggestions, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -1868,9 +1821,7 @@ public class WifiManager { @RequiresPermission(ACCESS_WIFI_STATE) public @NonNull List getNetworkSuggestions() { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return Collections.emptyList(); - return iWifiManager.getNetworkSuggestions(mContext.getOpPackageName()); + return mService.getNetworkSuggestions(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); } @@ -1900,13 +1851,7 @@ public class WifiManager { */ public void addOrUpdatePasspointConfiguration(PasspointConfiguration config) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - if (config == null) return; - throw new RemoteException("Wifi service is not running"); - } - if (!iWifiManager.addOrUpdatePasspointConfiguration( - config, mContext.getOpPackageName())) { + if (!mService.addOrUpdatePasspointConfiguration(config, mContext.getOpPackageName())) { throw new IllegalArgumentException(); } } catch (RemoteException e) { @@ -1930,13 +1875,7 @@ public class WifiManager { }) public void removePasspointConfiguration(String fqdn) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - if (TextUtils.isEmpty(fqdn)) return; - throw new RemoteException("Wifi service is not running"); - } - if (!iWifiManager.removePasspointConfiguration( - fqdn, mContext.getOpPackageName())) { + if (!mService.removePasspointConfiguration(fqdn, mContext.getOpPackageName())) { throw new IllegalArgumentException(); } } catch (RemoteException e) { @@ -1959,9 +1898,7 @@ public class WifiManager { }) public List getPasspointConfigurations() { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) Collections.emptyList(); - return iWifiManager.getPasspointConfigurations(mContext.getOpPackageName()); + return mService.getPasspointConfigurations(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1981,12 +1918,7 @@ public class WifiManager { */ public void queryPasspointIcon(long bssid, String fileName) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - if (bssid == 0L || TextUtils.isEmpty(fileName)) return; - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.queryPasspointIcon(bssid, fileName); + mService.queryPasspointIcon(bssid, fileName); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2000,9 +1932,7 @@ public class WifiManager { */ public int matchProviderWithCurrentNetwork(String fqdn) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return -1; - return iWifiManager.matchProviderWithCurrentNetwork(fqdn); + return mService.matchProviderWithCurrentNetwork(fqdn); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2018,11 +1948,7 @@ public class WifiManager { */ public void deauthenticateNetwork(long holdoff, boolean ess) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.deauthenticateNetwork(holdoff, ess); + mService.deauthenticateNetwork(holdoff, ess); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2052,9 +1978,7 @@ public class WifiManager { @Deprecated public boolean removeNetwork(int netId) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return false; - return iWifiManager.removeNetwork(netId, mContext.getOpPackageName()); + return mService.removeNetwork(netId, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2109,10 +2033,7 @@ public class WifiManager { boolean success; try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return false; - success = iWifiManager.enableNetwork( - netId, attemptConnect, mContext.getOpPackageName()); + success = mService.enableNetwork(netId, attemptConnect, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2148,9 +2069,7 @@ public class WifiManager { @Deprecated public boolean disableNetwork(int netId) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return false; - return iWifiManager.disableNetwork(netId, mContext.getOpPackageName()); + return mService.disableNetwork(netId, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2173,9 +2092,7 @@ public class WifiManager { @Deprecated public boolean disconnect() { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return false; - return iWifiManager.disconnect(mContext.getOpPackageName()); + return mService.disconnect(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2199,9 +2116,7 @@ public class WifiManager { @Deprecated public boolean reconnect() { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return false; - return iWifiManager.reconnect(mContext.getOpPackageName()); + return mService.reconnect(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2225,9 +2140,7 @@ public class WifiManager { @Deprecated public boolean reassociate() { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return false; - return iWifiManager.reassociate(mContext.getOpPackageName()); + return mService.reassociate(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2323,9 +2236,7 @@ public class WifiManager { private long getSupportedFeatures() { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return 0L; - return iWifiManager.getSupportedFeatures(); + return mService.getSupportedFeatures(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2482,10 +2393,8 @@ public class WifiManager { */ public WifiActivityEnergyInfo getControllerActivityEnergyInfo() { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return null; synchronized(this) { - return iWifiManager.reportActivityInfo(); + return mService.reportActivityInfo(); } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -2524,11 +2433,9 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public boolean startScan(WorkSource workSource) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return false; String packageName = mContext.getOpPackageName(); String featureId = mContext.getFeatureId(); - return iWifiManager.startScan(packageName, featureId); + return mService.startScan(packageName, featureId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2557,9 +2464,7 @@ public class WifiManager { */ public WifiInfo getConnectionInfo() { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return null; - return iWifiManager.getConnectionInfo(mContext.getOpPackageName(), + return mService.getConnectionInfo(mContext.getOpPackageName(), mContext.getFeatureId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -2574,9 +2479,7 @@ public class WifiManager { */ public List getScanResults() { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return Collections.emptyList(); - return iWifiManager.getScanResults(mContext.getOpPackageName(), + return mService.getScanResults(mContext.getOpPackageName(), mContext.getFeatureId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -2596,9 +2499,7 @@ public class WifiManager { @Deprecated public boolean isScanAlwaysAvailable() { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return false; - return iWifiManager.isScanAlwaysAvailable(); + return mService.isScanAlwaysAvailable(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2631,9 +2532,7 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL) public String getCountryCode() { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return null; - return iWifiManager.getCountryCode(); + return mService.getCountryCode(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2648,9 +2547,7 @@ public class WifiManager { @SystemApi public boolean isDualBandSupported() { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return false; - return iWifiManager.isDualBandSupported(); + return mService.isDualBandSupported(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2673,9 +2570,7 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public boolean isDualModeSupported() { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return false; - return iWifiManager.needs5GHzToAnyApBandConversion(); + return mService.needs5GHzToAnyApBandConversion(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2688,9 +2583,7 @@ public class WifiManager { */ public DhcpInfo getDhcpInfo() { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return null; - return iWifiManager.getDhcpInfo(); + return mService.getDhcpInfo(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2717,9 +2610,7 @@ public class WifiManager { @Deprecated public boolean setWifiEnabled(boolean enabled) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return false; - return iWifiManager.setWifiEnabled(mContext.getOpPackageName(), enabled); + return mService.setWifiEnabled(mContext.getOpPackageName(), enabled); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2734,9 +2625,7 @@ public class WifiManager { */ public int getWifiState() { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return WIFI_STATE_UNKNOWN; - return iWifiManager.getWifiEnabledState(); + return mService.getWifiEnabledState(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2764,11 +2653,7 @@ public class WifiManager { 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, + mService.getTxPacketCount(mContext.getOpPackageName(), binder, listenerProxy, listener.hashCode()); } catch (RemoteException e) { listenerProxy.onFailure(ERROR); @@ -2811,11 +2696,7 @@ public class WifiManager { */ public int calculateSignalLevel(int rssi) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - return iWifiManager.calculateSignalLevel(rssi); + return mService.calculateSignalLevel(rssi); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2861,12 +2742,7 @@ public class WifiManager { }) public void updateInterfaceIpState(@Nullable String ifaceName, @IfaceIpMode int mode) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - if (TextUtils.isEmpty(ifaceName) || mode == IFACE_IP_MODE_UNSPECIFIED) return; - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.updateInterfaceIpState(ifaceName, mode); + mService.updateInterfaceIpState(ifaceName, mode); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2890,9 +2766,7 @@ public class WifiManager { }) public boolean startSoftAp(@Nullable WifiConfiguration wifiConfig) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return false; - return iWifiManager.startSoftAp(wifiConfig); + return mService.startSoftAp(wifiConfig); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2912,9 +2786,7 @@ public class WifiManager { }) public boolean stopSoftAp() { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return false; - return iWifiManager.stopSoftAp(); + return mService.stopSoftAp(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -3032,13 +2904,9 @@ public class WifiManager { LocalOnlyHotspotCallbackProxy proxy = new LocalOnlyHotspotCallbackProxy(this, executor, callback); try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } String packageName = mContext.getOpPackageName(); String featureId = mContext.getFeatureId(); - int returnCode = iWifiManager.startLocalOnlyHotspot(proxy, packageName, featureId, + int returnCode = mService.startLocalOnlyHotspot(proxy, packageName, featureId, config); if (returnCode != LocalOnlyHotspotCallback.REQUEST_REGISTERED) { // Send message to the proxy to make sure we call back on the correct thread @@ -3090,11 +2958,7 @@ public class WifiManager { } mLOHSCallbackProxy = null; try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.stopLocalOnlyHotspot(); + mService.stopLocalOnlyHotspot(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -3126,11 +2990,7 @@ public class WifiManager { mLOHSObserverProxy = new LocalOnlyHotspotObserverProxy(this, executor, observer); try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.startWatchLocalOnlyHotspot(mLOHSObserverProxy); + mService.startWatchLocalOnlyHotspot(mLOHSObserverProxy); mLOHSObserverProxy.registered(); } catch (RemoteException e) { mLOHSObserverProxy = null; @@ -3153,11 +3013,7 @@ public class WifiManager { } mLOHSObserverProxy = null; try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.stopWatchLocalOnlyHotspot(); + mService.stopWatchLocalOnlyHotspot(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -3177,9 +3033,7 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public int getWifiApState() { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return WIFI_AP_STATE_FAILED; - return iWifiManager.getWifiApEnabledState(); + return mService.getWifiApEnabledState(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -3208,9 +3062,7 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public WifiConfiguration getWifiApConfiguration() { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return null; - return iWifiManager.getWifiApConfiguration(); + return mService.getWifiApConfiguration(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -3227,10 +3079,7 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public boolean setWifiApConfiguration(WifiConfiguration wifiConfig) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return false; - return iWifiManager.setWifiApConfiguration( - wifiConfig, mContext.getOpPackageName()); + return mService.setWifiApConfiguration(wifiConfig, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -3258,12 +3107,7 @@ public class WifiManager { */ public void setTdlsEnabled(InetAddress remoteIPAddress, boolean enable) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - if (remoteIPAddress == null || !enable) return; - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.enableTdls(remoteIPAddress.getHostAddress(), enable); + mService.enableTdls(remoteIPAddress.getHostAddress(), enable); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -3277,12 +3121,7 @@ public class WifiManager { */ public void setTdlsEnabledWithMacAddress(String remoteMacAddress, boolean enable) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - if (TextUtils.isEmpty(remoteMacAddress) || !enable) return; - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.enableTdlsWithMacAddress(remoteMacAddress, enable); + mService.enableTdlsWithMacAddress(remoteMacAddress, enable); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -3573,11 +3412,7 @@ public class WifiManager { Binder binder = new Binder(); try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.registerSoftApCallback( + mService.registerSoftApCallback( binder, new SoftApCallbackProxy(executor, callback), callback.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -3599,11 +3434,7 @@ public class WifiManager { Log.v(TAG, "unregisterSoftApCallback: callback=" + callback); try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.unregisterSoftApCallback(callback.hashCode()); + mService.unregisterSoftApCallback(callback.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -3931,11 +3762,7 @@ public class WifiManager { binder = new Binder(); } try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.connect(config, networkId, binder, listenerProxy, + mService.connect(config, networkId, binder, listenerProxy, listener == null ? 0 : listener.hashCode()); } catch (RemoteException e) { if (listenerProxy != null) listenerProxy.onFailure(ERROR); @@ -4028,11 +3855,7 @@ public class WifiManager { binder = new Binder(); } try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.save(config, binder, listenerProxy, + mService.save(config, binder, listenerProxy, listener == null ? 0 : listener.hashCode()); } catch (RemoteException e) { if (listenerProxy != null) listenerProxy.onFailure(ERROR); @@ -4069,11 +3892,7 @@ public class WifiManager { binder = new Binder(); } try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.forget(netId, binder, listenerProxy, + mService.forget(netId, binder, listenerProxy, listener == null ? 0 : listener.hashCode()); } catch (RemoteException e) { if (listenerProxy != null) listenerProxy.onFailure(ERROR); @@ -4126,11 +3945,7 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void allowAutojoin(int netId, boolean choice) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.allowAutojoin(netId, choice); + mService.allowAutojoin(netId, choice); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4153,11 +3968,7 @@ public class WifiManager { throw new IllegalArgumentException("SSID cannot be null or empty!"); } try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.disableEphemeralNetwork(ssid, mContext.getOpPackageName()); + mService.disableEphemeralNetwork(ssid, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4245,14 +4056,10 @@ public class WifiManager { synchronized (mBinder) { if (mRefCounted ? (++mRefCount == 1) : (!mHeld)) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.acquireWifiLock(mBinder, mLockType, mTag, mWorkSource); + mService.acquireWifiLock(mBinder, mLockType, mTag, mWorkSource); synchronized (WifiManager.this) { if (mActiveLockCount >= MAX_ACTIVE_LOCKS) { - iWifiManager.releaseWifiLock(mBinder); + mService.releaseWifiLock(mBinder); throw new UnsupportedOperationException( "Exceeded maximum number of wifi locks"); } @@ -4282,11 +4089,7 @@ public class WifiManager { synchronized (mBinder) { if (mRefCounted ? (--mRefCount == 0) : (mHeld)) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.releaseWifiLock(mBinder); + mService.releaseWifiLock(mBinder); synchronized (WifiManager.this) { mActiveLockCount--; } @@ -4349,11 +4152,7 @@ public class WifiManager { } if (changed && mHeld) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.updateWifiLockWorkSource(mBinder, mWorkSource); + mService.updateWifiLockWorkSource(mBinder, mWorkSource); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4381,11 +4180,7 @@ public class WifiManager { synchronized (mBinder) { if (mHeld) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.releaseWifiLock(mBinder); + mService.releaseWifiLock(mBinder); synchronized (WifiManager.this) { mActiveLockCount--; } @@ -4498,14 +4293,10 @@ public class WifiManager { synchronized (mBinder) { if (mRefCounted ? (++mRefCount == 1) : (!mHeld)) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.acquireMulticastLock(mBinder, mTag); + mService.acquireMulticastLock(mBinder, mTag); synchronized (WifiManager.this) { if (mActiveLockCount >= MAX_ACTIVE_LOCKS) { - iWifiManager.releaseMulticastLock(mTag); + mService.releaseMulticastLock(mTag); throw new UnsupportedOperationException( "Exceeded maximum number of wifi locks"); } @@ -4547,11 +4338,7 @@ public class WifiManager { synchronized (mBinder) { if (mRefCounted ? (--mRefCount == 0) : (mHeld)) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.releaseMulticastLock(mTag); + mService.releaseMulticastLock(mTag); synchronized (WifiManager.this) { mActiveLockCount--; } @@ -4628,9 +4415,7 @@ public class WifiManager { */ public boolean isMulticastEnabled() { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return false; - return iWifiManager.isMulticastEnabled(); + return mService.isMulticastEnabled(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4643,9 +4428,7 @@ public class WifiManager { @UnsupportedAppUsage public boolean initializeMulticastFiltering() { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return false; - iWifiManager.initializeMulticastFiltering(); + mService.initializeMulticastFiltering(); return true; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -4664,12 +4447,7 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void enableVerboseLogging (int verbose) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - if (verbose == 0) return; - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.enableVerboseLogging(verbose); + mService.enableVerboseLogging(verbose); } catch (Exception e) { //ignore any failure here Log.e(TAG, "enableVerboseLogging " + e.toString()); @@ -4688,9 +4466,7 @@ public class WifiManager { @SystemApi public int getVerboseLoggingLevel() { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return -1; - return iWifiManager.getVerboseLoggingLevel(); + return mService.getVerboseLoggingLevel(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4706,11 +4482,7 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL) public void factoryReset() { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.factoryReset(mContext.getOpPackageName()); + mService.factoryReset(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4725,9 +4497,7 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public Network getCurrentNetwork() { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return null; - return iWifiManager.getCurrentNetwork(); + return mService.getCurrentNetwork(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4759,12 +4529,7 @@ public class WifiManager { */ public void enableWifiConnectivityManager(boolean enabled) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - if (enabled) return; - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.enableWifiConnectivityManager(enabled); + mService.enableWifiConnectivityManager(enabled); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4781,9 +4546,7 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public byte[] retrieveBackupData() { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return new byte[0]; - return iWifiManager.retrieveBackupData(); + return mService.retrieveBackupData(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4798,12 +4561,7 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void restoreBackupData(@NonNull byte[] data) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - if (ArrayUtils.isEmpty(data)) return; - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.restoreBackupData(data); + mService.restoreBackupData(data); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4824,12 +4582,7 @@ public class WifiManager { public void restoreSupplicantBackupData( @NonNull byte[] supplicantData, @NonNull byte[] ipConfigData) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - if (ArrayUtils.isEmpty(supplicantData) && ArrayUtils.isEmpty(ipConfigData)) return; - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.restoreSupplicantBackupData(supplicantData, ipConfigData); + mService.restoreSupplicantBackupData(supplicantData, ipConfigData); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4858,11 +4611,7 @@ public class WifiManager { throw new IllegalArgumentException("callback must not be null"); } try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.startSubscriptionProvisioning(provider, + mService.startSubscriptionProvisioning(provider, new ProvisioningCallbackProxy(executor, callback)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -4996,11 +4745,7 @@ public class WifiManager { Binder binder = new Binder(); try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.registerTrafficStateCallback( + mService.registerTrafficStateCallback( binder, new TrafficStateCallbackProxy(executor, callback), callback.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -5021,11 +4766,7 @@ public class WifiManager { Log.v(TAG, "unregisterTrafficStateCallback: callback=" + callback); try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.unregisterTrafficStateCallback(callback.hashCode()); + mService.unregisterTrafficStateCallback(callback.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -5083,9 +4824,7 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public String[] getFactoryMacAddresses() { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) return new String[0]; - return iWifiManager.getFactoryMacAddresses(); + return mService.getFactoryMacAddresses(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -5154,12 +4893,7 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.WIFI_SET_DEVICE_MOBILITY_STATE) public void setDeviceMobilityState(@DeviceMobilityState int state) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - if (state == DEVICE_MOBILITY_STATE_UNKNOWN) return; - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.setDeviceMobilityState(state); + mService.setDeviceMobilityState(state); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -5214,13 +4948,8 @@ public class WifiManager { @NonNull EasyConnectStatusCallback callback) { Binder binder = new Binder(); try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.startDppAsConfiguratorInitiator( - binder, enrolleeUri, selectedNetworkId, enrolleeNetworkRole, - new EasyConnectCallbackProxy(executor, callback)); + mService.startDppAsConfiguratorInitiator(binder, enrolleeUri, selectedNetworkId, + enrolleeNetworkRole, new EasyConnectCallbackProxy(executor, callback)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -5245,11 +4974,7 @@ public class WifiManager { @NonNull EasyConnectStatusCallback callback) { Binder binder = new Binder(); try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.startDppAsEnrolleeInitiator(binder, configuratorUri, + mService.startDppAsEnrolleeInitiator(binder, configuratorUri, new EasyConnectCallbackProxy(executor, callback)); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -5270,12 +4995,8 @@ public class WifiManager { android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void stopEasyConnectSession() { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } /* Request lower layers to stop/abort and clear resources */ - iWifiManager.stopDppSession(); + mService.stopDppSession(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -5374,11 +5095,7 @@ public class WifiManager { Log.v(TAG, "addOnWifiUsabilityStatsListener: listener=" + listener); } try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.addOnWifiUsabilityStatsListener(new Binder(), + mService.addOnWifiUsabilityStatsListener(new Binder(), new IOnWifiUsabilityStatsListener.Stub() { @Override public void onWifiUsabilityStats(int seqNum, boolean isSameBssidAndFreq, @@ -5415,11 +5132,7 @@ public class WifiManager { Log.v(TAG, "removeOnWifiUsabilityStatsListener: listener=" + listener); } try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.removeOnWifiUsabilityStatsListener(listener.hashCode()); + mService.removeOnWifiUsabilityStatsListener(listener.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -5442,11 +5155,7 @@ public class WifiManager { @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public void updateWifiUsabilityScore(int seqNum, int score, int predictionHorizonSec) { try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.updateWifiUsabilityScore(seqNum, score, predictionHorizonSec); + mService.updateWifiUsabilityScore(seqNum, score, predictionHorizonSec); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -5545,11 +5254,7 @@ public class WifiManager { ScanResultsCallback.ScanResultsCallbackProxy proxy = callback.getProxy(); proxy.initProxy(executor, callback); try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.registerScanResultsCallback(proxy); + mService.registerScanResultsCallback(proxy); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -5567,11 +5272,7 @@ public class WifiManager { Log.v(TAG, "unregisterScanResultsCallback: Callback=" + callback); ScanResultsCallback.ScanResultsCallbackProxy proxy = callback.getProxy(); try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.unregisterScanResultsCallback(proxy); + mService.unregisterScanResultsCallback(proxy); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } finally { @@ -5647,11 +5348,7 @@ public class WifiManager { Log.v(TAG, "addSuggestionConnectionStatusListener listener=" + listener + ", executor=" + executor); try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.registerSuggestionConnectionStatusListener(new Binder(), + mService.registerSuggestionConnectionStatusListener(new Binder(), new SuggestionConnectionStatusListenerProxy(executor, listener), listener.hashCode(), mContext.getOpPackageName(), mContext.getFeatureId()); } catch (RemoteException e) { @@ -5672,11 +5369,7 @@ public class WifiManager { if (listener == null) throw new IllegalArgumentException("Listener cannot be null"); Log.v(TAG, "removeSuggestionConnectionStatusListener: listener=" + listener); try { - IWifiManager iWifiManager = getIWifiManager(); - if (iWifiManager == null) { - throw new RemoteException("Wifi service is not running"); - } - iWifiManager.unregisterSuggestionConnectionStatusListener(listener.hashCode(), + mService.unregisterSuggestionConnectionStatusListener(listener.hashCode(), mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); -- cgit v1.2.3 From 9707dc2136f659de3288917e9ae3b920bdb45013 Mon Sep 17 00:00:00 2001 From: "Nate(Qiang) Jiang" Date: Wed, 20 Nov 2019 18:52:47 -0800 Subject: [NetworkSuggestion] change comments to fit the disconnect behavior Bug: 137582811 Test: build Change-Id: I0ee13a98c74e25cac9b94ee16703e291a2ff2610 --- wifi/java/android/net/wifi/WifiManager.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 2a0211b77450..820f33bdcdf6 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1835,8 +1835,9 @@ public class WifiManager { /** * Remove some or all of the network suggestions that were previously provided by the app. - * If the current network is a suggestion being removed and if it was only provided by this app - * and is not a saved network then the framework will immediately disconnect. + * If one of the suggestions being removed was used to establish connection to the current + * network, then the device will immediately disconnect from that network. + * * See {@link WifiNetworkSuggestion} for a detailed explanation of the parameters. * See {@link WifiNetworkSuggestion#equals(Object)} for the equivalence evaluation used. * -- cgit v1.2.3 From ace322e441f20008b7525ab729ac2feb0dc64ce0 Mon Sep 17 00:00:00 2001 From: David Su Date: Mon, 25 Nov 2019 16:03:05 -0800 Subject: Expose additional WifiScanner @SystemApis Exposed scan type, HiddenNetwork, and register/unregisterScanListener(). Bug: 143614759 Test: atest FrameworkWifiApiTests Change-Id: Ie926dc8d75266dad13e5d1589f8e14011a856a01 --- .../java/android/net/wifi/SynchronousExecutor.java | 29 +++ wifi/java/android/net/wifi/WifiScanner.java | 221 +++++++++++++-------- .../src/android/net/wifi/WifiManagerTest.java | 9 - .../src/android/net/wifi/WifiScannerTest.java | 166 +++++++++++++++- 4 files changed, 325 insertions(+), 100 deletions(-) create mode 100644 wifi/java/android/net/wifi/SynchronousExecutor.java (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/SynchronousExecutor.java b/wifi/java/android/net/wifi/SynchronousExecutor.java new file mode 100644 index 000000000000..9926b1b5f7dc --- /dev/null +++ b/wifi/java/android/net/wifi/SynchronousExecutor.java @@ -0,0 +1,29 @@ +/* + * 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 java.util.concurrent.Executor; + +/** + * An executor implementation that runs synchronously on the current thread. + * @hide + */ +public class SynchronousExecutor implements Executor { + @Override + public void execute(Runnable r) { + r.run(); + } +} diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index 0de506610ec1..77f7b9e23fc0 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -17,13 +17,16 @@ package android.net.wifi; import android.Manifest; +import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; import android.content.Context; +import android.os.Binder; import android.os.Bundle; import android.os.Handler; import android.os.Looper; @@ -45,6 +48,7 @@ import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.concurrent.Executor; /** * This class provides a way to scan the Wifi universe around the device @@ -196,24 +200,29 @@ public class WifiScanner { */ public static final int REPORT_EVENT_NO_BATCH = (1 << 2); + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"SCAN_TYPE_"}, value = { + SCAN_TYPE_LOW_LATENCY, + SCAN_TYPE_LOW_POWER, + SCAN_TYPE_HIGH_ACCURACY}) + public @interface ScanType {} + /** - * This is used to indicate the purpose of the scan to the wifi chip in - * {@link ScanSettings#type}. - * On devices with multiple hardware radio chains (and hence different modes of scan), - * this type serves as an indication to the hardware on what mode of scan to perform. - * Only apps holding android.Manifest.permission.NETWORK_STACK permission can set this value. - * - * Note: This serves as an intent and not as a stipulation, the wifi chip - * might honor or ignore the indication based on the current radio conditions. Always - * use the {@link ScanResult#radioChainInfos} to figure out the radio chain configuration used - * to receive the corresponding scan result. + * Optimize the scan for lower latency. + * @see ScanSettings#type */ - /** {@hide} */ - public static final int TYPE_LOW_LATENCY = 0; - /** {@hide} */ - public static final int TYPE_LOW_POWER = 1; - /** {@hide} */ - public static final int TYPE_HIGH_ACCURACY = 2; + public static final int SCAN_TYPE_LOW_LATENCY = 0; + /** + * Optimize the scan for lower power usage. + * @see ScanSettings#type + */ + public static final int SCAN_TYPE_LOW_POWER = 1; + /** + * Optimize the scan for higher accuracy. + * @see ScanSettings#type + */ + public static final int SCAN_TYPE_HIGH_ACCURACY = 2; /** {@hide} */ public static final String SCAN_PARAMS_SCAN_SETTINGS_KEY = "ScanSettings"; @@ -228,18 +237,14 @@ public class WifiScanner { * scan configuration parameters to be sent to {@link #startBackgroundScan} */ public static class ScanSettings implements Parcelable { - /** - * Hidden network to be scanned for. - * {@hide} - */ + /** Hidden network to be scanned for. */ public static class HiddenNetwork { /** SSID of the network */ - public String ssid; + @NonNull + public final String ssid; - /** - * Default constructor for HiddenNetwork. - */ - public HiddenNetwork(String ssid) { + /** Default constructor for HiddenNetwork. */ + public HiddenNetwork(@NonNull String ssid) { this.ssid = ssid; } } @@ -249,12 +254,12 @@ public class WifiScanner { /** list of channels; used when band is set to WIFI_BAND_UNSPECIFIED */ public ChannelSpec[] channels; /** - * list of hidden networks to scan for. Explicit probe requests are sent out for such + * List of hidden networks to scan for. Explicit probe requests are sent out for such * networks during scan. Only valid for single scan requests. - * {@hide} */ + @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_STACK) - public HiddenNetwork[] hiddenNetworks; + public final List hiddenNetworks = new ArrayList<>(); /** period of background scan; in millisecond, 0 => single shot scan */ public int periodInMs; /** must have a valid REPORT_EVENT value */ @@ -285,11 +290,24 @@ public class WifiScanner { public boolean isPnoScan; /** * Indicate the type of scan to be performed by the wifi chip. - * Default value: {@link #TYPE_LOW_LATENCY}. - * {@hide} + * + * On devices with multiple hardware radio chains (and hence different modes of scan), + * this type serves as an indication to the hardware on what mode of scan to perform. + * Only apps holding {@link android.Manifest.permission.NETWORK_STACK} permission can set + * this value. + * + * Note: This serves as an intent and not as a stipulation, the wifi chip + * might honor or ignore the indication based on the current radio conditions. Always + * use the {@link ScanResult#radioChainInfos} to figure out the radio chain configuration + * used to receive the corresponding scan result. + * + * One of {@link #SCAN_TYPE_LOW_LATENCY}, {@link #SCAN_TYPE_LOW_POWER}, + * {@link #SCAN_TYPE_HIGH_ACCURACY}. + * Default value: {@link #SCAN_TYPE_LOW_LATENCY}. */ + @ScanType @RequiresPermission(android.Manifest.permission.NETWORK_STACK) - public int type = TYPE_LOW_LATENCY; + public int type = SCAN_TYPE_LOW_LATENCY; /** * This scan request may ignore location settings while receiving scans. This should only * be used in emergency situations. @@ -336,13 +354,9 @@ public class WifiScanner { } else { dest.writeInt(0); } - if (hiddenNetworks != null) { - dest.writeInt(hiddenNetworks.length); - for (int i = 0; i < hiddenNetworks.length; i++) { - dest.writeString(hiddenNetworks[i].ssid); - } - } else { - dest.writeInt(0); + dest.writeInt(hiddenNetworks.size()); + for (HiddenNetwork hiddenNetwork : hiddenNetworks) { + dest.writeString(hiddenNetwork.ssid); } } @@ -372,10 +386,10 @@ public class WifiScanner { settings.channels[i] = spec; } int numNetworks = in.readInt(); - settings.hiddenNetworks = new HiddenNetwork[numNetworks]; + settings.hiddenNetworks.clear(); for (int i = 0; i < numNetworks; i++) { String ssid = in.readString(); - settings.hiddenNetworks[i] = new HiddenNetwork(ssid);; + settings.hiddenNetworks.add(new HiddenNetwork(ssid)); } return settings; } @@ -801,33 +815,44 @@ public class WifiScanner { } /** - * Register a listener that will receive results from all single scans - * Either the onSuccess/onFailure will be called once when the listener is registered. After - * (assuming onSuccess was called) all subsequent single scan results will be delivered to the - * listener. It is possible that onFullResult will not be called for all results of the first - * scan if the listener was registered during the scan. + * Register a listener that will receive results from all single scans. + * Either the {@link ScanListener#onSuccess()} or {@link ScanListener#onFailure(int, String)} + * method will be called once when the listener is registered. + * Afterwards (assuming onSuccess was called), all subsequent single scan results will be + * delivered to the listener. It is possible that onFullResult will not be called for all + * results of the first scan if the listener was registered during the scan. * * @param listener specifies the object to report events to. This object is also treated as a * key for this request, and must also be specified to cancel the request. * Multiple requests should also not share this object. - * {@hide} */ @RequiresPermission(Manifest.permission.NETWORK_STACK) - public void registerScanListener(ScanListener listener) { + public void registerScanListener(@NonNull @CallbackExecutor Executor executor, + @NonNull ScanListener listener) { + Preconditions.checkNotNull(executor, "executor cannot be null"); Preconditions.checkNotNull(listener, "listener cannot be null"); - int key = addListener(listener); + int key = addListener(listener, executor); if (key == INVALID_KEY) return; validateChannel(); mAsyncChannel.sendMessage(CMD_REGISTER_SCAN_LISTENER, 0, key); } + /** + * Overload of {@link #registerScanListener(Executor, ScanListener)} that executes the callback + * synchronously. + * @hide + */ + @RequiresPermission(Manifest.permission.NETWORK_STACK) + public void registerScanListener(@NonNull ScanListener listener) { + registerScanListener(new SynchronousExecutor(), listener); + } + /** * Deregister a listener for ongoing single scans * @param listener specifies which scan to cancel; must be same object as passed in {@link * #registerScanListener} - * {@hide} */ - public void deregisterScanListener(ScanListener listener) { + public void unregisterScanListener(@NonNull ScanListener listener) { Preconditions.checkNotNull(listener, "listener cannot be null"); int key = removeListener(listener); if (key == INVALID_KEY) return; @@ -1280,6 +1305,7 @@ public class WifiScanner { private int mListenerKey = 1; private final SparseArray mListenerMap = new SparseArray(); + private final SparseArray mExecutorMap = new SparseArray<>(); private final Object mListenerMapLock = new Object(); private AsyncChannel mAsyncChannel; @@ -1327,10 +1353,14 @@ public class WifiScanner { "No permission to access and change wifi or a bad initialization"); } + private int addListener(ActionListener listener) { + return addListener(listener, null); + } + // Add a listener into listener map. If the listener already exists, return INVALID_KEY and // send an error message to internal handler; Otherwise add the listener to the listener map and // return the key of the listener. - private int addListener(ActionListener listener) { + private int addListener(ActionListener listener, Executor executor) { synchronized (mListenerMapLock) { boolean keyExists = (getListenerKey(listener) != INVALID_KEY); // Note we need to put the listener into listener map even if it's a duplicate as the @@ -1346,6 +1376,7 @@ public class WifiScanner { message.sendToTarget(); return INVALID_KEY; } else { + mExecutorMap.put(key, executor); return key; } } @@ -1363,11 +1394,22 @@ public class WifiScanner { return key; } - private Object getListener(int key) { - if (key == INVALID_KEY) return null; + private static class ListenerWithExecutor { + @Nullable final Object mListener; + @Nullable final Executor mExecutor; + + ListenerWithExecutor(@Nullable Object listener, @Nullable Executor executor) { + mListener = listener; + mExecutor = executor; + } + } + + private ListenerWithExecutor getListenerWithExecutor(int key) { + if (key == INVALID_KEY) return new ListenerWithExecutor(null, null); synchronized (mListenerMapLock) { Object listener = mListenerMap.get(key); - return listener; + Executor executor = mExecutorMap.get(key); + return new ListenerWithExecutor(listener, executor); } } @@ -1388,6 +1430,7 @@ public class WifiScanner { synchronized (mListenerMapLock) { Object listener = mListenerMap.get(key); mListenerMap.remove(key); + mExecutorMap.remove(key); return listener; } } @@ -1400,6 +1443,7 @@ public class WifiScanner { } synchronized (mListenerMapLock) { mListenerMap.remove(key); + mExecutorMap.remove(key); return key; } } @@ -1458,7 +1502,8 @@ public class WifiScanner { return; } - Object listener = getListener(msg.arg2); + ListenerWithExecutor listenerWithExecutor = getListenerWithExecutor(msg.arg2); + Object listener = listenerWithExecutor.mListener; if (listener == null) { if (DBG) Log.d(TAG, "invalid listener key = " + msg.arg2); @@ -1467,36 +1512,52 @@ public class WifiScanner { if (DBG) Log.d(TAG, "listener key = " + msg.arg2); } + Executor executor = listenerWithExecutor.mExecutor; + if (executor == null) { + executor = new SynchronousExecutor(); + } + switch (msg.what) { - /* ActionListeners grouped together */ - case CMD_OP_SUCCEEDED : - ((ActionListener) listener).onSuccess(); - break; - case CMD_OP_FAILED : { - OperationResult result = (OperationResult)msg.obj; - ((ActionListener) listener).onFailure(result.reason, result.description); - removeListener(msg.arg2); - } - break; - case CMD_SCAN_RESULT : - ((ScanListener) listener).onResults( - ((ParcelableScanData) msg.obj).getResults()); - return; - case CMD_FULL_SCAN_RESULT : + /* ActionListeners grouped together */ + case CMD_OP_SUCCEEDED: { + ActionListener actionListener = (ActionListener) listener; + Binder.clearCallingIdentity(); + executor.execute(actionListener::onSuccess); + } break; + case CMD_OP_FAILED: { + OperationResult result = (OperationResult) msg.obj; + ActionListener actionListener = (ActionListener) listener; + removeListener(msg.arg2); + Binder.clearCallingIdentity(); + executor.execute(() -> + actionListener.onFailure(result.reason, result.description)); + } break; + case CMD_SCAN_RESULT: { + ScanListener scanListener = (ScanListener) listener; + ParcelableScanData parcelableScanData = (ParcelableScanData) msg.obj; + Binder.clearCallingIdentity(); + executor.execute(() -> scanListener.onResults(parcelableScanData.getResults())); + } break; + case CMD_FULL_SCAN_RESULT: { ScanResult result = (ScanResult) msg.obj; - ((ScanListener) listener).onFullResult(result); - return; - case CMD_SINGLE_SCAN_COMPLETED: + ScanListener scanListener = ((ScanListener) listener); + Binder.clearCallingIdentity(); + executor.execute(() -> scanListener.onFullResult(result)); + } break; + case CMD_SINGLE_SCAN_COMPLETED: { if (DBG) Log.d(TAG, "removing listener for single scan"); removeListener(msg.arg2); - break; - case CMD_PNO_NETWORK_FOUND: - ((PnoScanListener) listener).onPnoNetworkFound( - ((ParcelableScanResults) msg.obj).getResults()); - return; - default: + } break; + case CMD_PNO_NETWORK_FOUND: { + PnoScanListener pnoScanListener = (PnoScanListener) listener; + ParcelableScanResults parcelableScanResults = (ParcelableScanResults) msg.obj; + Binder.clearCallingIdentity(); + executor.execute(() -> + pnoScanListener.onPnoNetworkFound(parcelableScanResults.getResults())); + } break; + default: { if (DBG) Log.d(TAG, "Ignoring message " + msg.what); - return; + } break; } } } diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 8cdcba67386b..d326201fa574 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -1436,15 +1436,6 @@ public class WifiManagerTest { eq((int) listenerIdentifier.getValue())); } - /** - * Defined for testing purpose. - */ - class SynchronousExecutor implements Executor { - public void execute(Runnable r) { - r.run(); - } - } - /** * Test behavior of isEnhancedOpenSupported */ diff --git a/wifi/tests/src/android/net/wifi/WifiScannerTest.java b/wifi/tests/src/android/net/wifi/WifiScannerTest.java index f4fa38beaa40..b1436c90f5dd 100644 --- a/wifi/tests/src/android/net/wifi/WifiScannerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiScannerTest.java @@ -22,7 +22,9 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.validateMockitoUsage; @@ -33,6 +35,7 @@ import android.content.Context; import android.net.wifi.WifiScanner.PnoSettings; import android.net.wifi.WifiScanner.PnoSettings.PnoNetwork; import android.net.wifi.WifiScanner.ScanData; +import android.net.wifi.WifiScanner.ScanListener; import android.net.wifi.WifiScanner.ScanSettings; import android.os.Bundle; import android.os.Handler; @@ -51,8 +54,10 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.mockito.Spy; import java.util.Arrays; +import java.util.concurrent.Executor; /** * Unit tests for {@link android.net.wifi.WifiScanner}. @@ -63,6 +68,13 @@ public class WifiScannerTest { private Context mContext; @Mock private IWifiScanner mService; + @Spy + private Executor mExecutor = new SynchronousExecutor(); + @Mock + private ScanListener mScanListener; + @Mock + private WifiScanner.ParcelableScanData mParcelableScanData; + private ScanData[] mScanData = {}; private static final boolean TEST_PNOSETTINGS_IS_CONNECTED = false; private static final int TEST_PNOSETTINGS_MIN_5GHZ_RSSI = -60; @@ -76,6 +88,7 @@ public class WifiScannerTest { private static final String TEST_SSID_2 = "TEST2"; private static final int[] TEST_FREQUENCIES_1 = {}; private static final int[] TEST_FREQUENCIES_2 = {2500, 5124}; + private static final String DESCRIPTION_NOT_AUTHORIZED = "Not authorized"; private WifiScanner mWifiScanner; private TestLooper mLooper; @@ -95,6 +108,7 @@ public class WifiScannerTest { when(mService.getMessenger()).thenReturn(mBidirectionalAsyncChannelServer.getMessenger()); mWifiScanner = new WifiScanner(mContext, mService, mLooper.getLooper()); mLooper.dispatchAll(); + when(mParcelableScanData.getResults()).thenReturn(mScanData); } /** @@ -111,7 +125,7 @@ public class WifiScannerTest { @Test public void verifyScanSettingsParcelWithBand() throws Exception { ScanSettings writeSettings = new ScanSettings(); - writeSettings.type = WifiScanner.TYPE_LOW_POWER; + writeSettings.type = WifiScanner.SCAN_TYPE_LOW_POWER; writeSettings.band = WifiScanner.WIFI_BAND_BOTH_WITH_DFS; ScanSettings readSettings = parcelWriteRead(writeSettings); @@ -126,7 +140,7 @@ public class WifiScannerTest { @Test public void verifyScanSettingsParcelWithChannels() throws Exception { ScanSettings writeSettings = new ScanSettings(); - writeSettings.type = WifiScanner.TYPE_HIGH_ACCURACY; + writeSettings.type = WifiScanner.SCAN_TYPE_HIGH_ACCURACY; writeSettings.band = WifiScanner.WIFI_BAND_UNSPECIFIED; writeSettings.channels = new WifiScanner.ChannelSpec[] { new WifiScanner.ChannelSpec(5), @@ -243,13 +257,13 @@ public class WifiScannerTest { /** - * Test behavior of {@link WifiScanner#startScan(ScanSettings, WifiScanner.ScanListener)} + * Test behavior of {@link WifiScanner#startScan(ScanSettings, ScanListener)} * @throws Exception */ @Test public void testStartScan() throws Exception { ScanSettings scanSettings = new ScanSettings(); - WifiScanner.ScanListener scanListener = mock(WifiScanner.ScanListener.class); + ScanListener scanListener = mock(ScanListener.class); mWifiScanner.startScan(scanSettings, scanListener); mLooper.dispatchAll(); @@ -273,13 +287,13 @@ public class WifiScannerTest { } /** - * Test behavior of {@link WifiScanner#stopScan(WifiScanner.ScanListener)} + * Test behavior of {@link WifiScanner#stopScan(ScanListener)} * @throws Exception */ @Test public void testStopScan() throws Exception { ScanSettings scanSettings = new ScanSettings(); - WifiScanner.ScanListener scanListener = mock(WifiScanner.ScanListener.class); + ScanListener scanListener = mock(ScanListener.class); mWifiScanner.startScan(scanSettings, scanListener); mLooper.dispatchAll(); @@ -302,13 +316,13 @@ public class WifiScannerTest { } /** - * Test behavior of {@link WifiScanner#startScan(ScanSettings, WifiScanner.ScanListener)} + * Test behavior of {@link WifiScanner#startScan(ScanSettings, ScanListener)} * @throws Exception */ @Test public void testStartScanListenerOnSuccess() throws Exception { ScanSettings scanSettings = new ScanSettings(); - WifiScanner.ScanListener scanListener = mock(WifiScanner.ScanListener.class); + ScanListener scanListener = mock(ScanListener.class); mWifiScanner.startScan(scanSettings, scanListener); mLooper.dispatchAll(); @@ -332,13 +346,13 @@ public class WifiScannerTest { } /** - * Test behavior of {@link WifiScanner#startScan(ScanSettings, WifiScanner.ScanListener)} + * Test behavior of {@link WifiScanner#startScan(ScanSettings, ScanListener)} * @throws Exception */ @Test public void testStartScanListenerOnResults() throws Exception { ScanSettings scanSettings = new ScanSettings(); - WifiScanner.ScanListener scanListener = mock(WifiScanner.ScanListener.class); + ScanListener scanListener = mock(ScanListener.class); mWifiScanner.startScan(scanSettings, scanListener); mLooper.dispatchAll(); @@ -425,7 +439,7 @@ public class WifiScannerTest { } /** - * Test behavior of {@link WifiScanner#stopPnoScan(WifiScanner.ScanListener)} + * Test behavior of {@link WifiScanner#stopPnoScan(ScanListener)} * WifiScanner.PnoScanListener)} * @throws Exception */ @@ -480,4 +494,134 @@ public class WifiScannerTest { assertEquals(scanData.getResults().length, readScanData.getResults().length); assertEquals(scanData.getResults()[0].SSID, readScanData.getResults()[0].SSID); } + + /** Tests that upon registration success, {@link ScanListener#onSuccess()} is called. */ + @Test + public void testRegisterScanListenerSuccess() throws Exception { + mWifiScanner.registerScanListener(mExecutor, mScanListener); + mLooper.dispatchAll(); + + ArgumentCaptor messageArgumentCaptor = ArgumentCaptor.forClass(Message.class); + verify(mHandler).handleMessage(messageArgumentCaptor.capture()); + Message sentMessage = messageArgumentCaptor.getValue(); + assertNotNull(sentMessage); + + assertEquals(1, mBidirectionalAsyncChannelServer.getClientMessengers().size()); + Messenger scannerMessenger = + mBidirectionalAsyncChannelServer.getClientMessengers().iterator().next(); + + Message responseMessage = Message.obtain(); + responseMessage.what = WifiScanner.CMD_OP_SUCCEEDED; + responseMessage.arg2 = sentMessage.arg2; + scannerMessenger.send(responseMessage); + mLooper.dispatchAll(); + + verify(mExecutor).execute(any()); + verify(mScanListener).onSuccess(); + } + + /** + * Tests that upon registration failed, {@link ScanListener#onFailure(int, String)} is called. + */ + @Test + public void testRegisterScanListenerFailed() throws Exception { + mWifiScanner.registerScanListener(mExecutor, mScanListener); + mLooper.dispatchAll(); + + ArgumentCaptor messageArgumentCaptor = ArgumentCaptor.forClass(Message.class); + verify(mHandler).handleMessage(messageArgumentCaptor.capture()); + Message sentMessage = messageArgumentCaptor.getValue(); + assertNotNull(sentMessage); + + assertEquals(1, mBidirectionalAsyncChannelServer.getClientMessengers().size()); + Messenger scannerMessenger = + mBidirectionalAsyncChannelServer.getClientMessengers().iterator().next(); + + { + Message responseMessage = Message.obtain(); + responseMessage.what = WifiScanner.CMD_OP_FAILED; + responseMessage.arg2 = sentMessage.arg2; + responseMessage.obj = new WifiScanner.OperationResult( + WifiScanner.REASON_NOT_AUTHORIZED, DESCRIPTION_NOT_AUTHORIZED); + scannerMessenger.send(responseMessage); + mLooper.dispatchAll(); + } + + verify(mExecutor).execute(any()); + verify(mScanListener).onFailure( + WifiScanner.REASON_NOT_AUTHORIZED, DESCRIPTION_NOT_AUTHORIZED); + + // CMD_OP_FAILED should have caused the removal of the listener, verify this + { + Message responseMessage = Message.obtain(); + responseMessage.what = WifiScanner.CMD_SCAN_RESULT; + responseMessage.arg2 = sentMessage.arg2; + responseMessage.obj = mParcelableScanData; + scannerMessenger.send(responseMessage); + mLooper.dispatchAll(); + } + // execute() called once before, not called again + verify(mExecutor, times(1)).execute(any()); + // onResults() never triggered + verify(mScanListener, never()).onResults(any()); + } + + /** + * Tests that when the ScanListener is triggered, {@link ScanListener#onResults(ScanData[])} + * is called. + */ + @Test + public void testRegisterScanListenerReceiveScanResults() throws Exception { + mWifiScanner.registerScanListener(mExecutor, mScanListener); + mLooper.dispatchAll(); + + ArgumentCaptor messageArgumentCaptor = ArgumentCaptor.forClass(Message.class); + verify(mHandler).handleMessage(messageArgumentCaptor.capture()); + Message sentMessage = messageArgumentCaptor.getValue(); + assertNotNull(sentMessage); + + assertEquals(1, mBidirectionalAsyncChannelServer.getClientMessengers().size()); + Messenger scannerMessenger = + mBidirectionalAsyncChannelServer.getClientMessengers().iterator().next(); + + Message responseMessage = Message.obtain(); + responseMessage.what = WifiScanner.CMD_SCAN_RESULT; + responseMessage.arg2 = sentMessage.arg2; + responseMessage.obj = mParcelableScanData; + scannerMessenger.send(responseMessage); + mLooper.dispatchAll(); + + verify(mExecutor).execute(any()); + verify(mScanListener).onResults(mScanData); + } + + /** + * Tests that after unregistering a scan listener, {@link ScanListener#onResults(ScanData[])} + * is not called. + */ + @Test + public void testUnregisterScanListener() throws Exception { + mWifiScanner.registerScanListener(mExecutor, mScanListener); + mWifiScanner.unregisterScanListener(mScanListener); + mLooper.dispatchAll(); + + assertEquals(1, mBidirectionalAsyncChannelServer.getClientMessengers().size()); + Messenger scannerMessenger = + mBidirectionalAsyncChannelServer.getClientMessengers().iterator().next(); + + ArgumentCaptor messageArgumentCaptor = ArgumentCaptor.forClass(Message.class); + verify(mHandler, times(2)).handleMessage(messageArgumentCaptor.capture()); + Message sentMessage = messageArgumentCaptor.getValue(); + assertNotNull(sentMessage); + + Message responseMessage = Message.obtain(); + responseMessage.what = WifiScanner.CMD_SCAN_RESULT; + responseMessage.obj = mParcelableScanData; + responseMessage.arg2 = sentMessage.arg2; + scannerMessenger.send(responseMessage); + mLooper.dispatchAll(); + + verify(mExecutor, never()).execute(any()); + verify(mScanListener, never()).onResults(mScanData); + } } -- cgit v1.2.3 From 20ceb4c6ea60783246b145782f095dcdbb4013c9 Mon Sep 17 00:00:00 2001 From: David Su Date: Tue, 26 Nov 2019 18:42:35 -0800 Subject: Expose WifiP2pDevice.update() as public API Bug: 143892817 Test: compiles Change-Id: Ibab8b0e1ccd88993978549bd61be21c82e777f41 --- wifi/java/android/net/wifi/p2p/WifiP2pDevice.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java index 13b25209990e..98ec208f32e6 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java @@ -286,14 +286,12 @@ public class WifiP2pDevice implements Parcelable { } /** - * Update device details. This will throw an exception if the device address does not match. + * Update this device's details using another {@link WifiP2pDevice} instance. + * This will throw an exception if the device address does not match. * - * @param device to be updated + * @param device another instance of {@link WifiP2pDevice} used to update this instance. * @throws IllegalArgumentException if the device is null or the device address does not match - * - * @hide */ - @UnsupportedAppUsage public void update(@NonNull WifiP2pDevice device) { updateSupplicantDetails(device); status = device.status; -- cgit v1.2.3 From f3b8e8e0366490fcbf65e5ddda50e45277d1df8c Mon Sep 17 00:00:00 2001 From: "Nate(Qiang) Jiang" Date: Tue, 19 Nov 2019 13:48:26 -0800 Subject: [NetworkSuggestion] add API to allow app share credential with user When app shares credential with user that suggestion will show in the WifiPicker. And user can click to connect to that network. Bug: 142134651 Test: atest android.net.wifi Test: atest com.android.server.wifi Change-Id: I1d64abdd045734f4f79a4424f4f6199d7e6cd7d2 --- .../android/net/wifi/WifiNetworkSuggestion.java | 54 ++++++++++++++++++++++ .../net/wifi/WifiNetworkSuggestionTest.java | 50 ++++++++++++++------ 2 files changed, 90 insertions(+), 14 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java index 246e96f4ce3f..a5ca82c50627 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java +++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java @@ -116,6 +116,16 @@ public final class WifiNetworkSuggestion implements Parcelable { */ private int mCarrierId; + /** + * Whether this network is shared credential with user to allow user manually connect. + */ + private boolean mIsUserAllowed; + + /** + * Whether the setIsUserAllowedToManuallyConnect have been called. + */ + private boolean mIsUserAllowedBeenSet; + public Builder() { mSsid = null; mBssid = null; @@ -129,6 +139,8 @@ public final class WifiNetworkSuggestion implements Parcelable { mIsAppInteractionRequired = false; mIsUserInteractionRequired = false; mIsMetered = false; + mIsUserAllowed = true; + mIsUserAllowedBeenSet = false; mPriority = UNASSIGNED_PRIORITY; mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID; } @@ -365,6 +377,27 @@ public final class WifiNetworkSuggestion implements Parcelable { return this; } + /** + * Specifies whether the network credentials provided with this suggestion can be used by + * the user to explicitly (manually) connect to this network. If true this network will + * appear in the Wi-Fi Picker (in Settings) and the user will be able to select and connect + * to it with the provided credentials. If false, the user will need to enter network + * credentials and the resulting configuration will become a user saved network. + *

    + *

  • Note: Only valid for secure (non-open) networks. + *
  • If not set, defaults to true (i.e. allow user to manually connect) for secure + * networks and false for open networks.
  • + * + * @param isAllowed {@code true} to indicate that the credentials may be used by the user to + * manually connect to the network, {@code false} otherwise. + * @return Instance of {@link Builder} to enable chaining of the builder method. + */ + public @NonNull Builder setIsUserAllowedToManuallyConnect(boolean isAllowed) { + mIsUserAllowed = isAllowed; + mIsUserAllowedBeenSet = true; + return this; + } + private void setSecurityParamsInWifiConfiguration( @NonNull WifiConfiguration configuration) { if (!TextUtils.isEmpty(mWpa2PskPassphrase)) { // WPA-PSK network. @@ -516,6 +549,13 @@ public final class WifiNetworkSuggestion implements Parcelable { throw new IllegalStateException("invalid bssid for suggestion"); } wifiConfiguration = buildWifiConfiguration(); + if (wifiConfiguration.isOpenNetwork()) { + if (mIsUserAllowedBeenSet && mIsUserAllowed) { + throw new IllegalStateException("Open network should not be " + + "setIsUserAllowedToManuallyConnect to true"); + } + mIsUserAllowed = false; + } } return new WifiNetworkSuggestion( @@ -523,6 +563,7 @@ public final class WifiNetworkSuggestion implements Parcelable { mPasspointConfiguration, mIsAppInteractionRequired, mIsUserInteractionRequired, + mIsUserAllowed, Process.myUid(), ActivityThread.currentApplication().getApplicationContext().getOpPackageName()); } @@ -564,12 +605,20 @@ public final class WifiNetworkSuggestion implements Parcelable { */ public final String suggestorPackageName; + /** + * Whether app share credential with the user, allow user use provided credential to + * connect network manually. + * @hide + */ + public final boolean isUserAllowedToManuallyConnect; + /** @hide */ public WifiNetworkSuggestion() { this.wifiConfiguration = null; this.passpointConfiguration = null; this.isAppInteractionRequired = false; this.isUserInteractionRequired = false; + this.isUserAllowedToManuallyConnect = true; this.suggestorUid = -1; this.suggestorPackageName = null; } @@ -579,6 +628,7 @@ public final class WifiNetworkSuggestion implements Parcelable { @Nullable PasspointConfiguration passpointConfiguration, boolean isAppInteractionRequired, boolean isUserInteractionRequired, + boolean isUserAllowedToManuallyConnect, int suggestorUid, @NonNull String suggestorPackageName) { checkNotNull(networkConfiguration); checkNotNull(suggestorPackageName); @@ -587,6 +637,7 @@ public final class WifiNetworkSuggestion implements Parcelable { this.isAppInteractionRequired = isAppInteractionRequired; this.isUserInteractionRequired = isUserInteractionRequired; + this.isUserAllowedToManuallyConnect = isUserAllowedToManuallyConnect; this.suggestorUid = suggestorUid; this.suggestorPackageName = suggestorPackageName; } @@ -600,6 +651,7 @@ public final class WifiNetworkSuggestion implements Parcelable { in.readParcelable(null), // PasspointConfiguration in.readBoolean(), // isAppInteractionRequired in.readBoolean(), // isUserInteractionRequired + in.readBoolean(), // isSharedCredentialWithUser in.readInt(), // suggestorUid in.readString() // suggestorPackageName ); @@ -622,6 +674,7 @@ public final class WifiNetworkSuggestion implements Parcelable { dest.writeParcelable(passpointConfiguration, flags); dest.writeBoolean(isAppInteractionRequired); dest.writeBoolean(isUserInteractionRequired); + dest.writeBoolean(isUserAllowedToManuallyConnect); dest.writeInt(suggestorUid); dest.writeString(suggestorPackageName); } @@ -666,6 +719,7 @@ public final class WifiNetworkSuggestion implements Parcelable { .append(", FQDN=").append(wifiConfiguration.FQDN) .append(", isAppInteractionRequired=").append(isAppInteractionRequired) .append(", isUserInteractionRequired=").append(isUserInteractionRequired) + .append(", isUserAllowedToManuallyConnect=").append(isUserAllowedToManuallyConnect) .append(", suggestorUid=").append(suggestorUid) .append(", suggestorPackageName=").append(suggestorPackageName) .append("]"); diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java index 699008905f0a..ce085f55b0dd 100644 --- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java +++ b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java @@ -64,12 +64,13 @@ public class WifiNetworkSuggestionTest { assertEquals(WifiConfiguration.METERED_OVERRIDE_NONE, suggestion.wifiConfiguration.meteredOverride); assertEquals(-1, suggestion.wifiConfiguration.priority); + assertEquals(false, suggestion.isUserAllowedToManuallyConnect); } /** * Validate correctness of WifiNetworkSuggestion object created by * {@link WifiNetworkSuggestion.Builder#build()} for WPA_EAP network which requires - * app interaction and has a priority of zero set. + * app interaction, not share credential and has a priority of zero set. */ @Test public void @@ -78,6 +79,7 @@ public class WifiNetworkSuggestionTest { .setSsid(TEST_SSID) .setWpa2Passphrase(TEST_PRESHARED_KEY) .setIsAppInteractionRequired(true) + .setIsUserAllowedToManuallyConnect(false) .setPriority(0) .build(); @@ -91,6 +93,7 @@ public class WifiNetworkSuggestionTest { assertEquals(WifiConfiguration.METERED_OVERRIDE_NONE, suggestion.wifiConfiguration.meteredOverride); assertEquals(0, suggestion.wifiConfiguration.priority); + assertEquals(false, suggestion.isUserAllowedToManuallyConnect); } /** @@ -118,6 +121,7 @@ public class WifiNetworkSuggestionTest { assertEquals(WifiConfiguration.METERED_OVERRIDE_METERED, suggestion.wifiConfiguration.meteredOverride); assertEquals(-1, suggestion.wifiConfiguration.priority); + assertTrue(suggestion.isUserAllowedToManuallyConnect); } /** @@ -138,6 +142,7 @@ public class WifiNetworkSuggestionTest { .get(WifiConfiguration.KeyMgmt.OWE)); assertNull(suggestion.wifiConfiguration.preSharedKey); assertTrue(suggestion.wifiConfiguration.requirePMF); + assertFalse(suggestion.isUserAllowedToManuallyConnect); } /** @@ -149,6 +154,7 @@ public class WifiNetworkSuggestionTest { WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() .setSsid(TEST_SSID) .setWpa3Passphrase(TEST_PRESHARED_KEY) + .setIsUserAllowedToManuallyConnect(true) .build(); assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID); @@ -157,6 +163,7 @@ public class WifiNetworkSuggestionTest { assertEquals("\"" + TEST_PRESHARED_KEY + "\"", suggestion.wifiConfiguration.preSharedKey); assertTrue(suggestion.wifiConfiguration.requirePMF); + assertTrue(suggestion.isUserAllowedToManuallyConnect); } @@ -186,6 +193,7 @@ public class WifiNetworkSuggestionTest { assertNull(suggestion.wifiConfiguration.preSharedKey); // allowedSuiteBCiphers are set according to the loaded certificate and cannot be tested // here. + assertTrue(suggestion.isUserAllowedToManuallyConnect); } /** @@ -205,6 +213,7 @@ public class WifiNetworkSuggestionTest { assertTrue(suggestion.isAppInteractionRequired); assertEquals(suggestion.wifiConfiguration.meteredOverride, WifiConfiguration.METERED_OVERRIDE_METERED); + assertTrue(suggestion.isUserAllowedToManuallyConnect); } /** @@ -439,7 +448,7 @@ public class WifiNetworkSuggestionTest { configuration.BSSID = TEST_BSSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion( - configuration, null, false, true, TEST_UID, TEST_PACKAGE_NAME); + configuration, null, false, true, true, TEST_UID, TEST_PACKAGE_NAME); Parcel parcelW = Parcel.obtain(); suggestion.writeToParcel(parcelW, 0); @@ -506,7 +515,7 @@ public class WifiNetworkSuggestionTest { configuration.BSSID = TEST_BSSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, null, true, false, TEST_UID, + new WifiNetworkSuggestion(configuration, null, true, false, true, TEST_UID, TEST_PACKAGE_NAME); WifiConfiguration configuration1 = new WifiConfiguration(); @@ -514,7 +523,7 @@ public class WifiNetworkSuggestionTest { configuration1.BSSID = TEST_BSSID; configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); WifiNetworkSuggestion suggestion1 = - new WifiNetworkSuggestion(configuration1, null, false, true, TEST_UID, + new WifiNetworkSuggestion(configuration1, null, false, true, true, TEST_UID, TEST_PACKAGE_NAME); assertEquals(suggestion, suggestion1); @@ -531,14 +540,14 @@ public class WifiNetworkSuggestionTest { configuration.SSID = TEST_SSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, null, false, false, TEST_UID, + new WifiNetworkSuggestion(configuration, null, false, false, true, TEST_UID, TEST_PACKAGE_NAME); WifiConfiguration configuration1 = new WifiConfiguration(); configuration1.SSID = TEST_SSID_1; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion1 = - new WifiNetworkSuggestion(configuration1, null, false, false, TEST_UID, + new WifiNetworkSuggestion(configuration1, null, false, false, true, TEST_UID, TEST_PACKAGE_NAME); assertNotEquals(suggestion, suggestion1); @@ -555,14 +564,14 @@ public class WifiNetworkSuggestionTest { configuration.BSSID = TEST_BSSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, null, false, false, TEST_UID, + new WifiNetworkSuggestion(configuration, null, false, false, true, TEST_UID, TEST_PACKAGE_NAME); WifiConfiguration configuration1 = new WifiConfiguration(); configuration1.SSID = TEST_SSID; configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion1 = - new WifiNetworkSuggestion(configuration1, null, false, false, TEST_UID, + new WifiNetworkSuggestion(configuration1, null, false, false, true, TEST_UID, TEST_PACKAGE_NAME); assertNotEquals(suggestion, suggestion1); @@ -578,14 +587,14 @@ public class WifiNetworkSuggestionTest { configuration.SSID = TEST_SSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, null, false, false, TEST_UID, + new WifiNetworkSuggestion(configuration, null, false, false, true, TEST_UID, TEST_PACKAGE_NAME); WifiConfiguration configuration1 = new WifiConfiguration(); configuration1.SSID = TEST_SSID; configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); WifiNetworkSuggestion suggestion1 = - new WifiNetworkSuggestion(configuration1, null, false, false, TEST_UID, + new WifiNetworkSuggestion(configuration1, null, false, false, true, TEST_UID, TEST_PACKAGE_NAME); assertNotEquals(suggestion, suggestion1); @@ -601,11 +610,11 @@ public class WifiNetworkSuggestionTest { configuration.SSID = TEST_SSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, null, false, false, TEST_UID, + new WifiNetworkSuggestion(configuration, null, false, false, true, TEST_UID, TEST_PACKAGE_NAME); WifiNetworkSuggestion suggestion1 = - new WifiNetworkSuggestion(configuration, null, false, false, TEST_UID_OTHER, + new WifiNetworkSuggestion(configuration, null, false, false, true, TEST_UID_OTHER, TEST_PACKAGE_NAME); assertNotEquals(suggestion, suggestion1); @@ -621,10 +630,10 @@ public class WifiNetworkSuggestionTest { configuration.SSID = TEST_SSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion( - configuration, null, false, false, TEST_UID, TEST_PACKAGE_NAME); + configuration, null, false, false, true, TEST_UID, TEST_PACKAGE_NAME); WifiNetworkSuggestion suggestion1 = new WifiNetworkSuggestion( - configuration, null, false, false, TEST_UID, TEST_PACKAGE_NAME_OTHER); + configuration, null, false, false, true, TEST_UID, TEST_PACKAGE_NAME_OTHER); assertNotEquals(suggestion, suggestion1); } @@ -664,4 +673,17 @@ public class WifiNetworkSuggestionTest { .build(); assertNotEquals(suggestion, suggestion1); } + + /** + * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception + * when {@link WifiNetworkSuggestion.Builder#setIsUserAllowedToManuallyConnect(boolean)} to + * true on a open network suggestion. + */ + @Test(expected = IllegalStateException.class) + public void testSetIsUserAllowedToManuallyConnectToWithOpenNetwork() { + WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() + .setSsid(TEST_SSID) + .setIsUserAllowedToManuallyConnect(true) + .build(); + } } -- cgit v1.2.3 From e0ee85b9c24957b967f54e88c3ec8896922c5342 Mon Sep 17 00:00:00 2001 From: David Su Date: Fri, 29 Nov 2019 18:45:52 -0800 Subject: Remove OsuProvider#mIcon mIcon is never used, removing it since it uses @hide API Icon#sameAs(). Bug: 145409537 Test: atest FrameworksWifiApiTests Change-Id: Ie7b515e5b3068aa033d3ffbc277cd372f68f39d1 --- .../android/net/wifi/hotspot2/OsuProvider.java | 42 +++++----------------- .../android/net/wifi/hotspot2/OsuProviderTest.java | 13 +++---- 2 files changed, 14 insertions(+), 41 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/hotspot2/OsuProvider.java b/wifi/java/android/net/wifi/hotspot2/OsuProvider.java index 3bef50211015..f0a06076961c 100644 --- a/wifi/java/android/net/wifi/hotspot2/OsuProvider.java +++ b/wifi/java/android/net/wifi/hotspot2/OsuProvider.java @@ -19,7 +19,6 @@ package android.net.wifi.hotspot2; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.graphics.drawable.Icon; import android.net.Uri; import android.net.wifi.WifiSsid; import android.os.Bundle; @@ -86,23 +85,16 @@ public final class OsuProvider implements Parcelable { */ private final List mMethodList; - /** - * Icon data for the OSU (Online Sign-Up) provider. - */ - private final Icon mIcon; - /** @hide */ public OsuProvider(String osuSsid, Map friendlyNames, - String serviceDescription, Uri serverUri, String nai, List methodList, - Icon icon) { + String serviceDescription, Uri serverUri, String nai, List methodList) { this(WifiSsid.createFromByteArray(osuSsid.getBytes(StandardCharsets.UTF_8)), - friendlyNames, serviceDescription, serverUri, nai, methodList, icon); + friendlyNames, serviceDescription, serverUri, nai, methodList); } /** @hide */ public OsuProvider(WifiSsid osuSsid, Map friendlyNames, - String serviceDescription, Uri serverUri, String nai, List methodList, - Icon icon) { + String serviceDescription, Uri serverUri, String nai, List methodList) { mOsuSsid = osuSsid; mFriendlyNames = friendlyNames; mServiceDescription = serviceDescription; @@ -113,7 +105,6 @@ public final class OsuProvider implements Parcelable { } else { mMethodList = new ArrayList<>(methodList); } - mIcon = icon; } /** @@ -130,7 +121,6 @@ public final class OsuProvider implements Parcelable { mServerUri = null; mNetworkAccessIdentifier = null; mMethodList = new ArrayList<>(); - mIcon = null; return; } @@ -144,7 +134,6 @@ public final class OsuProvider implements Parcelable { } else { mMethodList = new ArrayList<>(source.mMethodList); } - mIcon = source.mIcon; } /** @hide */ @@ -205,11 +194,6 @@ public final class OsuProvider implements Parcelable { return mMethodList; } - /** @hide */ - public Icon getIcon() { - return mIcon; - } - @Override public int describeContents() { return 0; @@ -222,7 +206,6 @@ public final class OsuProvider implements Parcelable { dest.writeParcelable(mServerUri, flags); dest.writeString(mNetworkAccessIdentifier); dest.writeList(mMethodList); - dest.writeParcelable(mIcon, flags); Bundle bundle = new Bundle(); bundle.putSerializable("friendlyNameMap", (HashMap) mFriendlyNames); dest.writeBundle(bundle); @@ -237,21 +220,16 @@ public final class OsuProvider implements Parcelable { return false; } OsuProvider that = (OsuProvider) thatObject; - return (mOsuSsid == null ? that.mOsuSsid == null : mOsuSsid.equals(that.mOsuSsid)) - && (mFriendlyNames == null) ? that.mFriendlyNames == null - : mFriendlyNames.equals(that.mFriendlyNames) + return Objects.equals(mOsuSsid, that.mOsuSsid) + && Objects.equals(mFriendlyNames, that.mFriendlyNames) && TextUtils.equals(mServiceDescription, that.mServiceDescription) - && (mServerUri == null ? that.mServerUri == null - : mServerUri.equals(that.mServerUri)) + && Objects.equals(mServerUri, that.mServerUri) && TextUtils.equals(mNetworkAccessIdentifier, that.mNetworkAccessIdentifier) - && (mMethodList == null ? that.mMethodList == null - : mMethodList.equals(that.mMethodList)) - && (mIcon == null ? that.mIcon == null : mIcon.sameAs(that.mIcon)); + && Objects.equals(mMethodList, that.mMethodList); } @Override public int hashCode() { - // mIcon is not hashable, skip the variable. return Objects.hash(mOsuSsid, mServiceDescription, mFriendlyNames, mServerUri, mNetworkAccessIdentifier, mMethodList); } @@ -264,8 +242,7 @@ public final class OsuProvider implements Parcelable { + " mServiceDescription=" + mServiceDescription + " mServerUri=" + mServerUri + " mNetworkAccessIdentifier=" + mNetworkAccessIdentifier - + " mMethodList=" + mMethodList - + " mIcon=" + mIcon; + + " mMethodList=" + mMethodList; } public static final @android.annotation.NonNull Creator CREATOR = @@ -278,12 +255,11 @@ public final class OsuProvider implements Parcelable { String nai = in.readString(); List methodList = new ArrayList<>(); in.readList(methodList, null); - Icon icon = in.readParcelable(null); Bundle bundle = in.readBundle(); Map friendlyNamesMap = (HashMap) bundle.getSerializable( "friendlyNameMap"); return new OsuProvider(osuSsid, friendlyNamesMap, serviceDescription, - serverUri, nai, methodList, icon); + serverUri, nai, methodList); } @Override diff --git a/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java b/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java index 43ee24943e12..2ded849331d7 100644 --- a/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java +++ b/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java @@ -19,7 +19,6 @@ package android.net.wifi.hotspot2; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import android.graphics.drawable.Icon; import android.net.Uri; import android.net.wifi.WifiSsid; import android.os.Parcel; @@ -56,7 +55,6 @@ public class OsuProviderTest { private static final String TEST_NAI = "test.access.com"; private static final List TEST_METHOD_LIST = Arrays.asList(OsuProvider.METHOD_SOAP_XML_SPP); - private static final Icon TEST_ICON = Icon.createWithData(new byte[10], 0, 10); /** * Verify parcel write and read consistency for the given {@link OsuProvider}. @@ -82,7 +80,7 @@ public class OsuProviderTest { */ @Test public void verifyParcelWithEmptyProviderInfo() throws Exception { - verifyParcel(new OsuProvider((WifiSsid) null, null, null, null, null, null, null)); + verifyParcel(new OsuProvider((WifiSsid) null, null, null, null, null, null)); } /** @@ -93,7 +91,7 @@ public class OsuProviderTest { @Test public void verifyParcelWithFullProviderInfo() throws Exception { verifyParcel(new OsuProvider(TEST_SSID, TEST_FRIENDLY_NAMES, - TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI, TEST_METHOD_LIST, TEST_ICON)); + TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI, TEST_METHOD_LIST)); } /** @@ -102,7 +100,7 @@ public class OsuProviderTest { */ @Test public void verifyCopyConstructorWithNullSource() throws Exception { - OsuProvider expected = new OsuProvider((WifiSsid) null, null, null, null, null, null, null); + OsuProvider expected = new OsuProvider((WifiSsid) null, null, null, null, null, null); assertEquals(expected, new OsuProvider(null)); } @@ -114,7 +112,7 @@ public class OsuProviderTest { @Test public void verifyCopyConstructorWithValidSource() throws Exception { OsuProvider source = new OsuProvider(TEST_SSID, TEST_FRIENDLY_NAMES, - TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI, TEST_METHOD_LIST, TEST_ICON); + TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI, TEST_METHOD_LIST); assertEquals(source, new OsuProvider(source)); } @@ -126,7 +124,7 @@ public class OsuProviderTest { @Test public void verifyGetters() throws Exception { OsuProvider provider = new OsuProvider(TEST_SSID, TEST_FRIENDLY_NAMES, - TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI, TEST_METHOD_LIST, TEST_ICON); + TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI, TEST_METHOD_LIST); assertTrue(TEST_SSID.equals(provider.getOsuSsid())); assertTrue(TEST_FRIENDLY_NAME.equals(provider.getFriendlyName())); @@ -135,6 +133,5 @@ public class OsuProviderTest { assertTrue(TEST_SERVER_URI.equals(provider.getServerUri())); assertTrue(TEST_NAI.equals(provider.getNetworkAccessIdentifier())); assertTrue(TEST_METHOD_LIST.equals(provider.getMethodList())); - assertTrue(TEST_ICON.sameAs(provider.getIcon())); } } -- cgit v1.2.3 From ffaf81bee8b481805c83bb182975834b501f299a Mon Sep 17 00:00:00 2001 From: David Su Date: Fri, 29 Nov 2019 19:29:02 -0800 Subject: framework-wifi: fix miscellaneous @hide API usages Bug: 145409537 Test: FrameworksWifiApiTests Change-Id: I9553f7f7d0c980eaf43a9264b256ccf01afba123 --- wifi/java/android/net/wifi/WifiConfiguration.java | 20 +++++++++++++++----- wifi/java/android/net/wifi/WifiManager.java | 6 +++--- .../wifi/aware/WifiAwareAgentNetworkSpecifier.java | 4 ++-- 3 files changed, 20 insertions(+), 10 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index e08a11e0b924..1ba9407687f2 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -39,7 +39,6 @@ import android.text.TextUtils; import android.util.BackupUtils; import android.util.Log; import android.util.SparseArray; -import android.util.TimeUtils; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; @@ -49,6 +48,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Arrays; import java.util.BitSet; +import java.util.Calendar; import java.util.HashMap; /** @@ -2006,6 +2006,16 @@ public class WifiConfiguration implements Parcelable { && enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE; } + private static String logTimeOfDay(long millis) { + Calendar c = Calendar.getInstance(); + if (millis >= 0) { + c.setTimeInMillis(millis); + return String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c); + } else { + return Long.toString(millis); + } + } + @Override public String toString() { StringBuilder sbuf = new StringBuilder(); @@ -2042,7 +2052,7 @@ public class WifiConfiguration implements Parcelable { if (mNetworkSelectionStatus.getConnectChoice() != null) { sbuf.append(" connect choice: ").append(mNetworkSelectionStatus.getConnectChoice()); sbuf.append(" connect choice set time: ") - .append(TimeUtils.logTimeOfDay( + .append(logTimeOfDay( mNetworkSelectionStatus.getConnectChoiceTimestamp())); } sbuf.append(" hasEverConnected: ") @@ -2081,7 +2091,7 @@ public class WifiConfiguration implements Parcelable { sbuf.append(" mRandomizedMacAddress: ").append(mRandomizedMacAddress).append("\n"); sbuf.append(" randomizedMacExpirationTimeMs: ") .append(randomizedMacExpirationTimeMs == 0 ? "" - : TimeUtils.logTimeOfDay(randomizedMacExpirationTimeMs)).append("\n"); + : logTimeOfDay(randomizedMacExpirationTimeMs)).append("\n"); sbuf.append(" KeyMgmt:"); for (int k = 0; k < this.allowedKeyManagement.size(); k++) { if (this.allowedKeyManagement.get(k)) { @@ -2205,7 +2215,7 @@ public class WifiConfiguration implements Parcelable { if (this.lastConnected != 0) { sbuf.append('\n'); - sbuf.append("lastConnected: ").append(TimeUtils.logTimeOfDay(this.lastConnected)); + sbuf.append("lastConnected: ").append(logTimeOfDay(this.lastConnected)); sbuf.append(" "); } sbuf.append('\n'); @@ -2355,7 +2365,7 @@ public class WifiConfiguration implements Parcelable { ? getSsidAndSecurityTypeString() : FQDN + KeyMgmt.strings[KeyMgmt.WPA_EAP]; if (!shared) { - key += "-" + UserHandle.getUserId(creatorUid); + key += "-" + UserHandle.getUserHandleForUid(creatorUid).getIdentifier(); } return key; } diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 6557bbeec039..f037919592bf 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -5105,9 +5105,9 @@ public class WifiManager { Log.v(TAG, "OnWifiUsabilityStatsListener: " + "onWifiUsabilityStats: seqNum=" + seqNum); } - Binder.withCleanCallingIdentity(() -> - executor.execute(() -> listener.onWifiUsabilityStats(seqNum, - isSameBssidAndFreq, stats))); + Binder.clearCallingIdentity(); + executor.execute(() -> listener.onWifiUsabilityStats( + seqNum, isSameBssidAndFreq, stats)); } }, listener.hashCode() diff --git a/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java b/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java index 9164d04885b3..5ec4c8b13ee8 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java @@ -207,14 +207,14 @@ public class WifiAwareAgentNetworkSpecifier extends NetworkSpecifier implements @Override public void writeToParcel(Parcel dest, int flags) { - dest.writeBlob(mData); + dest.writeByteArray(mData); } public static final @android.annotation.NonNull Creator CREATOR = new Creator() { @Override public ByteArrayWrapper createFromParcel(Parcel in) { - return new ByteArrayWrapper(in.readBlob()); + return new ByteArrayWrapper(in.createByteArray()); } @Override -- cgit v1.2.3 From 2a6689646fb4c076e59fc5af43647df2f641addd Mon Sep 17 00:00:00 2001 From: David Su Date: Fri, 29 Nov 2019 20:43:12 -0800 Subject: Remove NetworkPinner usage from WifiManager#enableNetwork NetworkPinner and NetworkRequest$Builder#clearCapabilities() are @hide APIs, remove them from WifiManager#enableNetwork(). Bug: 145409537 Test: atest FrameworksWifiApiTests Change-Id: I138397bf203f603693b1726c6fc34721d7a8111f --- wifi/java/android/net/wifi/WifiManager.java | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 6557bbeec039..50ebb7ef113f 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -36,15 +36,12 @@ import android.content.pm.ParceledListSlice; import android.net.ConnectivityManager; 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; 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; @@ -57,7 +54,6 @@ import android.util.Pair; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; -import com.android.server.net.NetworkPinner; import dalvik.system.CloseGuard; @@ -2022,28 +2018,11 @@ public class WifiManager { */ @Deprecated public boolean enableNetwork(int netId, boolean attemptConnect) { - final boolean pin = attemptConnect && mTargetSdkVersion < Build.VERSION_CODES.LOLLIPOP; - if (pin) { - NetworkRequest request = new NetworkRequest.Builder() - .clearCapabilities() - .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN) - .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) - .build(); - NetworkPinner.pin(mContext, request); - } - - boolean success; try { - success = mService.enableNetwork(netId, attemptConnect, mContext.getOpPackageName()); + return mService.enableNetwork(netId, attemptConnect, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } - - if (pin && !success) { - NetworkPinner.unpin(); - } - - return success; } /** -- cgit v1.2.3 From 0de3620f4af6f99a3d780e4f14a5dbc14472f08c Mon Sep 17 00:00:00 2001 From: David Su Date: Fri, 29 Nov 2019 21:23:52 -0800 Subject: framework-wifi: remove usage of @hide libcore.io.Memory Copy utility methods from libcore.io.Memory to TlvBufferUtils. Bug: 145409537 Test: atest TlvBufferUtilsTest Change-Id: If24c46da75c1138372f08cee74060904f6eeac01 --- .../android/net/wifi/aware/TlvBufferUtils.java | 66 ++++++++++++++++++---- 1 file changed, 55 insertions(+), 11 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/aware/TlvBufferUtils.java b/wifi/java/android/net/wifi/aware/TlvBufferUtils.java index b3b5b2903471..2d3cc1eda643 100644 --- a/wifi/java/android/net/wifi/aware/TlvBufferUtils.java +++ b/wifi/java/android/net/wifi/aware/TlvBufferUtils.java @@ -18,8 +18,6 @@ package android.net.wifi.aware; import android.annotation.Nullable; -import libcore.io.Memory; - import java.nio.BufferOverflowException; import java.nio.ByteOrder; import java.util.ArrayList; @@ -266,7 +264,7 @@ public class TlvBufferUtils { public TlvConstructor putShort(int type, short data) { checkLength(2); addHeader(type, 2); - Memory.pokeShort(mArray, mPosition, data, mByteOrder); + pokeShort(mArray, mPosition, data, mByteOrder); mPosition += 2; return this; } @@ -284,7 +282,7 @@ public class TlvBufferUtils { public TlvConstructor putInt(int type, int data) { checkLength(4); addHeader(type, 4); - Memory.pokeInt(mArray, mPosition, data, mByteOrder); + pokeInt(mArray, mPosition, data, mByteOrder); mPosition += 4; return this; } @@ -349,14 +347,14 @@ public class TlvBufferUtils { if (mTypeSize == 1) { mArray[mPosition] = (byte) type; } else if (mTypeSize == 2) { - Memory.pokeShort(mArray, mPosition, (short) type, mByteOrder); + pokeShort(mArray, mPosition, (short) type, mByteOrder); } mPosition += mTypeSize; if (mLengthSize == 1) { mArray[mPosition] = (byte) length; } else if (mLengthSize == 2) { - Memory.pokeShort(mArray, mPosition, (short) length, mByteOrder); + pokeShort(mArray, mPosition, (short) length, mByteOrder); } mPosition += mLengthSize; } @@ -445,7 +443,7 @@ public class TlvBufferUtils { throw new IllegalArgumentException( "Accesing a short from a TLV element of length " + length); } - return Memory.peekShort(mRefArray, offset, byteOrder); + return peekShort(mRefArray, offset, byteOrder); } /** @@ -460,7 +458,7 @@ public class TlvBufferUtils { throw new IllegalArgumentException( "Accesing an int from a TLV element of length " + length); } - return Memory.peekInt(mRefArray, offset, byteOrder); + return peekInt(mRefArray, offset, byteOrder); } /** @@ -590,7 +588,7 @@ public class TlvBufferUtils { if (mTypeSize == 1) { type = mArray[mOffset]; } else if (mTypeSize == 2) { - type = Memory.peekShort(mArray, mOffset, mByteOrder); + type = peekShort(mArray, mOffset, mByteOrder); } mOffset += mTypeSize; @@ -598,7 +596,7 @@ public class TlvBufferUtils { if (mLengthSize == 1) { length = mArray[mOffset]; } else if (mLengthSize == 2) { - length = Memory.peekShort(mArray, mOffset, mByteOrder); + length = peekShort(mArray, mOffset, mByteOrder); } mOffset += mLengthSize; @@ -661,10 +659,56 @@ public class TlvBufferUtils { if (lengthSize == 1) { nextTlvIndex += lengthSize + array[nextTlvIndex]; } else { - nextTlvIndex += lengthSize + Memory.peekShort(array, nextTlvIndex, byteOrder); + nextTlvIndex += lengthSize + peekShort(array, nextTlvIndex, byteOrder); } } return nextTlvIndex == array.length; } + + private static void pokeShort(byte[] dst, int offset, short value, ByteOrder order) { + if (order == ByteOrder.BIG_ENDIAN) { + dst[offset++] = (byte) ((value >> 8) & 0xff); + dst[offset ] = (byte) ((value >> 0) & 0xff); + } else { + dst[offset++] = (byte) ((value >> 0) & 0xff); + dst[offset ] = (byte) ((value >> 8) & 0xff); + } + } + + private static void pokeInt(byte[] dst, int offset, int value, ByteOrder order) { + if (order == ByteOrder.BIG_ENDIAN) { + dst[offset++] = (byte) ((value >> 24) & 0xff); + dst[offset++] = (byte) ((value >> 16) & 0xff); + dst[offset++] = (byte) ((value >> 8) & 0xff); + dst[offset ] = (byte) ((value >> 0) & 0xff); + } else { + dst[offset++] = (byte) ((value >> 0) & 0xff); + dst[offset++] = (byte) ((value >> 8) & 0xff); + dst[offset++] = (byte) ((value >> 16) & 0xff); + dst[offset ] = (byte) ((value >> 24) & 0xff); + } + } + + private static short peekShort(byte[] src, int offset, ByteOrder order) { + if (order == ByteOrder.BIG_ENDIAN) { + return (short) ((src[offset] << 8) | (src[offset + 1] & 0xff)); + } else { + return (short) ((src[offset + 1] << 8) | (src[offset] & 0xff)); + } + } + + private static int peekInt(byte[] src, int offset, ByteOrder order) { + if (order == ByteOrder.BIG_ENDIAN) { + return ((src[offset++] & 0xff) << 24) + | ((src[offset++] & 0xff) << 16) + | ((src[offset++] & 0xff) << 8) + | ((src[offset ] & 0xff) << 0); + } else { + return ((src[offset++] & 0xff) << 0) + | ((src[offset++] & 0xff) << 8) + | ((src[offset++] & 0xff) << 16) + | ((src[offset ] & 0xff) << 24); + } + } } -- cgit v1.2.3 From 0297bb7c2edd077026a883fda10671dc4fd2df31 Mon Sep 17 00:00:00 2001 From: David Su Date: Fri, 29 Nov 2019 22:17:22 -0800 Subject: Migrate WifiConfiguration to use non-@hide networking APIs Migrate IpConfiguration raw field accesses to getters and setters; migrate ProxyInfo constructor calls to factory method calls. Bug: 145409537 Test: compiles Change-Id: I3ff47e8d2c55bb6c58e7ad4c72f30b8e15db7482 --- wifi/java/android/net/wifi/WifiConfiguration.java | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index e08a11e0b924..faf7625872e3 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -2426,13 +2426,13 @@ public class WifiConfiguration implements Parcelable { @NonNull @SystemApi public IpConfiguration.IpAssignment getIpAssignment() { - return mIpConfiguration.ipAssignment; + return mIpConfiguration.getIpAssignment(); } /** @hide */ @UnsupportedAppUsage public void setIpAssignment(IpConfiguration.IpAssignment ipAssignment) { - mIpConfiguration.ipAssignment = ipAssignment; + mIpConfiguration.setIpAssignment(ipAssignment); } /** @@ -2442,13 +2442,13 @@ public class WifiConfiguration implements Parcelable { @NonNull @SystemApi public IpConfiguration.ProxySettings getProxySettings() { - return mIpConfiguration.proxySettings; + return mIpConfiguration.getProxySettings(); } /** @hide */ @UnsupportedAppUsage public void setProxySettings(IpConfiguration.ProxySettings proxySettings) { - mIpConfiguration.proxySettings = proxySettings; + mIpConfiguration.setProxySettings(proxySettings); } /** @@ -2457,10 +2457,10 @@ public class WifiConfiguration implements Parcelable { * WifiConfiguration, or {@code null} if no proxy is specified. */ public ProxyInfo getHttpProxy() { - if (mIpConfiguration.proxySettings == IpConfiguration.ProxySettings.NONE) { + if (mIpConfiguration.getProxySettings() == IpConfiguration.ProxySettings.NONE) { return null; } - return new ProxyInfo(mIpConfiguration.httpProxy); + return new ProxyInfo(mIpConfiguration.getHttpProxy()); } /** @@ -2485,12 +2485,12 @@ public class WifiConfiguration implements Parcelable { if (!Uri.EMPTY.equals(httpProxy.getPacFileUrl())) { proxySettingCopy = IpConfiguration.ProxySettings.PAC; // Construct a new PAC URL Proxy - httpProxyCopy = new ProxyInfo(httpProxy.getPacFileUrl(), httpProxy.getPort()); + httpProxyCopy = ProxyInfo.buildPacProxy(httpProxy.getPacFileUrl(), httpProxy.getPort()); } else { proxySettingCopy = IpConfiguration.ProxySettings.STATIC; // Construct a new HTTP Proxy - httpProxyCopy = new ProxyInfo(httpProxy.getHost(), httpProxy.getPort(), - httpProxy.getExclusionListAsString()); + httpProxyCopy = ProxyInfo.buildDirectProxy(httpProxy.getHost(), httpProxy.getPort(), + Arrays.asList(httpProxy.getExclusionList())); } if (!httpProxyCopy.isValid()) { throw new IllegalArgumentException("Invalid ProxyInfo: " + httpProxyCopy.toString()); @@ -2505,8 +2505,8 @@ public class WifiConfiguration implements Parcelable { */ @SystemApi public void setProxy(@NonNull ProxySettings settings, @NonNull ProxyInfo proxy) { - mIpConfiguration.proxySettings = settings; - mIpConfiguration.httpProxy = proxy; + mIpConfiguration.setProxySettings(settings); + mIpConfiguration.setHttpProxy(proxy); } /** Implement the Parcelable interface {@hide} */ -- cgit v1.2.3 From 6c1f7010aca129b0f69c4aa1286f75a9b9504979 Mon Sep 17 00:00:00 2001 From: Ahmed ElArabawy Date: Thu, 7 Nov 2019 10:13:56 -0800 Subject: Wifi: Reorganize wifi bands definition This CL reorganizes wifi bands definition to be represented as a bit-mask rather than arbitrary values. This is useful for making it scalable for adding new bands. This is a prep step before adding 6GHz band support. Bug: 139354972 Test: Manual Change-Id: I95b359ed05d429abc81faa726bc6a282b3a3e329 --- wifi/java/android/net/wifi/WifiScanner.java | 72 +++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 19 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index 77f7b9e23fc0..b2930772c217 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -58,38 +58,73 @@ import java.util.concurrent.Executor; @SystemService(Context.WIFI_SCANNING_SERVICE) public class WifiScanner { + /** @hide */ + public static final int WIFI_BAND_INDEX_24_GHZ = 0; + /** @hide */ + public static final int WIFI_BAND_INDEX_5_GHZ = 1; + /** @hide */ + public static final int WIFI_BAND_INDEX_5_GHZ_DFS_ONLY = 2; + /** @hide */ + public static final int WIFI_BAND_COUNT = 3; + /** @hide */ @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = {"WIFI_BAND_"}, value = { - WIFI_BAND_UNSPECIFIED, - WIFI_BAND_24_GHZ, - WIFI_BAND_5_GHZ, - WIFI_BAND_BOTH, - WIFI_BAND_5_GHZ_DFS_ONLY, - WIFI_BAND_24_GHZ_WITH_5GHZ_DFS, - WIFI_BAND_5_GHZ_WITH_DFS, - WIFI_BAND_BOTH_WITH_DFS}) - public @interface WifiBand {} + @IntDef(prefix = {"WIFI_BAND_INDEX_"}, value = { + WIFI_BAND_INDEX_24_GHZ, + WIFI_BAND_INDEX_5_GHZ, + WIFI_BAND_INDEX_5_GHZ_DFS_ONLY}) + public @interface WifiBandIndex {} /** no band specified; use channel list instead */ public static final int WIFI_BAND_UNSPECIFIED = 0; /** 2.4 GHz band */ - public static final int WIFI_BAND_24_GHZ = 1; + public static final int WIFI_BAND_24_GHZ = 1 << WIFI_BAND_INDEX_24_GHZ; /** 5 GHz band excluding DFS channels */ - public static final int WIFI_BAND_5_GHZ = 2; - /** Both 2.4 GHz band and 5 GHz band; no DFS channels */ - public static final int WIFI_BAND_BOTH = 3; + public static final int WIFI_BAND_5_GHZ = 1 << WIFI_BAND_INDEX_5_GHZ; /** DFS channels from 5 GHz band only */ - public static final int WIFI_BAND_5_GHZ_DFS_ONLY = 4; + public static final int WIFI_BAND_5_GHZ_DFS_ONLY = 1 << WIFI_BAND_INDEX_5_GHZ_DFS_ONLY; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"WIFI_BAND_"}, value = { + WIFI_BAND_UNSPECIFIED, + WIFI_BAND_24_GHZ, + WIFI_BAND_5_GHZ, + WIFI_BAND_5_GHZ_DFS_ONLY}) + public @interface WifiBandBasic {} + + /** + * Combination of bands + * Note that those are only the common band combinations, + * other combinations can be created by combining any of the basic bands above + */ + /** Both 2.4 GHz band and 5 GHz band; no DFS channels */ + public static final int WIFI_BAND_BOTH = WIFI_BAND_24_GHZ | WIFI_BAND_5_GHZ; /** * 2.4Ghz band + DFS channels from 5 GHz band only * @hide */ - public static final int WIFI_BAND_24_GHZ_WITH_5GHZ_DFS = 5; + public static final int WIFI_BAND_24_GHZ_WITH_5GHZ_DFS = + WIFI_BAND_24_GHZ | WIFI_BAND_5_GHZ_DFS_ONLY; /** 5 GHz band including DFS channels */ - public static final int WIFI_BAND_5_GHZ_WITH_DFS = 6; + public static final int WIFI_BAND_5_GHZ_WITH_DFS = WIFI_BAND_5_GHZ | WIFI_BAND_5_GHZ_DFS_ONLY; /** Both 2.4 GHz band and 5 GHz band; with DFS channels */ - public static final int WIFI_BAND_BOTH_WITH_DFS = 7; + public static final int WIFI_BAND_BOTH_WITH_DFS = + WIFI_BAND_24_GHZ | WIFI_BAND_5_GHZ | WIFI_BAND_5_GHZ_DFS_ONLY; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"WIFI_BAND_"}, value = { + WIFI_BAND_UNSPECIFIED, + WIFI_BAND_24_GHZ, + WIFI_BAND_5_GHZ, + WIFI_BAND_BOTH, + WIFI_BAND_5_GHZ_DFS_ONLY, + WIFI_BAND_24_GHZ_WITH_5GHZ_DFS, + WIFI_BAND_5_GHZ_WITH_DFS, + WIFI_BAND_BOTH_WITH_DFS}) + public @interface WifiBand {} + /** * Max band value * @hide @@ -398,7 +433,6 @@ public class WifiScanner { return new ScanSettings[size]; } }; - } /** -- cgit v1.2.3 From 14361ea9cacd0b5cdb91ed1494a87bd94635ee76 Mon Sep 17 00:00:00 2001 From: David Su Date: Wed, 30 Oct 2019 13:50:40 -0700 Subject: Make WifiActivityEnergyInfo @SystemApi Bug: 145244073 Test: atest FrameworksWifiApiTests Change-Id: Ib91a3b23c92c003146868bac605ff61a7475b1ff --- .../android/net/wifi/WifiActivityEnergyInfo.java | 260 +++++++++++---------- .../src/android/net/wifi/WifiManagerTest.java | 2 +- 2 files changed, 142 insertions(+), 120 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.java b/wifi/java/android/net/wifi/WifiActivityEnergyInfo.java index 0f7fc2d48b7d..f0f31fae0aeb 100644 --- a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.java +++ b/wifi/java/android/net/wifi/WifiActivityEnergyInfo.java @@ -16,10 +16,14 @@ package android.net.wifi; +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; -import java.util.Arrays; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; /** * Record of energy and activity information from controller and @@ -27,179 +31,197 @@ import java.util.Arrays; * real-time. * @hide */ +@SystemApi public final class WifiActivityEnergyInfo implements Parcelable { - /** - * @hide - */ - public long mTimestamp; - - /** - * @hide - */ - public int mStackState; - - /** - * @hide - */ - public long mControllerTxTimeMs; - - /** - * @hide - */ - public long[] mControllerTxTimePerLevelMs; - - /** - * @hide - */ - public long mControllerRxTimeMs; - - /** - * @hide - */ - public long mControllerScanTimeMs; - - /** - * @hide - */ - public long mControllerIdleTimeMs; - - /** - * @hide - */ - public long mControllerEnergyUsed; - + private long mTimeSinceBootMillis; + @StackState + private int mStackState; + private long mControllerTxDurationMillis; + private long mControllerRxDurationMillis; + private long mControllerScanDurationMillis; + private long mControllerIdleDurationMillis; + private long mControllerEnergyUsedMicroJoules; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"STACK_STATE_"}, value = { + STACK_STATE_INVALID, + STACK_STATE_STATE_ACTIVE, + STACK_STATE_STATE_SCANNING, + STACK_STATE_STATE_IDLE}) + public @interface StackState {} + + /** Invalid Wifi stack state. */ public static final int STACK_STATE_INVALID = 0; + /** Wifi stack is active. */ public static final int STACK_STATE_STATE_ACTIVE = 1; + /** Wifi stack is scanning. */ public static final int STACK_STATE_STATE_SCANNING = 2; + /** Wifi stack is idle. */ public static final int STACK_STATE_STATE_IDLE = 3; - public WifiActivityEnergyInfo(long timestamp, int stackState, - long txTime, long[] txTimePerLevel, long rxTime, long scanTime, - long idleTime, long energyUsed) { - mTimestamp = timestamp; + /** + * Constructor. + * + * @param timeSinceBootMillis the time since boot, in milliseconds. + * @param stackState The current state of the Wifi Stack. One of {@link #STACK_STATE_INVALID}, + * {@link #STACK_STATE_STATE_ACTIVE}, {@link #STACK_STATE_STATE_SCANNING}, + * or {@link #STACK_STATE_STATE_IDLE}. + * @param txDurationMillis Cumulative milliseconds of active transmission. + * @param rxDurationMillis Cumulative milliseconds of active receive. + * @param scanDurationMillis Cumulative milliseconds when radio is awake due to scan. + * @param idleDurationMillis Cumulative milliseconds when radio is awake but not transmitting or + * receiving. + * @param energyUsedMicroJoules Cumulative energy consumed by Wifi, in microjoules. + */ + public WifiActivityEnergyInfo( + long timeSinceBootMillis, + @StackState int stackState, + long txDurationMillis, + long rxDurationMillis, + long scanDurationMillis, + long idleDurationMillis, + long energyUsedMicroJoules) { + mTimeSinceBootMillis = timeSinceBootMillis; mStackState = stackState; - mControllerTxTimeMs = txTime; - mControllerTxTimePerLevelMs = txTimePerLevel; - mControllerRxTimeMs = rxTime; - mControllerScanTimeMs = scanTime; - mControllerIdleTimeMs = idleTime; - mControllerEnergyUsed = energyUsed; + mControllerTxDurationMillis = txDurationMillis; + mControllerRxDurationMillis = rxDurationMillis; + mControllerScanDurationMillis = scanDurationMillis; + mControllerIdleDurationMillis = idleDurationMillis; + mControllerEnergyUsedMicroJoules = energyUsedMicroJoules; } @Override public String toString() { return "WifiActivityEnergyInfo{" - + " timestamp=" + mTimestamp - + " mStackState=" + mStackState - + " mControllerTxTimeMs=" + mControllerTxTimeMs - + " mControllerTxTimePerLevelMs=" + Arrays.toString(mControllerTxTimePerLevelMs) - + " mControllerRxTimeMs=" + mControllerRxTimeMs - + " mControllerScanTimeMs=" + mControllerScanTimeMs - + " mControllerIdleTimeMs=" + mControllerIdleTimeMs - + " mControllerEnergyUsed=" + mControllerEnergyUsed - + " }"; - } - - public static final @android.annotation.NonNull Parcelable.Creator CREATOR = + + " mTimeSinceBootMillis=" + mTimeSinceBootMillis + + " mStackState=" + mStackState + + " mControllerTxDurationMillis=" + mControllerTxDurationMillis + + " mControllerRxDurationMillis=" + mControllerRxDurationMillis + + " mControllerScanDurationMillis=" + mControllerScanDurationMillis + + " mControllerIdleDurationMillis=" + mControllerIdleDurationMillis + + " mControllerEnergyUsedMicroJoules=" + mControllerEnergyUsedMicroJoules + + " }"; + } + + public static final @NonNull Parcelable.Creator CREATOR = new Parcelable.Creator() { public WifiActivityEnergyInfo createFromParcel(Parcel in) { long timestamp = in.readLong(); int stackState = in.readInt(); long txTime = in.readLong(); - long[] txTimePerLevel = in.createLongArray(); long rxTime = in.readLong(); long scanTime = in.readLong(); long idleTime = in.readLong(); long energyUsed = in.readLong(); return new WifiActivityEnergyInfo(timestamp, stackState, - txTime, txTimePerLevel, rxTime, scanTime, idleTime, energyUsed); + txTime, rxTime, scanTime, idleTime, energyUsed); } public WifiActivityEnergyInfo[] newArray(int size) { return new WifiActivityEnergyInfo[size]; } }; - public void writeToParcel(Parcel out, int flags) { - out.writeLong(mTimestamp); + @Override + public void writeToParcel(@NonNull Parcel out, int flags) { + out.writeLong(mTimeSinceBootMillis); out.writeInt(mStackState); - out.writeLong(mControllerTxTimeMs); - out.writeLongArray(mControllerTxTimePerLevelMs); - out.writeLong(mControllerRxTimeMs); - out.writeLong(mControllerScanTimeMs); - out.writeLong(mControllerIdleTimeMs); - out.writeLong(mControllerEnergyUsed); + out.writeLong(mControllerTxDurationMillis); + out.writeLong(mControllerRxDurationMillis); + out.writeLong(mControllerScanDurationMillis); + out.writeLong(mControllerIdleDurationMillis); + out.writeLong(mControllerEnergyUsedMicroJoules); } + @Override public int describeContents() { return 0; } + /** Get the timestamp (milliseconds since boot) of record creation. */ + public long getTimeSinceBootMillis() { + return mTimeSinceBootMillis; + } + + /** Set the timestamp (milliseconds since boot) of record creation. */ + public void setTimeSinceBootMillis(long timeSinceBootMillis) { + mTimeSinceBootMillis = timeSinceBootMillis; + } + /** - * @return bt stack reported state + * Get the Wifi stack reported state. One of {@link #STACK_STATE_INVALID}, + * {@link #STACK_STATE_STATE_ACTIVE}, {@link #STACK_STATE_STATE_SCANNING}, + * {@link #STACK_STATE_STATE_IDLE}. */ + @StackState public int getStackState() { return mStackState; } /** - * @return tx time in ms + * Set the Wifi stack reported state. One of {@link #STACK_STATE_INVALID}, + * {@link #STACK_STATE_STATE_ACTIVE}, {@link #STACK_STATE_STATE_SCANNING}, + * {@link #STACK_STATE_STATE_IDLE}. */ - public long getControllerTxTimeMillis() { - return mControllerTxTimeMs; + public void setStackState(@StackState int stackState) { + mStackState = stackState; } - /** - * @return tx time at power level provided in ms - */ - public long getControllerTxTimeMillisAtLevel(int level) { - if (level < mControllerTxTimePerLevelMs.length) { - return mControllerTxTimePerLevelMs[level]; - } - return 0; + /** Get the Wifi transmission duration, in milliseconds. */ + public long getControllerTxDurationMillis() { + return mControllerTxDurationMillis; } - /** - * @return rx time in ms - */ - public long getControllerRxTimeMillis() { - return mControllerRxTimeMs; + /** Set the Wifi transmission duration, in milliseconds. */ + public void setControllerTxDurationMillis(long controllerTxDurationMillis) { + mControllerTxDurationMillis = controllerTxDurationMillis; } - /** - * @return scan time in ms - */ - public long getControllerScanTimeMillis() { - return mControllerScanTimeMs; + /** Get the Wifi receive duration, in milliseconds. */ + public long getControllerRxDurationMillis() { + return mControllerRxDurationMillis; } - /** - * @return idle time in ms - */ - public long getControllerIdleTimeMillis() { - return mControllerIdleTimeMs; + /** Set the Wifi receive duration, in milliseconds. */ + public void setControllerRxDurationMillis(long controllerRxDurationMillis) { + mControllerRxDurationMillis = controllerRxDurationMillis; } - /** - * product of current(mA), voltage(V) and time(ms) - * @return energy used - */ - public long getControllerEnergyUsed() { - return mControllerEnergyUsed; + /** Get the Wifi scan duration, in milliseconds. */ + public long getControllerScanDurationMillis() { + return mControllerScanDurationMillis; } - /** - * @return timestamp(wall clock) of record creation - */ - public long getTimeStamp() { - return mTimestamp; + + /** Set the Wifi scan duration, in milliseconds. */ + public void setControllerScanDurationMillis(long controllerScanDurationMillis) { + mControllerScanDurationMillis = controllerScanDurationMillis; } - /** - * @return if the record is valid - */ + /** Get the Wifi idle duration, in milliseconds. */ + public long getControllerIdleDurationMillis() { + return mControllerIdleDurationMillis; + } + + /** Set the Wifi idle duration, in milliseconds. */ + public void setControllerIdleDurationMillis(long controllerIdleDurationMillis) { + mControllerIdleDurationMillis = controllerIdleDurationMillis; + } + + /** Get the energy consumed by Wifi, in microjoules. */ + public long getControllerEnergyUsedMicroJoules() { + return mControllerEnergyUsedMicroJoules; + } + + /** Set the energy consumed by Wifi, in microjoules. */ + public void setControllerEnergyUsedMicroJoules(long controllerEnergyUsedMicroJoules) { + mControllerEnergyUsedMicroJoules = controllerEnergyUsedMicroJoules; + } + + /** Returns true if the record is valid, false otherwise. */ public boolean isValid() { - return ((mControllerTxTimeMs >=0) && - (mControllerRxTimeMs >=0) && - (mControllerScanTimeMs >=0) && - (mControllerIdleTimeMs >=0)); + return mControllerTxDurationMillis >= 0 + && mControllerRxDurationMillis >= 0 + && mControllerScanDurationMillis >= 0 + && mControllerIdleDurationMillis >= 0; } -} \ No newline at end of file +} diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index d326201fa574..8b68bb430c51 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -1620,7 +1620,7 @@ public class WifiManagerTest { @Test public void testGetControllerActivityEnergyInfo() throws Exception { WifiActivityEnergyInfo activityEnergyInfo = - new WifiActivityEnergyInfo(5, 3, 3, new long[]{5L, 5L, 5L}, 5, 5, 5, 5); + new WifiActivityEnergyInfo(5, 3, 3, 5, 5, 5, 5); when(mWifiService.reportActivityInfo()).thenReturn(activityEnergyInfo); assertEquals(activityEnergyInfo, mWifiManager.getControllerActivityEnergyInfo()); -- cgit v1.2.3 From 692d3750a6361bf83f40f5c8081b2c31cdbf2af8 Mon Sep 17 00:00:00 2001 From: lesl Date: Wed, 27 Nov 2019 16:17:47 +0800 Subject: wifi: Use SoftApConfiguration to replace WifiConfiguration for SoftAp Add new APIs for soft Ap enable/configuration set and get. Bug: 142752869 Test: atest frameworks/base/wifi/tests/ Test: Manual Test, softAP enable/disable/configuration change. Change-Id: Ie9c666d6c10d59d53bd75768e9eb2da1de22fb55 --- wifi/java/android/net/wifi/IWifiManager.aidl | 12 + .../java/android/net/wifi/SoftApConfiguration.java | 276 +++++++++++++++++++-- wifi/java/android/net/wifi/WifiManager.java | 101 +++++++- .../com/android/server/wifi/BaseWifiService.java | 26 ++ .../android/net/wifi/SoftApConfigurationTest.java | 37 +++ .../src/android/net/wifi/WifiManagerTest.java | 64 +++++ 6 files changed, 499 insertions(+), 17 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 4a89c66dd0a0..032f66af2433 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -142,6 +142,8 @@ interface IWifiManager boolean startSoftAp(in WifiConfiguration wifiConfig); + boolean startTetheredHotspot(in SoftApConfiguration softApConfig); + boolean stopSoftAp(); int startLocalOnlyHotspot(in ILocalOnlyHotspotCallback callback, String packageName, @@ -159,8 +161,14 @@ interface IWifiManager @UnsupportedAppUsage WifiConfiguration getWifiApConfiguration(); + SoftApConfiguration getSoftApConfiguration(); + boolean setWifiApConfiguration(in WifiConfiguration wifiConfig, String packageName); + boolean setSoftApConfiguration(in SoftApConfiguration softApConfig, String packageName); + + void notifyUserOfApBandConversion(String packageName); + void enableTdls(String remoteIPAddress, boolean enable); void enableTdlsWithMacAddress(String remoteMacAddress, boolean enable); @@ -184,6 +192,10 @@ interface IWifiManager void restoreBackupData(in byte[] data); + byte[] retrieveSoftApBackupData(); + + void restoreSoftApBackupData(in byte[] data); + void restoreSupplicantBackupData(in byte[] supplicantData, in byte[] ipConfigData); void startSubscriptionProvisioning(in OsuProvider provider, in IProvisioningCallback callback); diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java index 4cc86539926c..8030bd66e313 100644 --- a/wifi/java/android/net/wifi/SoftApConfiguration.java +++ b/wifi/java/android/net/wifi/SoftApConfiguration.java @@ -16,28 +16,34 @@ package android.net.wifi; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.net.MacAddress; import android.os.Parcel; import android.os.Parcelable; +import android.text.TextUtils; import com.android.internal.util.Preconditions; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.nio.charset.CharsetEncoder; import java.nio.charset.StandardCharsets; import java.util.Objects; import java.util.concurrent.Executor; /** - * WiFi configuration for a soft access point (a.k.a. Soft AP, SAP, Hotspot). + * Configuration for a soft access point (a.k.a. Soft AP, SAP, Hotspot). * * This is input for the framework provided by a client app, i.e. it exposes knobs to instruct the - * framework how it should open a hotspot. It is not meant to describe the network as it will be - * seen by clients; this role is currently served by {@link WifiConfiguration} (see - * {@link WifiManager.LocalOnlyHotspotReservation#getWifiConfiguration()}). + * framework how it should configure a hotspot. * - * System apps can use this to configure a local-only hotspot using + * System apps can use this to configure a tethered hotspot using + * {@link WifiManager#startTetheredHotspot(SoftApConfiguration)} and + * {@link WifiManager#setSoftApConfiguration(SoftApConfiguration)} + * or local-only hotspot using * {@link WifiManager#startLocalOnlyHotspot(SoftApConfiguration, Executor, * WifiManager.LocalOnlyHotspotCallback)}. * @@ -48,25 +54,106 @@ import java.util.concurrent.Executor; */ @SystemApi public final class SoftApConfiguration implements Parcelable { + + /** + * 2GHz band. + * @hide + */ + @SystemApi + public static final int BAND_2GHZ = 0; + + /** + * 5GHz band. + * @hide + */ + @SystemApi + public static final int BAND_5GHZ = 1; + + /** + * Device is allowed to choose the optimal band (2Ghz or 5Ghz) based on device capability, + * operating country code and current radio conditions. + * @hide + */ + @SystemApi + public static final int BAND_ANY = -1; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = { "BAND_TYPE_" }, value = { + BAND_2GHZ, + BAND_5GHZ, + BAND_ANY, + }) + public @interface BandType {} + /** * SSID for the AP, or null for a framework-determined SSID. */ private final @Nullable String mSsid; + /** * BSSID for the AP, or null to use a framework-determined BSSID. */ private final @Nullable MacAddress mBssid; + /** * Pre-shared key for WPA2-PSK encryption (non-null enables WPA2-PSK). */ private final @Nullable String mWpa2Passphrase; + /** + * This is a network that does not broadcast its SSID, so an + * SSID-specific probe request must be used for scans. + */ + private final boolean mHiddenSsid; + + /** + * The operating band of the AP. + * One of the band types from {@link @BandType}. + */ + private final @BandType int mBand; + + /** + * The operating channel of the AP. + */ + private final int mChannel; + + /** + * The operating security type of the AP. + * One of the security types from {@link @SecurityType} + */ + private final @SecurityType int mSecurityType; + + /** + * Security types we support. + */ + /** @hide */ + @SystemApi + public static final int SECURITY_TYPE_OPEN = 0; + + /** @hide */ + @SystemApi + public static final int SECURITY_TYPE_WPA2_PSK = 1; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = { "SECURITY_TYPE" }, value = { + SECURITY_TYPE_OPEN, + SECURITY_TYPE_WPA2_PSK, + }) + public @interface SecurityType {} + /** Private constructor for Builder and Parcelable implementation. */ - private SoftApConfiguration( - @Nullable String ssid, @Nullable MacAddress bssid, String wpa2Passphrase) { + private SoftApConfiguration(@Nullable String ssid, @Nullable MacAddress bssid, + @Nullable String wpa2Passphrase, boolean hiddenSsid, @BandType int band, int channel, + @SecurityType int securityType) { mSsid = ssid; mBssid = bssid; mWpa2Passphrase = wpa2Passphrase; + mHiddenSsid = hiddenSsid; + mBand = band; + mChannel = channel; + mSecurityType = securityType; } @Override @@ -80,12 +167,31 @@ public final class SoftApConfiguration implements Parcelable { SoftApConfiguration other = (SoftApConfiguration) otherObj; return Objects.equals(mSsid, other.mSsid) && Objects.equals(mBssid, other.mBssid) - && Objects.equals(mWpa2Passphrase, other.mWpa2Passphrase); + && Objects.equals(mWpa2Passphrase, other.mWpa2Passphrase) + && mHiddenSsid == other.mHiddenSsid + && mBand == other.mBand + && mChannel == other.mChannel + && mSecurityType == other.mSecurityType; } @Override public int hashCode() { - return Objects.hash(mSsid, mBssid, mWpa2Passphrase); + return Objects.hash(mSsid, mBssid, mWpa2Passphrase, mHiddenSsid, + mBand, mChannel, mSecurityType); + } + + @Override + public String toString() { + StringBuilder sbuf = new StringBuilder(); + sbuf.append("ssid=").append(mSsid); + if (mBssid != null) sbuf.append(" \n bssid=").append(mBssid.toString()); + sbuf.append(" \n Wpa2Passphrase =").append( + TextUtils.isEmpty(mWpa2Passphrase) ? "" : ""); + sbuf.append(" \n HiddenSsid =").append(mHiddenSsid); + sbuf.append(" \n Band =").append(mBand); + sbuf.append(" \n Channel =").append(mChannel); + sbuf.append(" \n SecurityType=").append(getSecurityType()); + return sbuf.toString(); } @Override @@ -93,6 +199,10 @@ public final class SoftApConfiguration implements Parcelable { dest.writeString(mSsid); dest.writeParcelable(mBssid, flags); dest.writeString(mWpa2Passphrase); + dest.writeBoolean(mHiddenSsid); + dest.writeInt(mBand); + dest.writeInt(mChannel); + dest.writeInt(mSecurityType); } @Override @@ -107,7 +217,7 @@ public final class SoftApConfiguration implements Parcelable { return new SoftApConfiguration( in.readString(), in.readParcelable(MacAddress.class.getClassLoader()), - in.readString()); + in.readString(), in.readBoolean(), in.readInt(), in.readInt(), in.readInt()); } @Override @@ -116,21 +226,67 @@ public final class SoftApConfiguration implements Parcelable { } }; + /** + * Return String set to be the SSID for the AP. + * {@link #setSsid(String)}. + */ @Nullable public String getSsid() { return mSsid; } + /** + * Returns MAC address set to be BSSID for the AP. + * {@link #setBssid(MacAddress)}. + */ @Nullable public MacAddress getBssid() { return mBssid; } + /** + * Returns String set to be passphrase for the WPA2-PSK AP. + * {@link #setWpa2Passphrase(String)}. + */ @Nullable public String getWpa2Passphrase() { return mWpa2Passphrase; } + /** + * Returns Boolean set to be indicate hidden (true: doesn't broadcast its SSID) or + * not (false: broadcasts its SSID) for the AP. + * {@link #setHiddenSsid(boolean)}. + */ + public boolean isHiddenSsid() { + return mHiddenSsid; + } + + /** + * Returns {@link BandType} set to be the band for the AP. + * {@link #setBand(@BandType int)}. + */ + public @BandType int getBand() { + return mBand; + } + + /** + * Returns Integer set to be the channel for the AP. + * {@link #setChannel(int)}. + */ + public int getChannel() { + return mChannel; + } + + /** + * Get security type params which depends on which security passphrase to set. + * + * @return One of the security types from {@link SecurityType}. + */ + public @SecurityType int getSecurityType() { + return mSecurityType; + } + /** * Builds a {@link SoftApConfiguration}, which allows an app to configure various aspects of a * Soft AP. @@ -142,6 +298,21 @@ public final class SoftApConfiguration implements Parcelable { private String mSsid; private MacAddress mBssid; private String mWpa2Passphrase; + private boolean mHiddenSsid; + private int mBand; + private int mChannel; + + private int setSecurityType() { + int securityType = SECURITY_TYPE_OPEN; + if (!TextUtils.isEmpty(mWpa2Passphrase)) { // WPA2-PSK network. + securityType = SECURITY_TYPE_WPA2_PSK; + } + return securityType; + } + + private void clearAllPassphrase() { + mWpa2Passphrase = null; + } /** * Constructs a Builder with default values (see {@link Builder}). @@ -150,6 +321,9 @@ public final class SoftApConfiguration implements Parcelable { mSsid = null; mBssid = null; mWpa2Passphrase = null; + mHiddenSsid = false; + mBand = BAND_2GHZ; + mChannel = 0; } /** @@ -161,6 +335,9 @@ public final class SoftApConfiguration implements Parcelable { mSsid = other.mSsid; mBssid = other.mBssid; mWpa2Passphrase = other.mWpa2Passphrase; + mHiddenSsid = other.mHiddenSsid; + mBand = other.mBand; + mChannel = other.mChannel; } /** @@ -170,11 +347,16 @@ public final class SoftApConfiguration implements Parcelable { */ @NonNull public SoftApConfiguration build() { - return new SoftApConfiguration(mSsid, mBssid, mWpa2Passphrase); + return new SoftApConfiguration(mSsid, mBssid, mWpa2Passphrase, + mHiddenSsid, mBand, mChannel, setSecurityType()); } /** * Specifies an SSID for the AP. + *

    + * Null SSID only support when configure a local-only hotspot. + *

    + *

  • If not set, defaults to null.
  • * * @param ssid SSID of valid Unicode characters, or null to have the SSID automatically * chosen by the framework. @@ -193,7 +375,10 @@ public final class SoftApConfiguration implements Parcelable { /** * Specifies a BSSID for the AP. - * + *

    + * Only supported when configuring a local-only hotspot. + *

    + *

  • If not set, defaults to null.
  • * @param bssid BSSID, or null to have the BSSID chosen by the framework. The caller is * responsible for avoiding collisions. * @return Builder for chaining. @@ -211,8 +396,9 @@ public final class SoftApConfiguration implements Parcelable { } /** - * Specifies that this AP should use WPA2-PSK with the given passphrase. When set to null - * and no other encryption method is configured, an open network is created. + * Specifies that this AP should use WPA2-PSK with the given ASCII WPA2 passphrase. + * When set to null, an open network is created. + *

    * * @param passphrase The passphrase to use, or null to unset a previously-set WPA2-PSK * configuration. @@ -222,10 +408,72 @@ public final class SoftApConfiguration implements Parcelable { @NonNull public Builder setWpa2Passphrase(@Nullable String passphrase) { if (passphrase != null) { + final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder(); + if (!asciiEncoder.canEncode(passphrase)) { + throw new IllegalArgumentException("passphrase not ASCII encodable"); + } Preconditions.checkStringNotEmpty(passphrase); } + clearAllPassphrase(); mWpa2Passphrase = passphrase; return this; } + + /** + * Specifies whether the AP is hidden (doesn't broadcast its SSID) or + * not (broadcasts its SSID). + *

    + *

  • If not set, defaults to false (i.e not a hidden network).
  • + * + * @param hiddenSsid true for a hidden SSID, false otherwise. + * @return Builder for chaining. + */ + @NonNull + public Builder setHiddenSsid(boolean hiddenSsid) { + mHiddenSsid = hiddenSsid; + return this; + } + + /** + * Specifies the band for the AP. + *

    + *

  • If not set, defaults to BAND_2GHZ {@link @BandType}.
  • + * + * @param band One of the band types from {@link @BandType}. + * @return Builder for chaining. + */ + @NonNull + public Builder setBand(@BandType int band) { + switch (band) { + case BAND_2GHZ: + break; + case BAND_5GHZ: + break; + case BAND_ANY: + break; + default: + throw new IllegalArgumentException("Invalid band type"); + } + mBand = band; + return this; + } + + /** + * Specifies the channel for the AP. + * + * The channel which AP resides on. Valid channels are country dependent. + * Use the special channel value 0 to have the framework auto-select a valid channel + * from the band configured with {@link #setBand(@BandType int)}. + * + *

    + *

  • If not set, defaults to 0.
  • + * @param channel operating channel of the AP. + * @return Builder for chaining. + */ + @NonNull + public Builder setChannel(int channel) { + mChannel = channel; + return this; + } } } diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index bf609d765502..e2e6728068a9 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -2739,7 +2739,6 @@ public class WifiManager { * * @hide */ - @SystemApi @RequiresPermission(anyOf = { android.Manifest.permission.NETWORK_STACK, NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK @@ -2752,6 +2751,31 @@ public class WifiManager { } } + /** + * Start Soft AP (hotspot) mode for tethering purposes with the specified configuration. + * Note that starting Soft AP mode may disable station mode operation if the device does not + * support concurrency. + * @param softApConfig A valid SoftApConfiguration specifying the configuration of the SAP, + * or null to use the persisted Soft AP configuration that was previously + * set using {@link #setSoftApConfiguration(softApConfiguration)}. + * @return {@code true} if the operation succeeded, {@code false} otherwise + * + * @hide + */ + @SystemApi + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_STACK, + NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK + }) + public boolean startTetheredHotspot(@Nullable SoftApConfiguration softApConfig) { + try { + return mService.startTetheredHotspot(softApConfig); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Stop SoftAp mode. * Note that stopping softap mode will restore the previous wifi mode. @@ -3036,10 +3060,12 @@ public class WifiManager { * Gets the Wi-Fi AP Configuration. * @return AP details in WifiConfiguration * + * @deprecated This API is deprecated. Use {@link #getSoftApConfiguration()} instead. * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) + @Deprecated public WifiConfiguration getWifiApConfiguration() { try { return mService.getWifiApConfiguration(); @@ -3049,14 +3075,33 @@ public class WifiManager { } /** - * Sets the Wi-Fi AP Configuration. The AP configuration must either be open or - * WPA2 PSK networks. + * Gets the Wi-Fi AP Configuration. + * @return AP details in {@link SoftApConfiguration} + * + * @hide + */ + @NonNull + @SystemApi + @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) + public SoftApConfiguration getSoftApConfiguration() { + try { + return mService.getSoftApConfiguration(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Sets the Wi-Fi AP Configuration. * @return {@code true} if the operation succeeded, {@code false} otherwise * + * @deprecated This API is deprecated. Use {@link #setSoftApConfiguration(SoftApConfiguration)} + * instead. * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) + @Deprecated public boolean setWifiApConfiguration(WifiConfiguration wifiConfig) { try { return mService.setWifiApConfiguration(wifiConfig, mContext.getOpPackageName()); @@ -3065,6 +3110,26 @@ public class WifiManager { } } + /** + * Sets the Wi-Fi AP Configuration. + * + * @param softApConfig A valid SoftApConfiguration specifying the configuration of the SAP. + + * @return {@code true} if the operation succeeded, {@code false} otherwise + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) + public boolean setSoftApConfiguration(@NonNull SoftApConfiguration softApConfig) { + try { + return mService.setSoftApConfiguration( + softApConfig, mContext.getOpPackageName()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Enable/Disable TDLS on a specific local route. * @@ -4547,6 +4612,36 @@ public class WifiManager { } } + /** + * Retrieve the soft ap config data to be backed to save current config data. + * @hide + */ + @Nullable + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) + public byte[] retrieveSoftApBackupData() { + try { + return mService.retrieveSoftApBackupData(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Restore soft ap config from the backed up data. + * @hide + */ + @Nullable + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) + public void restoreSoftApBackupData(@NonNull byte[] data) { + try { + mService.restoreSoftApBackupData(data); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Restore state from the older version of back up data. * The old backup data was essentially a backup of wpa_supplicant.conf diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index 534e609f9af4..bc8683921321 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -284,6 +284,11 @@ public class BaseWifiService extends IWifiManager.Stub { throw new UnsupportedOperationException(); } + @Override + public boolean startTetheredHotspot(SoftApConfiguration softApConfig) { + throw new UnsupportedOperationException(); + } + @Override public boolean stopSoftAp() { throw new UnsupportedOperationException(); @@ -320,11 +325,22 @@ public class BaseWifiService extends IWifiManager.Stub { throw new UnsupportedOperationException(); } + @Override + public SoftApConfiguration getSoftApConfiguration() { + throw new UnsupportedOperationException(); + } + @Override public boolean setWifiApConfiguration(WifiConfiguration wifiConfig, String packageName) { throw new UnsupportedOperationException(); } + @Override + public boolean setSoftApConfiguration(SoftApConfiguration softApConfig, String packageName) { + throw new UnsupportedOperationException(); + } + + @Override public void notifyUserOfApBandConversion(String packageName) { throw new UnsupportedOperationException(); } @@ -384,6 +400,16 @@ public class BaseWifiService extends IWifiManager.Stub { throw new UnsupportedOperationException(); } + @Override + public byte[] retrieveSoftApBackupData() { + throw new UnsupportedOperationException(); + } + + @Override + public void restoreSoftApBackupData(byte[] data) { + throw new UnsupportedOperationException(); + } + @Override public void restoreSupplicantBackupData(byte[] supplicantData, byte[] ipConfigData) { throw new UnsupportedOperationException(); diff --git a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java index 949b4790d998..b8d3e413f1d2 100644 --- a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java @@ -46,6 +46,10 @@ public class SoftApConfigurationTest { assertThat(original.getSsid()).isEqualTo("ssid"); assertThat(original.getBssid()).isEqualTo(MacAddress.fromString("11:22:33:44:55:66")); assertThat(original.getWpa2Passphrase()).isNull(); + assertThat(original.getSecurityType()).isEqualTo(SoftApConfiguration.SECURITY_TYPE_OPEN); + assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_2GHZ); + assertThat(original.getChannel()).isEqualTo(0); + assertThat(original.isHiddenSsid()).isEqualTo(false); SoftApConfiguration unparceled = parcelUnparcel(original); assertThat(unparceled).isNotSameAs(original); @@ -64,6 +68,39 @@ public class SoftApConfigurationTest { .setWpa2Passphrase("secretsecret") .build(); assertThat(original.getWpa2Passphrase()).isEqualTo("secretsecret"); + assertThat(original.getSecurityType()).isEqualTo( + SoftApConfiguration.SECURITY_TYPE_WPA2_PSK); + assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_2GHZ); + assertThat(original.getChannel()).isEqualTo(0); + assertThat(original.isHiddenSsid()).isEqualTo(false); + + + SoftApConfiguration unparceled = parcelUnparcel(original); + assertThat(unparceled).isNotSameAs(original); + assertThat(unparceled).isEqualTo(original); + assertThat(unparceled.hashCode()).isEqualTo(original.hashCode()); + + SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build(); + assertThat(copy).isNotSameAs(original); + assertThat(copy).isEqualTo(original); + assertThat(copy.hashCode()).isEqualTo(original.hashCode()); + } + + @Test + public void testWpa2WithBandAndChannelAndHiddenNetwork() { + SoftApConfiguration original = new SoftApConfiguration.Builder() + .setWpa2Passphrase("secretsecret") + .setBand(SoftApConfiguration.BAND_ANY) + .setChannel(149) + .setHiddenSsid(true) + .build(); + assertThat(original.getWpa2Passphrase()).isEqualTo("secretsecret"); + assertThat(original.getSecurityType()).isEqualTo( + SoftApConfiguration.SECURITY_TYPE_WPA2_PSK); + assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_ANY); + assertThat(original.getChannel()).isEqualTo(149); + assertThat(original.isHiddenSsid()).isEqualTo(true); + SoftApConfiguration unparceled = parcelUnparcel(original); assertThat(unparceled).isNotSameAs(original); diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index d326201fa574..ab027b38348e 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -180,6 +180,33 @@ public class WifiManagerTest { assertFalse(mWifiManager.stopSoftAp()); } + /** + * Check the call to startSoftAp calls WifiService to startSoftAp with the provided + * WifiConfiguration. Verify that the return value is propagated to the caller. + */ + @Test + public void testStartTetheredHotspotCallsServiceWithSoftApConfig() throws Exception { + SoftApConfiguration mSoftApConfig = new SoftApConfiguration.Builder().build(); + when(mWifiService.startTetheredHotspot(eq(mSoftApConfig))).thenReturn(true); + assertTrue(mWifiManager.startTetheredHotspot(mSoftApConfig)); + + when(mWifiService.startTetheredHotspot(eq(mSoftApConfig))).thenReturn(false); + assertFalse(mWifiManager.startTetheredHotspot(mSoftApConfig)); + } + + /** + * Check the call to startSoftAp calls WifiService to startSoftAp with a null config. Verify + * that the return value is propagated to the caller. + */ + @Test + public void testStartTetheredHotspotCallsServiceWithNullConfig() throws Exception { + when(mWifiService.startTetheredHotspot(eq(null))).thenReturn(true); + assertTrue(mWifiManager.startTetheredHotspot(null)); + + when(mWifiService.startTetheredHotspot(eq(null))).thenReturn(false); + assertFalse(mWifiManager.startTetheredHotspot(null)); + } + /** * Test creation of a LocalOnlyHotspotReservation and verify that close properly calls * WifiService.stopLocalOnlyHotspot. @@ -1147,6 +1174,43 @@ public class WifiManagerTest { } catch (SecurityException e) { } } + /** + * Verify that a successful call properly returns true. + */ + @Test + public void testSetSoftApConfigurationSuccessReturnsTrue() throws Exception { + SoftApConfiguration apConfig = new SoftApConfiguration.Builder().build(); + + when(mWifiService.setSoftApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME))) + .thenReturn(true); + assertTrue(mWifiManager.setSoftApConfiguration(apConfig)); + } + + /** + * Verify that a failed call properly returns false. + */ + @Test + public void testSetSoftApConfigurationFailureReturnsFalse() throws Exception { + SoftApConfiguration apConfig = new SoftApConfiguration.Builder().build(); + + when(mWifiService.setSoftApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME))) + .thenReturn(false); + assertFalse(mWifiManager.setSoftApConfiguration(apConfig)); + } + + /** + * Verify Exceptions are rethrown when underlying calls to WifiService throw exceptions. + */ + @Test + public void testSetSoftApConfigurationRethrowsException() throws Exception { + doThrow(new SecurityException()).when(mWifiService).setSoftApConfiguration(any(), any()); + + try { + mWifiManager.setSoftApConfiguration(new SoftApConfiguration.Builder().build()); + fail("setWifiApConfiguration should rethrow Exceptions from WifiService"); + } catch (SecurityException e) { } + } + /** * Check the call to startScan calls WifiService. */ -- cgit v1.2.3 From e6efa3fca5648e664aa1c26700b8d76bda0b844b Mon Sep 17 00:00:00 2001 From: David Su Date: Fri, 29 Nov 2019 18:02:30 -0800 Subject: framework-wifi: Stop using @hide isLowRamDeviceStatic Migrate isLowRamDeviceStatic() to isLowRamDevice() Bug: 145409537 Test: atest FrameworksWifiApiTests Change-Id: I4346e5b5b470f0e5ab8c8c2e89f0f8a575aa2b3e --- wifi/java/android/net/wifi/WifiManager.java | 21 ++++++++++++++------- .../tests/src/android/net/wifi/WifiManagerTest.java | 13 +++++++++++-- 2 files changed, 25 insertions(+), 9 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index bf609d765502..376abacbf78c 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -146,12 +146,11 @@ public class WifiManager { @Deprecated public static final int ERROR_AUTH_FAILURE_EAP_FAILURE = 3; - /** - * Maximum number of active network suggestions allowed per app. - * @hide - */ - public static final int NETWORK_SUGGESTIONS_MAX_PER_APP = - ActivityManager.isLowRamDeviceStatic() ? 256 : 1024; + /** @hide */ + public static final int NETWORK_SUGGESTIONS_MAX_PER_APP_LOW_RAM = 256; + + /** @hide */ + public static final int NETWORK_SUGGESTIONS_MAX_PER_APP_HIGH_RAM = 1024; /** * Reason code if all of the network suggestions were successfully added or removed. @@ -1830,7 +1829,15 @@ public class WifiManager { * @see #removeNetworkSuggestions(List) */ public int getMaxNumberOfNetworkSuggestionsPerApp() { - return NETWORK_SUGGESTIONS_MAX_PER_APP; + return getMaxNumberOfNetworkSuggestionsPerApp( + mContext.getSystemService(ActivityManager.class).isLowRamDevice()); + } + + /** @hide */ + public static int getMaxNumberOfNetworkSuggestionsPerApp(boolean isLowRamDevice) { + return isLowRamDevice + ? NETWORK_SUGGESTIONS_MAX_PER_APP_LOW_RAM + : NETWORK_SUGGESTIONS_MAX_PER_APP_HIGH_RAM; } /** diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index d326201fa574..613e5763d700 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -50,6 +50,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; +import android.app.ActivityManager; import android.content.Context; import android.content.pm.ApplicationInfo; import android.net.DhcpInfo; @@ -116,6 +117,7 @@ public class WifiManagerTest { @Mock Runnable mRunnable; @Mock Executor mExecutor; @Mock Executor mAnotherExecutor; + @Mock ActivityManager mActivityManager; private Handler mHandler; private TestLooper mLooper; @@ -1395,8 +1397,15 @@ public class WifiManagerTest { */ @Test public void getMaxNumberOfNetworkSuggestionsPerApp() { - assertEquals(WifiManager.NETWORK_SUGGESTIONS_MAX_PER_APP, - mWifiManager.getMaxNumberOfNetworkSuggestionsPerApp()); + when(mContext.getSystemServiceName(ActivityManager.class)) + .thenReturn(Context.ACTIVITY_SERVICE); + when(mContext.getSystemService(Context.ACTIVITY_SERVICE)) + .thenReturn(mActivityManager); + when(mActivityManager.isLowRamDevice()).thenReturn(true); + assertEquals(256, mWifiManager.getMaxNumberOfNetworkSuggestionsPerApp()); + + when(mActivityManager.isLowRamDevice()).thenReturn(false); + assertEquals(1024, mWifiManager.getMaxNumberOfNetworkSuggestionsPerApp()); } /** -- cgit v1.2.3 From c244b81bb508bcd1f15108633b921a60cab0b07e Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Mon, 18 Nov 2019 09:19:39 -0800 Subject: make ACTION_NETWORK_SETTINGS_RESET to be system API bug: 138145656 Test: manual test - reset wifi settings Change-Id: I4ea5a7235411d769d27738d244c3ba63776151b6 --- wifi/java/android/net/wifi/WifiManager.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index e2e6728068a9..56817a863b4f 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -724,7 +724,9 @@ public class WifiManager { * had been reset. * @hide */ - public static final String WIFI_NETWORK_SETTINGS_RESET_ACTION = + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_CARRIER_PROVISIONING) + public static final String ACTION_NETWORK_SETTINGS_RESET = "android.net.wifi.action.NETWORK_SETTINGS_RESET"; /** -- cgit v1.2.3 From 308e25e5fb017f6d6173366c4badcc302383c07f Mon Sep 17 00:00:00 2001 From: David Su Date: Fri, 29 Nov 2019 00:27:46 -0800 Subject: Formalize WifiManager#requestActivityInfo as @SystemApi Rename WifiManager#requestActivityInfo to getWifiActivityEnergyInfoAsync and convert ResultReceiver to a formal listener interface. Bug: 145244073 Test: atest FrameworksWifiApiTests Change-Id: I7f343c07b63c191082443bd8296a5569fb1c0d49 --- .../wifi/IOnWifiActivityEnergyInfoListener.aidl | 33 +++++ wifi/java/android/net/wifi/IWifiManager.aidl | 11 +- wifi/java/android/net/wifi/WifiManager.java | 76 +++++++++++ .../com/android/server/wifi/BaseWifiService.java | 7 +- .../src/android/net/wifi/WifiManagerTest.java | 143 +++++++++++++++------ 5 files changed, 225 insertions(+), 45 deletions(-) create mode 100644 wifi/java/android/net/wifi/IOnWifiActivityEnergyInfoListener.aidl (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IOnWifiActivityEnergyInfoListener.aidl b/wifi/java/android/net/wifi/IOnWifiActivityEnergyInfoListener.aidl new file mode 100644 index 000000000000..5460b74a91d1 --- /dev/null +++ b/wifi/java/android/net/wifi/IOnWifiActivityEnergyInfoListener.aidl @@ -0,0 +1,33 @@ +/* + * 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.WifiActivityEnergyInfo; + +/** + * Interface for Wi-Fi activity energy info listener. + * + * @hide + */ +oneway interface IOnWifiActivityEnergyInfoListener +{ + /** + * Service to manager callback providing current Wi-Fi activity energy info. + * @param info the Wi-Fi activity energy info + */ + void onWifiActivityEnergyInfo(in WifiActivityEnergyInfo info); +} diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 032f66af2433..77dffc67b265 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -28,12 +28,13 @@ import android.net.wifi.IActionListener; import android.net.wifi.IDppCallback; import android.net.wifi.ILocalOnlyHotspotCallback; import android.net.wifi.INetworkRequestMatchCallback; +import android.net.wifi.IOnWifiActivityEnergyInfoListener; +import android.net.wifi.IOnWifiUsabilityStatsListener; import android.net.wifi.IScanResultsCallback; import android.net.wifi.ISoftApCallback; import android.net.wifi.ISuggestionConnectionStatusListener; import android.net.wifi.ITrafficStateCallback; import android.net.wifi.ITxPacketCountListener; -import android.net.wifi.IOnWifiUsabilityStatsListener; import android.net.wifi.ScanResult; import android.net.wifi.SoftApConfiguration; import android.net.wifi.WifiActivityEnergyInfo; @@ -56,13 +57,7 @@ interface IWifiManager WifiActivityEnergyInfo reportActivityInfo(); - /** - * Requests the controller activity info asynchronously. - * The implementor is expected to reply with the - * {@link android.net.wifi.WifiActivityEnergyInfo} object placed into the Bundle with the key - * {@link android.os.BatteryStats#RESULT_RECEIVER_CONTROLLER_KEY}. The result code is ignored. - */ - oneway void requestActivityInfo(in ResultReceiver result); + oneway void getWifiActivityEnergyInfoAsync(in IOnWifiActivityEnergyInfoListener listener); ParceledListSlice getConfiguredNetworks(String packageName, String featureId); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 83bba27e48a2..63d11e6bbc46 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -2388,6 +2388,82 @@ public class WifiManager { } } + /** + * Interface for Wi-Fi activity energy info listener. Should be implemented by applications and + * set when calling {@link WifiManager#getWifiActivityEnergyInfoAsync}. + * + * @hide + */ + @SystemApi + public interface OnWifiActivityEnergyInfoListener { + /** + * Called when Wi-Fi activity energy info is available. + * Note: this listener is triggered at most once for each call to + * {@link #getWifiActivityEnergyInfoAsync}. + * + * @param info the latest {@link WifiActivityEnergyInfo}, or null if unavailable. + */ + void onWifiActivityEnergyInfo(@Nullable WifiActivityEnergyInfo info); + } + + private static class OnWifiActivityEnergyInfoProxy + extends IOnWifiActivityEnergyInfoListener.Stub { + private final Object mLock = new Object(); + @Nullable @GuardedBy("mLock") private Executor mExecutor; + @Nullable @GuardedBy("mLock") private OnWifiActivityEnergyInfoListener mListener; + + OnWifiActivityEnergyInfoProxy(Executor executor, + OnWifiActivityEnergyInfoListener listener) { + mExecutor = executor; + mListener = listener; + } + + @Override + public void onWifiActivityEnergyInfo(WifiActivityEnergyInfo info) { + Executor executor; + OnWifiActivityEnergyInfoListener listener; + synchronized (mLock) { + if (mExecutor == null || mListener == null) { + return; + } + executor = mExecutor; + listener = mListener; + // null out to allow garbage collection, prevent triggering listener more than once + mExecutor = null; + mListener = null; + } + Binder.clearCallingIdentity(); + executor.execute(() -> listener.onWifiActivityEnergyInfo(info)); + } + } + + /** + * Request to get the current {@link WifiActivityEnergyInfo} asynchronously. + * Note: This method will return null if {@link #isEnhancedPowerReportingSupported()} returns + * false. + * + * @param executor the executor that the listener will be invoked on + * @param listener the listener that will receive the {@link WifiActivityEnergyInfo} object + * when it becomes available. The listener will be triggered at most once for + * each call to this method. + * + * @hide + */ + @SystemApi + @RequiresPermission(ACCESS_WIFI_STATE) + public void getWifiActivityEnergyInfoAsync( + @NonNull @CallbackExecutor Executor executor, + @NonNull OnWifiActivityEnergyInfoListener listener) { + if (executor == null) throw new IllegalArgumentException("executor cannot be null"); + if (listener == null) throw new IllegalArgumentException("listener cannot be null"); + try { + mService.getWifiActivityEnergyInfoAsync( + new OnWifiActivityEnergyInfoProxy(executor, listener)); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Request a scan for access points. Returns immediately. The availability * of the results is made known later by means of an asynchronous event sent diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index bc8683921321..5f1191e0d8ab 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -25,6 +25,7 @@ import android.net.wifi.IActionListener; import android.net.wifi.IDppCallback; import android.net.wifi.ILocalOnlyHotspotCallback; import android.net.wifi.INetworkRequestMatchCallback; +import android.net.wifi.IOnWifiActivityEnergyInfoListener; import android.net.wifi.IOnWifiUsabilityStatsListener; import android.net.wifi.IScanResultsCallback; import android.net.wifi.IScanResultsListener; @@ -80,11 +81,15 @@ public class BaseWifiService extends IWifiManager.Stub { throw new UnsupportedOperationException(); } - @Override public void requestActivityInfo(ResultReceiver result) { throw new UnsupportedOperationException(); } + @Override + public void getWifiActivityEnergyInfoAsync(IOnWifiActivityEnergyInfoListener listener) { + throw new UnsupportedOperationException(); + } + @Override public ParceledListSlice getConfiguredNetworks(String packageName, String featureId) { throw new UnsupportedOperationException(); diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index b3a73bc3ea91..aa0363461852 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -16,15 +16,31 @@ package android.net.wifi; +import static android.net.wifi.WifiManager.ActionListener; +import static android.net.wifi.WifiManager.BUSY; +import static android.net.wifi.WifiManager.ERROR; import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_GENERIC; import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE; import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_NO_CHANNEL; import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_TETHERING_DISALLOWED; import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.REQUEST_REGISTERED; +import static android.net.wifi.WifiManager.NOT_AUTHORIZED; +import static android.net.wifi.WifiManager.OnWifiActivityEnergyInfoListener; import static android.net.wifi.WifiManager.SAP_START_FAILURE_GENERAL; +import static android.net.wifi.WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS; +import static android.net.wifi.WifiManager.STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION; +import static android.net.wifi.WifiManager.TxPacketCountListener; import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED; import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLING; import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED; +import static android.net.wifi.WifiManager.WIFI_FEATURE_DPP; +import static android.net.wifi.WifiManager.WIFI_FEATURE_OWE; +import static android.net.wifi.WifiManager.WIFI_FEATURE_P2P; +import static android.net.wifi.WifiManager.WIFI_FEATURE_PASSPOINT; +import static android.net.wifi.WifiManager.WIFI_FEATURE_SCANNER; +import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SAE; +import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SUITE_B; +import static android.net.wifi.WifiManager.WpsCallback; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -113,6 +129,7 @@ public class WifiManagerTest { @Mock TrafficStateCallback mTrafficStateCallback; @Mock NetworkRequestMatchCallback mNetworkRequestMatchCallback; @Mock OnWifiUsabilityStatsListener mOnWifiUsabilityStatsListener; + @Mock OnWifiActivityEnergyInfoListener mOnWifiActivityEnergyInfoListener; @Mock SuggestionConnectionStatusListener mListener; @Mock Runnable mRunnable; @Mock Executor mExecutor; @@ -124,6 +141,7 @@ public class WifiManagerTest { private WifiManager mWifiManager; private WifiNetworkSuggestion mWifiNetworkSuggestion; private ScanResultsCallback mScanResultsCallback; + private WifiActivityEnergyInfo mWifiActivityEnergyInfo; @Before public void setUp() throws Exception { @@ -142,6 +160,7 @@ public class WifiManagerTest { mRunnable.run(); } }; + mWifiActivityEnergyInfo = new WifiActivityEnergyInfo(0, 0, 0, 0, 0, 0, 0); } /** @@ -1069,7 +1088,7 @@ public class WifiManagerTest { } - class WpsCallbackTester extends WifiManager.WpsCallback { + class WpsCallbackTester extends WpsCallback { public boolean mStarted = false; public boolean mSucceeded = false; public boolean mFailed = false; @@ -1101,7 +1120,7 @@ public class WifiManagerTest { WpsCallbackTester wpsCallback = new WpsCallbackTester(); mWifiManager.startWps(null, wpsCallback); assertTrue(wpsCallback.mFailed); - assertEquals(WifiManager.ERROR, wpsCallback.mFailureCode); + assertEquals(ERROR, wpsCallback.mFailureCode); assertFalse(wpsCallback.mStarted); assertFalse(wpsCallback.mSucceeded); verifyNoMoreInteractions(mWifiService); @@ -1124,7 +1143,7 @@ public class WifiManagerTest { WpsCallbackTester wpsCallback = new WpsCallbackTester(); mWifiManager.cancelWps(wpsCallback); assertTrue(wpsCallback.mFailed); - assertEquals(WifiManager.ERROR, wpsCallback.mFailureCode); + assertEquals(ERROR, wpsCallback.mFailureCode); assertFalse(wpsCallback.mStarted); assertFalse(wpsCallback.mSucceeded); verifyNoMoreInteractions(mWifiService); @@ -1437,13 +1456,13 @@ public class WifiManagerTest { public void addGetRemoveNetworkSuggestions() throws Exception { List testList = new ArrayList<>(); when(mWifiService.addNetworkSuggestions(any(List.class), anyString(), - nullable(String.class))).thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS); + nullable(String.class))).thenReturn(STATUS_NETWORK_SUGGESTIONS_SUCCESS); when(mWifiService.removeNetworkSuggestions(any(List.class), anyString())).thenReturn( - WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS); + STATUS_NETWORK_SUGGESTIONS_SUCCESS); when(mWifiService.getNetworkSuggestions(anyString())) .thenReturn(testList); - assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS, + assertEquals(STATUS_NETWORK_SUGGESTIONS_SUCCESS, mWifiManager.addNetworkSuggestions(testList)); verify(mWifiService).addNetworkSuggestions(anyList(), eq(TEST_PACKAGE_NAME), nullable(String.class)); @@ -1451,7 +1470,7 @@ public class WifiManagerTest { assertEquals(testList, mWifiManager.getNetworkSuggestions()); verify(mWifiService).getNetworkSuggestions(eq(TEST_PACKAGE_NAME)); - assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS, + assertEquals(STATUS_NETWORK_SUGGESTIONS_SUCCESS, mWifiManager.removeNetworkSuggestions(new ArrayList<>())); verify(mWifiService).removeNetworkSuggestions(anyList(), eq(TEST_PACKAGE_NAME)); } @@ -1515,10 +1534,10 @@ public class WifiManagerTest { @Test public void testIsEnhancedOpenSupported() throws Exception { when(mWifiService.getSupportedFeatures()) - .thenReturn(new Long(WifiManager.WIFI_FEATURE_OWE)); + .thenReturn(new Long(WIFI_FEATURE_OWE)); assertTrue(mWifiManager.isEnhancedOpenSupported()); when(mWifiService.getSupportedFeatures()) - .thenReturn(new Long(~WifiManager.WIFI_FEATURE_OWE)); + .thenReturn(new Long(~WIFI_FEATURE_OWE)); assertFalse(mWifiManager.isEnhancedOpenSupported()); } @@ -1528,10 +1547,10 @@ public class WifiManagerTest { @Test public void testIsWpa3SaeSupported() throws Exception { when(mWifiService.getSupportedFeatures()) - .thenReturn(new Long(WifiManager.WIFI_FEATURE_WPA3_SAE)); + .thenReturn(new Long(WIFI_FEATURE_WPA3_SAE)); assertTrue(mWifiManager.isWpa3SaeSupported()); when(mWifiService.getSupportedFeatures()) - .thenReturn(new Long(~WifiManager.WIFI_FEATURE_WPA3_SAE)); + .thenReturn(new Long(~WIFI_FEATURE_WPA3_SAE)); assertFalse(mWifiManager.isWpa3SaeSupported()); } @@ -1541,10 +1560,10 @@ public class WifiManagerTest { @Test public void testIsWpa3SuiteBSupported() throws Exception { when(mWifiService.getSupportedFeatures()) - .thenReturn(new Long(WifiManager.WIFI_FEATURE_WPA3_SUITE_B)); + .thenReturn(new Long(WIFI_FEATURE_WPA3_SUITE_B)); assertTrue(mWifiManager.isWpa3SuiteBSupported()); when(mWifiService.getSupportedFeatures()) - .thenReturn(new Long(~WifiManager.WIFI_FEATURE_WPA3_SUITE_B)); + .thenReturn(new Long(~WIFI_FEATURE_WPA3_SUITE_B)); assertFalse(mWifiManager.isWpa3SuiteBSupported()); } @@ -1554,10 +1573,10 @@ public class WifiManagerTest { @Test public void testIsEasyConnectSupported() throws Exception { when(mWifiService.getSupportedFeatures()) - .thenReturn(new Long(WifiManager.WIFI_FEATURE_DPP)); + .thenReturn(new Long(WIFI_FEATURE_DPP)); assertTrue(mWifiManager.isEasyConnectSupported()); when(mWifiService.getSupportedFeatures()) - .thenReturn(new Long(~WifiManager.WIFI_FEATURE_DPP)); + .thenReturn(new Long(~WIFI_FEATURE_DPP)); assertFalse(mWifiManager.isEasyConnectSupported()); } @@ -1666,9 +1685,9 @@ public class WifiManagerTest { @Test public void testGetSupportedFeatures() throws Exception { long supportedFeatures = - WifiManager.WIFI_FEATURE_SCANNER - | WifiManager.WIFI_FEATURE_PASSPOINT - | WifiManager.WIFI_FEATURE_P2P; + WIFI_FEATURE_SCANNER + | WIFI_FEATURE_PASSPOINT + | WIFI_FEATURE_P2P; when(mWifiService.getSupportedFeatures()) .thenReturn(Long.valueOf(supportedFeatures)); @@ -1699,6 +1718,58 @@ public class WifiManagerTest { assertEquals(activityEnergyInfo, mWifiManager.getControllerActivityEnergyInfo()); } + /** + * Tests that passing a null Executor to {@link WifiManager#getWifiActivityEnergyInfoAsync} + * throws an exception. + */ + @Test(expected = IllegalArgumentException.class) + public void testGetWifiActivityInfoNullExecutor() throws Exception { + mWifiManager.getWifiActivityEnergyInfoAsync(null, mOnWifiActivityEnergyInfoListener); + } + + /** + * Tests that passing a null listener to {@link WifiManager#getWifiActivityEnergyInfoAsync} + * throws an exception. + */ + @Test(expected = IllegalArgumentException.class) + public void testGetWifiActivityInfoNullListener() throws Exception { + mWifiManager.getWifiActivityEnergyInfoAsync(mExecutor, null); + } + + /** Tests that the listener runs on the correct Executor. */ + @Test + public void testGetWifiActivityInfoRunsOnCorrectExecutor() throws Exception { + mWifiManager.getWifiActivityEnergyInfoAsync(mExecutor, mOnWifiActivityEnergyInfoListener); + ArgumentCaptor listenerCaptor = + ArgumentCaptor.forClass(IOnWifiActivityEnergyInfoListener.class); + verify(mWifiService).getWifiActivityEnergyInfoAsync(listenerCaptor.capture()); + IOnWifiActivityEnergyInfoListener listener = listenerCaptor.getValue(); + listener.onWifiActivityEnergyInfo(mWifiActivityEnergyInfo); + verify(mExecutor).execute(any()); + + // ensure that the executor is only triggered once + listener.onWifiActivityEnergyInfo(mWifiActivityEnergyInfo); + verify(mExecutor).execute(any()); + } + + /** Tests that the correct listener runs. */ + @Test + public void testGetWifiActivityInfoRunsCorrectListener() throws Exception { + int[] flag = {0}; + mWifiManager.getWifiActivityEnergyInfoAsync( + new SynchronousExecutor(), info -> flag[0]++); + ArgumentCaptor listenerCaptor = + ArgumentCaptor.forClass(IOnWifiActivityEnergyInfoListener.class); + verify(mWifiService).getWifiActivityEnergyInfoAsync(listenerCaptor.capture()); + IOnWifiActivityEnergyInfoListener listener = listenerCaptor.getValue(); + listener.onWifiActivityEnergyInfo(mWifiActivityEnergyInfo); + assertEquals(1, flag[0]); + + // ensure that the listener is only triggered once + listener.onWifiActivityEnergyInfo(mWifiActivityEnergyInfo); + assertEquals(1, flag[0]); + } + /** * Test behavior of {@link WifiManager#getConnectionInfo()} */ @@ -1756,11 +1827,11 @@ public class WifiManagerTest { } /** - * Test behavior of {@link WifiManager#connect(int, WifiManager.ActionListener)} + * Test behavior of {@link WifiManager#connect(int, ActionListener)} */ @Test public void testConnectWithListener() throws Exception { - WifiManager.ActionListener externalListener = mock(WifiManager.ActionListener.class); + ActionListener externalListener = mock(ActionListener.class); mWifiManager.connect(TEST_NETWORK_ID, externalListener); ArgumentCaptor binderListenerCaptor = @@ -1775,43 +1846,43 @@ public class WifiManagerTest { verify(externalListener).onSuccess(); // Trigger on failure. - binderListenerCaptor.getValue().onFailure(WifiManager.BUSY); + binderListenerCaptor.getValue().onFailure(BUSY); mLooper.dispatchAll(); - verify(externalListener).onFailure(WifiManager.BUSY); + verify(externalListener).onFailure(BUSY); } /** - * Test behavior of {@link WifiManager#connect(int, WifiManager.ActionListener)} + * Test behavior of {@link WifiManager#connect(int, ActionListener)} */ @Test public void testConnectWithListenerHandleSecurityException() throws Exception { doThrow(new SecurityException()).when(mWifiService) .connect(eq(null), anyInt(), any(IBinder.class), any(IActionListener.class), anyInt()); - WifiManager.ActionListener externalListener = mock(WifiManager.ActionListener.class); + ActionListener externalListener = mock(ActionListener.class); mWifiManager.connect(TEST_NETWORK_ID, externalListener); mLooper.dispatchAll(); - verify(externalListener).onFailure(WifiManager.NOT_AUTHORIZED); + verify(externalListener).onFailure(NOT_AUTHORIZED); } /** - * Test behavior of {@link WifiManager#connect(int, WifiManager.ActionListener)} + * Test behavior of {@link WifiManager#connect(int, ActionListener)} */ @Test public void testConnectWithListenerHandleRemoteException() throws Exception { doThrow(new RemoteException()).when(mWifiService) .connect(eq(null), anyInt(), any(IBinder.class), any(IActionListener.class), anyInt()); - WifiManager.ActionListener externalListener = mock(WifiManager.ActionListener.class); + ActionListener externalListener = mock(ActionListener.class); mWifiManager.connect(TEST_NETWORK_ID, externalListener); mLooper.dispatchAll(); - verify(externalListener).onFailure(WifiManager.ERROR); + verify(externalListener).onFailure(ERROR); } /** - * Test behavior of {@link WifiManager#connect(int, WifiManager.ActionListener)} + * Test behavior of {@link WifiManager#connect(int, ActionListener)} */ @Test public void testConnectWithoutListener() throws Exception { @@ -1823,12 +1894,12 @@ public class WifiManagerTest { } /** - * Test behavior of {@link WifiManager#getTxPacketCount(WifiManager.TxPacketCountListener)} + * Test behavior of {@link WifiManager#getTxPacketCount(TxPacketCountListener)} */ @Test public void testGetTxPacketCount() throws Exception { - WifiManager.TxPacketCountListener externalListener = - mock(WifiManager.TxPacketCountListener.class); + TxPacketCountListener externalListener = + mock(TxPacketCountListener.class); mWifiManager.getTxPacketCount(externalListener); ArgumentCaptor binderListenerCaptor = @@ -1843,9 +1914,9 @@ public class WifiManagerTest { verify(externalListener).onSuccess(6); // Trigger on failure. - binderListenerCaptor.getValue().onFailure(WifiManager.BUSY); + binderListenerCaptor.getValue().onFailure(BUSY); mLooper.dispatchAll(); - verify(externalListener).onFailure(WifiManager.BUSY); + verify(externalListener).onFailure(BUSY); } /** @@ -1947,7 +2018,7 @@ public class WifiManagerTest { */ @Test public void testAddSuggestionConnectionStatusListenerAndReceiveEvent() throws Exception { - int errorCode = WifiManager.STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION; + int errorCode = STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION; ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(ISuggestionConnectionStatusListener.Stub.class); Executor executor = new SynchronousExecutor(); @@ -1963,7 +2034,7 @@ public class WifiManagerTest { */ @Test public void testAddSuggestionConnectionStatusListenerWithTheTargetExecutor() throws Exception { - int errorCode = WifiManager.STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION; + int errorCode = STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION; ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(ISuggestionConnectionStatusListener.Stub.class); mWifiManager.addSuggestionConnectionStatusListener(mExecutor, mListener); -- cgit v1.2.3 From 6f0e41683ad69b938820cb3dca1b63e7064f3e6b Mon Sep 17 00:00:00 2001 From: David Su Date: Mon, 2 Dec 2019 21:53:33 -0800 Subject: Move WifiActivityEnergyInfo to android.os.connectivity Move WifiActivityEnergyInfo out of the Wifi Mainline module so that it can use @hide PowerProfile. Bug: 145244073 Test: atest FrameworksWifiApiTests Change-Id: I168c3e187f391ac31660034e7873c8438c1096b3 --- .../wifi/IOnWifiActivityEnergyInfoListener.aidl | 2 +- wifi/java/android/net/wifi/IWifiManager.aidl | 2 +- .../android/net/wifi/WifiActivityEnergyInfo.aidl | 19 -- .../android/net/wifi/WifiActivityEnergyInfo.java | 227 --------------------- wifi/java/android/net/wifi/WifiManager.java | 1 + .../com/android/server/wifi/BaseWifiService.java | 2 +- .../src/android/net/wifi/WifiManagerTest.java | 1 + 7 files changed, 5 insertions(+), 249 deletions(-) delete mode 100644 wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl delete mode 100644 wifi/java/android/net/wifi/WifiActivityEnergyInfo.java (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IOnWifiActivityEnergyInfoListener.aidl b/wifi/java/android/net/wifi/IOnWifiActivityEnergyInfoListener.aidl index 5460b74a91d1..7e25fd8a3be2 100644 --- a/wifi/java/android/net/wifi/IOnWifiActivityEnergyInfoListener.aidl +++ b/wifi/java/android/net/wifi/IOnWifiActivityEnergyInfoListener.aidl @@ -16,7 +16,7 @@ package android.net.wifi; -import android.net.wifi.WifiActivityEnergyInfo; +import android.os.connectivity.WifiActivityEnergyInfo; /** * Interface for Wi-Fi activity energy info listener. diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 77dffc67b265..fccbcf7c101f 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -37,7 +37,6 @@ import android.net.wifi.ITrafficStateCallback; import android.net.wifi.ITxPacketCountListener; import android.net.wifi.ScanResult; import android.net.wifi.SoftApConfiguration; -import android.net.wifi.WifiActivityEnergyInfo; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiNetworkSuggestion; @@ -45,6 +44,7 @@ import android.net.wifi.WifiNetworkSuggestion; import android.os.Messenger; import android.os.ResultReceiver; import android.os.WorkSource; +import android.os.connectivity.WifiActivityEnergyInfo; /** * Interface that allows controlling and querying Wi-Fi connectivity. diff --git a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl b/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl deleted file mode 100644 index 007ec94378fd..000000000000 --- a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2014, 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; - -parcelable WifiActivityEnergyInfo; diff --git a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.java b/wifi/java/android/net/wifi/WifiActivityEnergyInfo.java deleted file mode 100644 index f0f31fae0aeb..000000000000 --- a/wifi/java/android/net/wifi/WifiActivityEnergyInfo.java +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (C) 2014 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.annotation.IntDef; -import android.annotation.NonNull; -import android.annotation.SystemApi; -import android.os.Parcel; -import android.os.Parcelable; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * Record of energy and activity information from controller and - * underlying wifi stack state. Timestamp the record with elapsed - * real-time. - * @hide - */ -@SystemApi -public final class WifiActivityEnergyInfo implements Parcelable { - private long mTimeSinceBootMillis; - @StackState - private int mStackState; - private long mControllerTxDurationMillis; - private long mControllerRxDurationMillis; - private long mControllerScanDurationMillis; - private long mControllerIdleDurationMillis; - private long mControllerEnergyUsedMicroJoules; - - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = {"STACK_STATE_"}, value = { - STACK_STATE_INVALID, - STACK_STATE_STATE_ACTIVE, - STACK_STATE_STATE_SCANNING, - STACK_STATE_STATE_IDLE}) - public @interface StackState {} - - /** Invalid Wifi stack state. */ - public static final int STACK_STATE_INVALID = 0; - /** Wifi stack is active. */ - public static final int STACK_STATE_STATE_ACTIVE = 1; - /** Wifi stack is scanning. */ - public static final int STACK_STATE_STATE_SCANNING = 2; - /** Wifi stack is idle. */ - public static final int STACK_STATE_STATE_IDLE = 3; - - /** - * Constructor. - * - * @param timeSinceBootMillis the time since boot, in milliseconds. - * @param stackState The current state of the Wifi Stack. One of {@link #STACK_STATE_INVALID}, - * {@link #STACK_STATE_STATE_ACTIVE}, {@link #STACK_STATE_STATE_SCANNING}, - * or {@link #STACK_STATE_STATE_IDLE}. - * @param txDurationMillis Cumulative milliseconds of active transmission. - * @param rxDurationMillis Cumulative milliseconds of active receive. - * @param scanDurationMillis Cumulative milliseconds when radio is awake due to scan. - * @param idleDurationMillis Cumulative milliseconds when radio is awake but not transmitting or - * receiving. - * @param energyUsedMicroJoules Cumulative energy consumed by Wifi, in microjoules. - */ - public WifiActivityEnergyInfo( - long timeSinceBootMillis, - @StackState int stackState, - long txDurationMillis, - long rxDurationMillis, - long scanDurationMillis, - long idleDurationMillis, - long energyUsedMicroJoules) { - mTimeSinceBootMillis = timeSinceBootMillis; - mStackState = stackState; - mControllerTxDurationMillis = txDurationMillis; - mControllerRxDurationMillis = rxDurationMillis; - mControllerScanDurationMillis = scanDurationMillis; - mControllerIdleDurationMillis = idleDurationMillis; - mControllerEnergyUsedMicroJoules = energyUsedMicroJoules; - } - - @Override - public String toString() { - return "WifiActivityEnergyInfo{" - + " mTimeSinceBootMillis=" + mTimeSinceBootMillis - + " mStackState=" + mStackState - + " mControllerTxDurationMillis=" + mControllerTxDurationMillis - + " mControllerRxDurationMillis=" + mControllerRxDurationMillis - + " mControllerScanDurationMillis=" + mControllerScanDurationMillis - + " mControllerIdleDurationMillis=" + mControllerIdleDurationMillis - + " mControllerEnergyUsedMicroJoules=" + mControllerEnergyUsedMicroJoules - + " }"; - } - - public static final @NonNull Parcelable.Creator CREATOR = - new Parcelable.Creator() { - public WifiActivityEnergyInfo createFromParcel(Parcel in) { - long timestamp = in.readLong(); - int stackState = in.readInt(); - long txTime = in.readLong(); - long rxTime = in.readLong(); - long scanTime = in.readLong(); - long idleTime = in.readLong(); - long energyUsed = in.readLong(); - return new WifiActivityEnergyInfo(timestamp, stackState, - txTime, rxTime, scanTime, idleTime, energyUsed); - } - public WifiActivityEnergyInfo[] newArray(int size) { - return new WifiActivityEnergyInfo[size]; - } - }; - - @Override - public void writeToParcel(@NonNull Parcel out, int flags) { - out.writeLong(mTimeSinceBootMillis); - out.writeInt(mStackState); - out.writeLong(mControllerTxDurationMillis); - out.writeLong(mControllerRxDurationMillis); - out.writeLong(mControllerScanDurationMillis); - out.writeLong(mControllerIdleDurationMillis); - out.writeLong(mControllerEnergyUsedMicroJoules); - } - - @Override - public int describeContents() { - return 0; - } - - /** Get the timestamp (milliseconds since boot) of record creation. */ - public long getTimeSinceBootMillis() { - return mTimeSinceBootMillis; - } - - /** Set the timestamp (milliseconds since boot) of record creation. */ - public void setTimeSinceBootMillis(long timeSinceBootMillis) { - mTimeSinceBootMillis = timeSinceBootMillis; - } - - /** - * Get the Wifi stack reported state. One of {@link #STACK_STATE_INVALID}, - * {@link #STACK_STATE_STATE_ACTIVE}, {@link #STACK_STATE_STATE_SCANNING}, - * {@link #STACK_STATE_STATE_IDLE}. - */ - @StackState - public int getStackState() { - return mStackState; - } - - /** - * Set the Wifi stack reported state. One of {@link #STACK_STATE_INVALID}, - * {@link #STACK_STATE_STATE_ACTIVE}, {@link #STACK_STATE_STATE_SCANNING}, - * {@link #STACK_STATE_STATE_IDLE}. - */ - public void setStackState(@StackState int stackState) { - mStackState = stackState; - } - - /** Get the Wifi transmission duration, in milliseconds. */ - public long getControllerTxDurationMillis() { - return mControllerTxDurationMillis; - } - - /** Set the Wifi transmission duration, in milliseconds. */ - public void setControllerTxDurationMillis(long controllerTxDurationMillis) { - mControllerTxDurationMillis = controllerTxDurationMillis; - } - - /** Get the Wifi receive duration, in milliseconds. */ - public long getControllerRxDurationMillis() { - return mControllerRxDurationMillis; - } - - /** Set the Wifi receive duration, in milliseconds. */ - public void setControllerRxDurationMillis(long controllerRxDurationMillis) { - mControllerRxDurationMillis = controllerRxDurationMillis; - } - - /** Get the Wifi scan duration, in milliseconds. */ - public long getControllerScanDurationMillis() { - return mControllerScanDurationMillis; - } - - /** Set the Wifi scan duration, in milliseconds. */ - public void setControllerScanDurationMillis(long controllerScanDurationMillis) { - mControllerScanDurationMillis = controllerScanDurationMillis; - } - - /** Get the Wifi idle duration, in milliseconds. */ - public long getControllerIdleDurationMillis() { - return mControllerIdleDurationMillis; - } - - /** Set the Wifi idle duration, in milliseconds. */ - public void setControllerIdleDurationMillis(long controllerIdleDurationMillis) { - mControllerIdleDurationMillis = controllerIdleDurationMillis; - } - - /** Get the energy consumed by Wifi, in microjoules. */ - public long getControllerEnergyUsedMicroJoules() { - return mControllerEnergyUsedMicroJoules; - } - - /** Set the energy consumed by Wifi, in microjoules. */ - public void setControllerEnergyUsedMicroJoules(long controllerEnergyUsedMicroJoules) { - mControllerEnergyUsedMicroJoules = controllerEnergyUsedMicroJoules; - } - - /** Returns true if the record is valid, false otherwise. */ - public boolean isValid() { - return mControllerTxDurationMillis >= 0 - && mControllerRxDurationMillis >= 0 - && mControllerScanDurationMillis >= 0 - && mControllerIdleDurationMillis >= 0; - } -} diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 63d11e6bbc46..9de15064207f 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -48,6 +48,7 @@ import android.os.IBinder; import android.os.Looper; import android.os.RemoteException; import android.os.WorkSource; +import android.os.connectivity.WifiActivityEnergyInfo; import android.text.TextUtils; import android.util.Log; import android.util.Pair; diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index 5f1191e0d8ab..367cfa069e74 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -36,7 +36,6 @@ import android.net.wifi.ITxPacketCountListener; import android.net.wifi.IWifiManager; import android.net.wifi.ScanResult; import android.net.wifi.SoftApConfiguration; -import android.net.wifi.WifiActivityEnergyInfo; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiNetworkSuggestion; @@ -47,6 +46,7 @@ import android.os.IBinder; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.WorkSource; +import android.os.connectivity.WifiActivityEnergyInfo; import java.util.List; import java.util.Map; diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index aa0363461852..de4514997b1c 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -87,6 +87,7 @@ import android.os.Handler; import android.os.HandlerExecutor; import android.os.IBinder; import android.os.RemoteException; +import android.os.connectivity.WifiActivityEnergyInfo; import android.os.test.TestLooper; import androidx.test.filters.SmallTest; -- cgit v1.2.3 From 7abff1d6fe31954c514207836a83f04fdfeec9c8 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Tue, 3 Dec 2019 11:36:41 -0800 Subject: WifiNetworkScoreCache: Use @hide INetworkScoreCache This version of WifiNetworkScoreCache extends the @hide AIDL callback. This will not be a part of the mainline module and will be used by settings/setupwizard. Bug: 144487252 Test: Compiles Test: Device boots up & connects to wifi networks. Change-Id: I3bf1525642329d4cc55830985ab5fb89ff651912 --- wifi/java/android/net/wifi/WifiNetworkScoreCache.java | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiNetworkScoreCache.java b/wifi/java/android/net/wifi/WifiNetworkScoreCache.java index 5a212a824452..be37c229dd14 100755 --- a/wifi/java/android/net/wifi/WifiNetworkScoreCache.java +++ b/wifi/java/android/net/wifi/WifiNetworkScoreCache.java @@ -22,7 +22,6 @@ import android.annotation.Nullable; import android.content.Context; import android.net.INetworkScoreCache; import android.net.NetworkKey; -import android.net.NetworkScoreManager; import android.net.ScoredNetwork; import android.os.Handler; import android.os.Process; @@ -39,10 +38,10 @@ import java.util.List; /** * {@link INetworkScoreCache} implementation for Wifi Networks. * + * TODO: This should not be part of wifi mainline module. * @hide */ -public class WifiNetworkScoreCache extends INetworkScoreCache.Stub - implements NetworkScoreManager.NetworkScoreCallback { +public class WifiNetworkScoreCache extends INetworkScoreCache.Stub { private static final String TAG = "WifiNetworkScoreCache"; private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG); @@ -248,17 +247,6 @@ public class WifiNetworkScoreCache extends INetworkScoreCache.Stub } @Override protected final void dump(FileDescriptor fd, PrintWriter writer, String[] args) { - WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); - dumpWithLatestScanResults(fd, writer, args, wifiManager.getScanResults()); - } - - /** - * This is directly invoked from within Wifi-Service (on it's instance of this class), hence - * avoid making the WifiManager.getScanResults() call to avoid a deadlock. - */ - public final void dumpWithLatestScanResults( - FileDescriptor fd, PrintWriter writer, String[] args, - List latestScanResults) { mContext.enforceCallingOrSelfPermission(permission.DUMP, TAG); String header = String.format("WifiNetworkScoreCache (%s/%d)", mContext.getPackageName(), Process.myUid()); @@ -269,7 +257,8 @@ public class WifiNetworkScoreCache extends INetworkScoreCache.Stub writer.println(" " + score); } writer.println(" Network scores for latest ScanResults:"); - for (ScanResult scanResult : latestScanResults) { + WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); + for (ScanResult scanResult : wifiManager.getScanResults()) { writer.println( " " + buildNetworkKey(scanResult) + ": " + getNetworkScore(scanResult)); } -- cgit v1.2.3 From 4351857f97c6afad417acbb79ec28b6a8a0cc07e Mon Sep 17 00:00:00 2001 From: David Su Date: Wed, 4 Dec 2019 11:35:50 -0800 Subject: Remove references to @hide MacAddress.ALL_ZEROS_ADDRESS Migrate to WifiManager.ALL_ZEROS_MAC_ADDRESS. Bug: 145409537 Test: atest FrameworksWifiApiTests Change-Id: I6203be94847e962ba87b97d1e5b4777678b7886a --- wifi/java/android/net/wifi/SoftApConfiguration.java | 2 +- wifi/java/android/net/wifi/WifiManager.java | 5 +++++ wifi/java/android/net/wifi/WifiNetworkSpecifier.java | 6 +++--- wifi/java/android/net/wifi/WifiNetworkSuggestion.java | 2 +- .../android/net/wifi/WifiNetworkAgentSpecifierTest.java | 4 ++-- .../src/android/net/wifi/WifiNetworkSpecifierTest.java | 14 +++++++++----- .../src/android/net/wifi/WifiNetworkSuggestionTest.java | 2 +- 7 files changed, 22 insertions(+), 13 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java index 8030bd66e313..d755053e60d2 100644 --- a/wifi/java/android/net/wifi/SoftApConfiguration.java +++ b/wifi/java/android/net/wifi/SoftApConfiguration.java @@ -388,7 +388,7 @@ public final class SoftApConfiguration implements Parcelable { @NonNull public Builder setBssid(@Nullable MacAddress bssid) { if (bssid != null) { - Preconditions.checkArgument(!bssid.equals(MacAddress.ALL_ZEROS_ADDRESS)); + Preconditions.checkArgument(!bssid.equals(WifiManager.ALL_ZEROS_MAC_ADDRESS)); Preconditions.checkArgument(!bssid.equals(MacAddress.BROADCAST_ADDRESS)); } mBssid = bssid; diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 83bba27e48a2..2a95316fd071 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -35,6 +35,7 @@ import android.content.Context; import android.content.pm.ParceledListSlice; import android.net.ConnectivityManager; import android.net.DhcpInfo; +import android.net.MacAddress; import android.net.Network; import android.net.NetworkStack; import android.net.wifi.hotspot2.IProvisioningCallback; @@ -1184,6 +1185,10 @@ public class WifiManager { /** Indicates an invalid SSID. */ public static final String UNKNOWN_SSID = ""; + /** @hide */ + public static final MacAddress ALL_ZEROS_MAC_ADDRESS = + MacAddress.fromString("00:00:00:00:00:00"); + /* Number of currently active WifiLocks and MulticastLocks */ @UnsupportedAppUsage private int mActiveLockCount; diff --git a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java index ba9dd37398a1..07afd7fb6714 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java +++ b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java @@ -49,11 +49,11 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc private static final String MATCH_ALL_SSID_PATTERN_PATH = ".*"; private static final String MATCH_EMPTY_SSID_PATTERN_PATH = ""; private static final Pair MATCH_NO_BSSID_PATTERN1 = - new Pair(MacAddress.BROADCAST_ADDRESS, MacAddress.BROADCAST_ADDRESS); + new Pair<>(MacAddress.BROADCAST_ADDRESS, MacAddress.BROADCAST_ADDRESS); private static final Pair MATCH_NO_BSSID_PATTERN2 = - new Pair(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.BROADCAST_ADDRESS); + new Pair<>(WifiManager.ALL_ZEROS_MAC_ADDRESS, MacAddress.BROADCAST_ADDRESS); private static final Pair MATCH_ALL_BSSID_PATTERN = - new Pair(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS); + new Pair<>(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS); private static final MacAddress MATCH_EXACT_BSSID_PATTERN_MASK = MacAddress.BROADCAST_ADDRESS; diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java index a5ca82c50627..e78104d3da38 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java +++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java @@ -545,7 +545,7 @@ public final class WifiNetworkSuggestion implements Parcelable { } if (mBssid != null && (mBssid.equals(MacAddress.BROADCAST_ADDRESS) - || mBssid.equals(MacAddress.ALL_ZEROS_ADDRESS))) { + || mBssid.equals(WifiManager.ALL_ZEROS_MAC_ADDRESS))) { throw new IllegalStateException("invalid bssid for suggestion"); } wifiConfiguration = buildWifiConfiguration(); diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java index e6eece85cb19..adc41f0df4b4 100644 --- a/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java +++ b/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java @@ -208,7 +208,7 @@ public class WifiNetworkAgentSpecifierTest { PatternMatcher ssidPattern = new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX); Pair bssidPattern = - Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS); + Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS); WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration(); wificonfigurationNetworkSpecifier.allowedKeyManagement .set(WifiConfiguration.KeyMgmt.WPA_PSK); @@ -299,7 +299,7 @@ public class WifiNetworkAgentSpecifierTest { PatternMatcher ssidPattern = new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX); Pair bssidPattern = - Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS); + Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS); WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration(); wificonfigurationNetworkSpecifier.allowedKeyManagement .set(WifiConfiguration.KeyMgmt.WPA_PSK); diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java index edb43d8bdf52..16197443b9d9 100644 --- a/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java +++ b/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java @@ -65,8 +65,10 @@ public class WifiNetworkSpecifierTest { assertEquals(Process.myUid(), wifiNetworkSpecifier.requestorUid); assertEquals(TEST_SSID, wifiNetworkSpecifier.ssidPatternMatcher.getPath()); assertEquals(PATTERN_PREFIX, wifiNetworkSpecifier.ssidPatternMatcher.getType()); - assertEquals(MacAddress.ALL_ZEROS_ADDRESS, wifiNetworkSpecifier.bssidPatternMatcher.first); - assertEquals(MacAddress.ALL_ZEROS_ADDRESS, wifiNetworkSpecifier.bssidPatternMatcher.second); + assertEquals(WifiManager.ALL_ZEROS_MAC_ADDRESS, + wifiNetworkSpecifier.bssidPatternMatcher.first); + assertEquals(WifiManager.ALL_ZEROS_MAC_ADDRESS, + wifiNetworkSpecifier.bssidPatternMatcher.second); assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement .get(WifiConfiguration.KeyMgmt.NONE)); } @@ -210,7 +212,8 @@ public class WifiNetworkSpecifierTest { @Test(expected = IllegalStateException.class) public void testWifiNetworkSpecifierBuilderWithMatchAllBssidPattern() { new WifiNetworkSpecifier.Builder() - .setBssidPattern(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS) + .setBssidPattern(WifiManager.ALL_ZEROS_MAC_ADDRESS, + WifiManager.ALL_ZEROS_MAC_ADDRESS) .build(); } @@ -265,7 +268,7 @@ public class WifiNetworkSpecifierTest { @Test(expected = IllegalStateException.class) public void testWifiNetworkSpecifierBuilderWithMatchNoneBssidPattern3() { new WifiNetworkSpecifier.Builder() - .setBssid(MacAddress.ALL_ZEROS_ADDRESS) + .setBssid(WifiManager.ALL_ZEROS_MAC_ADDRESS) .build(); } @@ -513,7 +516,8 @@ public class WifiNetworkSpecifierTest { WifiNetworkSpecifier specifier2 = new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL), - Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS), + Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, + WifiManager.ALL_ZEROS_MAC_ADDRESS), wifiConfiguration, TEST_UID, TEST_PACKAGE_NAME); diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java index ce085f55b0dd..8a5a0fd6805b 100644 --- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java +++ b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java @@ -294,7 +294,7 @@ public class WifiNetworkSuggestionTest { public void testWifiNetworkSuggestionBuilderWithInvalidAllZeroBssid() { new WifiNetworkSuggestion.Builder() .setSsid(TEST_SSID) - .setBssid(MacAddress.ALL_ZEROS_ADDRESS) + .setBssid(WifiManager.ALL_ZEROS_MAC_ADDRESS) .build(); } -- cgit v1.2.3 From 3b39715eeea241cde5b7610db8a686847bfc5395 Mon Sep 17 00:00:00 2001 From: Ahmed ElArabawy Date: Thu, 7 Nov 2019 10:13:56 -0800 Subject: Wifi: Add 6GHz bands This commit adds the 6GHz band to the list of bands available for WifiScanner APIs Bug: 139354972 Test: atest com.android.wifi.server Change-Id: I7570edba0dc88f81c0b034606d55d08c39bc3782 --- wifi/java/android/net/wifi/WifiScanner.java | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index b2930772c217..c743b63483d9 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -65,14 +65,17 @@ public class WifiScanner { /** @hide */ public static final int WIFI_BAND_INDEX_5_GHZ_DFS_ONLY = 2; /** @hide */ - public static final int WIFI_BAND_COUNT = 3; + public static final int WIFI_BAND_INDEX_6_GHZ = 3; + /** @hide */ + public static final int WIFI_BAND_COUNT = 4; /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = {"WIFI_BAND_INDEX_"}, value = { WIFI_BAND_INDEX_24_GHZ, WIFI_BAND_INDEX_5_GHZ, - WIFI_BAND_INDEX_5_GHZ_DFS_ONLY}) + WIFI_BAND_INDEX_5_GHZ_DFS_ONLY, + WIFI_BAND_INDEX_6_GHZ}) public @interface WifiBandIndex {} /** no band specified; use channel list instead */ @@ -83,6 +86,8 @@ public class WifiScanner { public static final int WIFI_BAND_5_GHZ = 1 << WIFI_BAND_INDEX_5_GHZ; /** DFS channels from 5 GHz band only */ public static final int WIFI_BAND_5_GHZ_DFS_ONLY = 1 << WIFI_BAND_INDEX_5_GHZ_DFS_ONLY; + /** 6 GHz band */ + public static final int WIFI_BAND_6_GHZ = 1 << WIFI_BAND_INDEX_6_GHZ; /** @hide */ @Retention(RetentionPolicy.SOURCE) @@ -90,7 +95,8 @@ public class WifiScanner { WIFI_BAND_UNSPECIFIED, WIFI_BAND_24_GHZ, WIFI_BAND_5_GHZ, - WIFI_BAND_5_GHZ_DFS_ONLY}) + WIFI_BAND_5_GHZ_DFS_ONLY, + WIFI_BAND_6_GHZ}) public @interface WifiBandBasic {} /** @@ -111,6 +117,11 @@ public class WifiScanner { /** Both 2.4 GHz band and 5 GHz band; with DFS channels */ public static final int WIFI_BAND_BOTH_WITH_DFS = WIFI_BAND_24_GHZ | WIFI_BAND_5_GHZ | WIFI_BAND_5_GHZ_DFS_ONLY; + /** 2.4 GHz band and 5 GHz band (no DFS channels) and 6 GHz */ + public static final int WIFI_BAND_24_5_6_GHZ = WIFI_BAND_BOTH | WIFI_BAND_6_GHZ; + /** 2.4 GHz band and 5 GHz band; with DFS channels and 6 GHz */ + public static final int WIFI_BAND_24_5_WITH_DFS_6_GHZ = + WIFI_BAND_BOTH_WITH_DFS | WIFI_BAND_6_GHZ; /** @hide */ @Retention(RetentionPolicy.SOURCE) @@ -122,14 +133,17 @@ public class WifiScanner { WIFI_BAND_5_GHZ_DFS_ONLY, WIFI_BAND_24_GHZ_WITH_5GHZ_DFS, WIFI_BAND_5_GHZ_WITH_DFS, - WIFI_BAND_BOTH_WITH_DFS}) + WIFI_BAND_BOTH_WITH_DFS, + WIFI_BAND_6_GHZ, + WIFI_BAND_24_5_6_GHZ, + WIFI_BAND_24_5_WITH_DFS_6_GHZ}) public @interface WifiBand {} /** * Max band value * @hide */ - public static final int WIFI_BAND_MAX = 8; + public static final int WIFI_BAND_MAX = 0x10; /** Minimum supported scanning period */ public static final int MIN_SCAN_PERIOD_MS = 1000; @@ -174,7 +188,7 @@ public class WifiScanner { @SystemApi @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) - public List getAvailableChannels(@WifiBand int band) { + public List getAvailableChannels(int band) { try { Bundle bundle = mService.getAvailableChannels(band, mContext.getOpPackageName(), mContext.getFeatureId()); -- cgit v1.2.3 From 7596faf3918fe4c5b950e9300d1786f6b15f916f Mon Sep 17 00:00:00 2001 From: Ahmed ElArabawy Date: Mon, 25 Nov 2019 12:03:56 -0800 Subject: Wifi: Add minRssi and bandBonus for 6GHz band This commit adds the minRssi and bandBonus for 6GHz band in PNO settings. Bug: 139354972 Test: atest com.android.server.wifi Change-Id: I5a9920fcd6efb50e6c959617acb2f1c67db1d581 --- wifi/java/android/net/wifi/ScanResult.java | 14 ++++++++++++++ wifi/java/android/net/wifi/WifiScanner.java | 8 ++++++++ wifi/tests/src/android/net/wifi/WifiScannerTest.java | 8 +++++++- 3 files changed, 29 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java index 9956901434d0..729ef61f0e4d 100644 --- a/wifi/java/android/net/wifi/ScanResult.java +++ b/wifi/java/android/net/wifi/ScanResult.java @@ -497,6 +497,13 @@ public class ScanResult implements Parcelable { return ScanResult.is5GHz(frequency); } + /** + * @hide + */ + public boolean is6GHz() { + return ScanResult.is6GHz(frequency); + } + /** * @hide * TODO: makes real freq boundaries @@ -505,6 +512,13 @@ public class ScanResult implements Parcelable { return freq > 4900 && freq < 5900; } + /** + * @hide + */ + public static boolean is6GHz(int freq) { + return freq > 5925 && freq < 7125; + } + /** * @hide * anqp lines from supplicant BSS response diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index c743b63483d9..760497b727cd 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -740,6 +740,8 @@ public class WifiScanner { public int min5GHzRssi; /** Minimum 2.4GHz RSSI for a BSSID to be considered */ public int min24GHzRssi; + /** Minimum 6GHz RSSI for a BSSID to be considered */ + public int min6GHzRssi; /** Maximum score that a network can have before bonuses */ public int initialScoreMax; /** @@ -753,6 +755,8 @@ public class WifiScanner { public int secureBonus; /** 5GHz RSSI score bonus (applied to all 5GHz networks) */ public int band5GHzBonus; + /** 6GHz RSSI score bonus (applied to all 5GHz networks) */ + public int band6GHzBonus; /** Pno Network filter list */ public PnoNetwork[] networkList; @@ -766,11 +770,13 @@ public class WifiScanner { dest.writeInt(isConnected ? 1 : 0); dest.writeInt(min5GHzRssi); dest.writeInt(min24GHzRssi); + dest.writeInt(min6GHzRssi); dest.writeInt(initialScoreMax); dest.writeInt(currentConnectionBonus); dest.writeInt(sameNetworkBonus); dest.writeInt(secureBonus); dest.writeInt(band5GHzBonus); + dest.writeInt(band6GHzBonus); if (networkList != null) { dest.writeInt(networkList.length); for (int i = 0; i < networkList.length; i++) { @@ -792,11 +798,13 @@ public class WifiScanner { settings.isConnected = in.readInt() == 1; settings.min5GHzRssi = in.readInt(); settings.min24GHzRssi = in.readInt(); + settings.min6GHzRssi = in.readInt(); settings.initialScoreMax = in.readInt(); settings.currentConnectionBonus = in.readInt(); settings.sameNetworkBonus = in.readInt(); settings.secureBonus = in.readInt(); settings.band5GHzBonus = in.readInt(); + settings.band6GHzBonus = in.readInt(); int numNetworks = in.readInt(); settings.networkList = new PnoNetwork[numNetworks]; for (int i = 0; i < numNetworks; i++) { diff --git a/wifi/tests/src/android/net/wifi/WifiScannerTest.java b/wifi/tests/src/android/net/wifi/WifiScannerTest.java index b1436c90f5dd..fa4f711056db 100644 --- a/wifi/tests/src/android/net/wifi/WifiScannerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiScannerTest.java @@ -79,15 +79,17 @@ public class WifiScannerTest { private static final boolean TEST_PNOSETTINGS_IS_CONNECTED = false; private static final int TEST_PNOSETTINGS_MIN_5GHZ_RSSI = -60; private static final int TEST_PNOSETTINGS_MIN_2GHZ_RSSI = -70; + private static final int TEST_PNOSETTINGS_MIN_6GHZ_RSSI = -55; private static final int TEST_PNOSETTINGS_INITIAL_SCORE_MAX = 50; private static final int TEST_PNOSETTINGS_CURRENT_CONNECTION_BONUS = 10; private static final int TEST_PNOSETTINGS_SAME_NETWORK_BONUS = 11; private static final int TEST_PNOSETTINGS_SECURE_BONUS = 12; private static final int TEST_PNOSETTINGS_BAND_5GHZ_BONUS = 13; + private static final int TEST_PNOSETTINGS_BAND_6GHZ_BONUS = 15; private static final String TEST_SSID_1 = "TEST1"; private static final String TEST_SSID_2 = "TEST2"; private static final int[] TEST_FREQUENCIES_1 = {}; - private static final int[] TEST_FREQUENCIES_2 = {2500, 5124}; + private static final int[] TEST_FREQUENCIES_2 = {2500, 5124, 6245}; private static final String DESCRIPTION_NOT_AUTHORIZED = "Not authorized"; private WifiScanner mWifiScanner; @@ -183,11 +185,13 @@ public class WifiScannerTest { pnoSettings.isConnected = TEST_PNOSETTINGS_IS_CONNECTED; pnoSettings.min5GHzRssi = TEST_PNOSETTINGS_MIN_5GHZ_RSSI; pnoSettings.min24GHzRssi = TEST_PNOSETTINGS_MIN_2GHZ_RSSI; + pnoSettings.min6GHzRssi = TEST_PNOSETTINGS_MIN_6GHZ_RSSI; pnoSettings.initialScoreMax = TEST_PNOSETTINGS_INITIAL_SCORE_MAX; pnoSettings.currentConnectionBonus = TEST_PNOSETTINGS_CURRENT_CONNECTION_BONUS; pnoSettings.sameNetworkBonus = TEST_PNOSETTINGS_SAME_NETWORK_BONUS; pnoSettings.secureBonus = TEST_PNOSETTINGS_SECURE_BONUS; pnoSettings.band5GHzBonus = TEST_PNOSETTINGS_BAND_5GHZ_BONUS; + pnoSettings.band6GHzBonus = TEST_PNOSETTINGS_BAND_6GHZ_BONUS; Parcel parcel = Parcel.obtain(); pnoSettings.writeToParcel(parcel, 0); @@ -200,6 +204,7 @@ public class WifiScannerTest { assertEquals(TEST_PNOSETTINGS_IS_CONNECTED, pnoSettingsDeserialized.isConnected); assertEquals(TEST_PNOSETTINGS_MIN_5GHZ_RSSI, pnoSettingsDeserialized.min5GHzRssi); assertEquals(TEST_PNOSETTINGS_MIN_2GHZ_RSSI, pnoSettingsDeserialized.min24GHzRssi); + assertEquals(TEST_PNOSETTINGS_MIN_6GHZ_RSSI, pnoSettingsDeserialized.min6GHzRssi); assertEquals(TEST_PNOSETTINGS_INITIAL_SCORE_MAX, pnoSettingsDeserialized.initialScoreMax); assertEquals(TEST_PNOSETTINGS_CURRENT_CONNECTION_BONUS, pnoSettingsDeserialized.currentConnectionBonus); @@ -207,6 +212,7 @@ public class WifiScannerTest { pnoSettingsDeserialized.sameNetworkBonus); assertEquals(TEST_PNOSETTINGS_SECURE_BONUS, pnoSettingsDeserialized.secureBonus); assertEquals(TEST_PNOSETTINGS_BAND_5GHZ_BONUS, pnoSettingsDeserialized.band5GHzBonus); + assertEquals(TEST_PNOSETTINGS_BAND_6GHZ_BONUS, pnoSettingsDeserialized.band6GHzBonus); // Test parsing of PnoNetwork assertEquals(pnoSettings.networkList.length, pnoSettingsDeserialized.networkList.length); -- cgit v1.2.3 From a69a245bb24987cd88b4c4de1d1a707fa3a86054 Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 5 Dec 2019 14:17:40 -0800 Subject: NetworkUtils is deprecated, migrate to Inet4AddressUtils Migrate NetworkUtils.inetAddressToInt() to Inet4AddressUtils.inet4AddressToIntHTL() in preparation to jarjar Inet4AddressUtils. Bug: 145409537 Test: compiles Change-Id: Ia57dde498db3e9b011d0a9772717b1539348cd37 --- wifi/java/android/net/wifi/WifiInfo.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java index f3f873b4ead8..f728491d33cd 100644 --- a/wifi/java/android/net/wifi/WifiInfo.java +++ b/wifi/java/android/net/wifi/WifiInfo.java @@ -21,7 +21,7 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; import android.net.NetworkInfo.DetailedState; -import android.net.NetworkUtils; +import android.net.shared.Inet4AddressUtils; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -708,7 +708,7 @@ public class WifiInfo implements Parcelable { public int getIpAddress() { int result = 0; if (mIpAddress instanceof Inet4Address) { - result = NetworkUtils.inetAddressToInt((Inet4Address)mIpAddress); + result = Inet4AddressUtils.inet4AddressToIntHTL((Inet4Address) mIpAddress); } return result; } -- cgit v1.2.3 From 26ef68260aa896ff51a27ebb3ee1361466f65689 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Mon, 2 Dec 2019 12:48:29 -0800 Subject: WifiActivityEnergyInfo: Use time values for energy calculation This removes PowerProfile @hide usage in wifi service. Bug: 145533104 Test: Compiles Change-Id: I56d366d557f5afe379f4ea0cbbff2c3b72440d99 --- wifi/tests/src/android/net/wifi/WifiManagerTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'wifi') diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index de4514997b1c..ac3304073809 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -161,7 +161,7 @@ public class WifiManagerTest { mRunnable.run(); } }; - mWifiActivityEnergyInfo = new WifiActivityEnergyInfo(0, 0, 0, 0, 0, 0, 0); + mWifiActivityEnergyInfo = new WifiActivityEnergyInfo(0, 0, 0, 0, 0, 0); } /** @@ -1713,7 +1713,7 @@ public class WifiManagerTest { @Test public void testGetControllerActivityEnergyInfo() throws Exception { WifiActivityEnergyInfo activityEnergyInfo = - new WifiActivityEnergyInfo(5, 3, 3, 5, 5, 5, 5); + new WifiActivityEnergyInfo(5, 3, 3, 5, 5, 5); when(mWifiService.reportActivityInfo()).thenReturn(activityEnergyInfo); assertEquals(activityEnergyInfo, mWifiManager.getControllerActivityEnergyInfo()); -- cgit v1.2.3 From a027f740ee4a530e10ffac6650c3d697f291c0ff Mon Sep 17 00:00:00 2001 From: Ahmed ElArabawy Date: Thu, 5 Dec 2019 10:35:39 -0800 Subject: Wifi: Add support of 6GHz band to NAN This commit adds the support of 6GHz band to NAN. Bug: 139354972 Test: atest com.android.wifi.server Change-Id: Ifb14b4b9d52119c782615e916b457839848f22d7 --- .../java/android/net/wifi/aware/ConfigRequest.java | 74 ++++++++++++++++------ .../net/wifi/aware/WifiAwareManagerTest.java | 18 +++++- 2 files changed, 71 insertions(+), 21 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/aware/ConfigRequest.java b/wifi/java/android/net/wifi/aware/ConfigRequest.java index b07d8edde3d4..61ab92c9416f 100644 --- a/wifi/java/android/net/wifi/aware/ConfigRequest.java +++ b/wifi/java/android/net/wifi/aware/ConfigRequest.java @@ -47,6 +47,7 @@ public final class ConfigRequest implements Parcelable { */ public static final int NAN_BAND_24GHZ = 0; public static final int NAN_BAND_5GHZ = 1; + public static final int NAN_BAND_6GHZ = 2; /** * Magic values for Discovery Window (DW) interval configuration @@ -59,6 +60,11 @@ public final class ConfigRequest implements Parcelable { */ public final boolean mSupport5gBand; + /** + * Indicates whether 6G band support is requested. + */ + public final boolean mSupport6gBand; + /** * Specifies the desired master preference. */ @@ -81,9 +87,10 @@ public final class ConfigRequest implements Parcelable { */ public final int mDiscoveryWindowInterval[]; - private ConfigRequest(boolean support5gBand, int masterPreference, int clusterLow, - int clusterHigh, int discoveryWindowInterval[]) { + private ConfigRequest(boolean support5gBand, boolean support6gBand, int masterPreference, + int clusterLow, int clusterHigh, int[] discoveryWindowInterval) { mSupport5gBand = support5gBand; + mSupport6gBand = support6gBand; mMasterPreference = masterPreference; mClusterLow = clusterLow; mClusterHigh = clusterHigh; @@ -92,10 +99,12 @@ public final class ConfigRequest implements Parcelable { @Override public String toString() { - return "ConfigRequest [mSupport5gBand=" + mSupport5gBand + ", mMasterPreference=" - + mMasterPreference + ", mClusterLow=" + mClusterLow + ", mClusterHigh=" - + mClusterHigh + ", mDiscoveryWindowInterval=" - + Arrays.toString(mDiscoveryWindowInterval) + "]"; + return "ConfigRequest [mSupport5gBand=" + mSupport5gBand + + ", mSupport6gBand=" + mSupport6gBand + + ", mMasterPreference=" + mMasterPreference + + ", mClusterLow=" + mClusterLow + + ", mClusterHigh=" + mClusterHigh + + ", mDiscoveryWindowInterval=" + Arrays.toString(mDiscoveryWindowInterval) + "]"; } @Override @@ -106,6 +115,7 @@ public final class ConfigRequest implements Parcelable { @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mSupport5gBand ? 1 : 0); + dest.writeInt(mSupport6gBand ? 1 : 0); dest.writeInt(mMasterPreference); dest.writeInt(mClusterLow); dest.writeInt(mClusterHigh); @@ -121,13 +131,14 @@ public final class ConfigRequest implements Parcelable { @Override public ConfigRequest createFromParcel(Parcel in) { boolean support5gBand = in.readInt() != 0; + boolean support6gBand = in.readInt() != 0; int masterPreference = in.readInt(); int clusterLow = in.readInt(); int clusterHigh = in.readInt(); int discoveryWindowInterval[] = in.createIntArray(); - return new ConfigRequest(support5gBand, masterPreference, clusterLow, clusterHigh, - discoveryWindowInterval); + return new ConfigRequest(support5gBand, support6gBand, masterPreference, clusterLow, + clusterHigh, discoveryWindowInterval); } }; @@ -143,7 +154,9 @@ public final class ConfigRequest implements Parcelable { ConfigRequest lhs = (ConfigRequest) o; - return mSupport5gBand == lhs.mSupport5gBand && mMasterPreference == lhs.mMasterPreference + return mSupport5gBand == lhs.mSupport5gBand + && mSupport6gBand == lhs.mSupport6gBand + && mMasterPreference == lhs.mMasterPreference && mClusterLow == lhs.mClusterLow && mClusterHigh == lhs.mClusterHigh && Arrays.equals(mDiscoveryWindowInterval, lhs.mDiscoveryWindowInterval); } @@ -153,6 +166,7 @@ public final class ConfigRequest implements Parcelable { int result = 17; result = 31 * result + (mSupport5gBand ? 1 : 0); + result = 31 * result + (mSupport6gBand ? 1 : 0); result = 31 * result + mMasterPreference; result = 31 * result + mClusterLow; result = 31 * result + mClusterHigh; @@ -190,9 +204,9 @@ public final class ConfigRequest implements Parcelable { throw new IllegalArgumentException( "Invalid argument combination - must have Cluster Low <= Cluster High"); } - if (mDiscoveryWindowInterval.length != 2) { + if (mDiscoveryWindowInterval.length != 3) { throw new IllegalArgumentException( - "Invalid discovery window interval: must have 2 elements (2.4 & 5"); + "Invalid discovery window interval: must have 3 elements (2.4 & 5 & 6"); } if (mDiscoveryWindowInterval[NAN_BAND_24GHZ] != DW_INTERVAL_NOT_INIT && (mDiscoveryWindowInterval[NAN_BAND_24GHZ] < 1 // valid for 2.4GHz: [1-5] @@ -206,7 +220,12 @@ public final class ConfigRequest implements Parcelable { throw new IllegalArgumentException( "Invalid discovery window interval for 5GHz: valid is UNSET or [0,5]"); } - + if (mDiscoveryWindowInterval[NAN_BAND_6GHZ] != DW_INTERVAL_NOT_INIT + && (mDiscoveryWindowInterval[NAN_BAND_6GHZ] < 0 // valid for 6GHz: [0-5] + || mDiscoveryWindowInterval[NAN_BAND_6GHZ] > 5)) { + throw new IllegalArgumentException( + "Invalid discovery window interval for 6GHz: valid is UNSET or [0,5]"); + } } /** @@ -214,10 +233,12 @@ public final class ConfigRequest implements Parcelable { */ public static final class Builder { private boolean mSupport5gBand = true; + private boolean mSupport6gBand = false; private int mMasterPreference = 0; private int mClusterLow = CLUSTER_ID_MIN; private int mClusterHigh = CLUSTER_ID_MAX; - private int mDiscoveryWindowInterval[] = {DW_INTERVAL_NOT_INIT, DW_INTERVAL_NOT_INIT}; + private int[] mDiscoveryWindowInterval = {DW_INTERVAL_NOT_INIT, DW_INTERVAL_NOT_INIT, + DW_INTERVAL_NOT_INIT}; /** * Specify whether 5G band support is required in this request. Disabled by default. @@ -232,6 +253,19 @@ public final class ConfigRequest implements Parcelable { return this; } + /** + * Specify whether 6G band support is required in this request. Disabled by default. + * + * @param support6gBand Support for 6G band is required. + * + * @return The builder to facilitate chaining + * {@code builder.setXXX(..).setXXX(..)}. + */ + public Builder setSupport6gBand(boolean support6gBand) { + mSupport6gBand = support6gBand; + return this; + } + /** * Specify the Master Preference requested. The permitted range is 0 (the default) to * 255 with 1 and 255 excluded (reserved). @@ -310,7 +344,8 @@ public final class ConfigRequest implements Parcelable { * awake. The configuration enables trading off latency vs. power (higher interval means * higher discovery latency but lower power). * - * @param band Either {@link #NAN_BAND_24GHZ} or {@link #NAN_BAND_5GHZ}. + * @param band Either {@link #NAN_BAND_24GHZ} or {@link #NAN_BAND_5GHZ} or + * {@link #NAN_BAND_6GHZ}. * @param interval A value of 1, 2, 3, 4, or 5 indicating an interval of 2^(interval-1). For * the 5GHz band a value of 0 indicates that the device will not be awake * for any discovery windows. @@ -319,13 +354,14 @@ public final class ConfigRequest implements Parcelable { * {@code builder.setDiscoveryWindowInterval(...).setMasterPreference(...)}. */ public Builder setDiscoveryWindowInterval(int band, int interval) { - if (band != NAN_BAND_24GHZ && band != NAN_BAND_5GHZ) { + if (band != NAN_BAND_24GHZ && band != NAN_BAND_5GHZ && band != NAN_BAND_6GHZ) { throw new IllegalArgumentException("Invalid band value"); } if ((band == NAN_BAND_24GHZ && (interval < 1 || interval > 5)) - || (band == NAN_BAND_5GHZ && (interval < 0 || interval > 5))) { + || (band == NAN_BAND_5GHZ && (interval < 0 || interval > 5)) + || (band == NAN_BAND_6GHZ && (interval < 0 || interval > 5))) { throw new IllegalArgumentException( - "Invalid interval value: 2.4 GHz [1,5] or 5GHz [0,5]"); + "Invalid interval value: 2.4 GHz [1,5] or 5GHz/6GHz [0,5]"); } mDiscoveryWindowInterval[band] = interval; @@ -342,8 +378,8 @@ public final class ConfigRequest implements Parcelable { "Invalid argument combination - must have Cluster Low <= Cluster High"); } - return new ConfigRequest(mSupport5gBand, mMasterPreference, mClusterLow, mClusterHigh, - mDiscoveryWindowInterval); + return new ConfigRequest(mSupport5gBand, mSupport6gBand, mMasterPreference, mClusterLow, + mClusterHigh, mDiscoveryWindowInterval); } } } diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java index 3483ff8a4664..145c272df4f4 100644 --- a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java +++ b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java @@ -579,12 +579,15 @@ public class WifiAwareManagerTest { collector.checkThat("mMasterPreference", 0, equalTo(configRequest.mMasterPreference)); collector.checkThat("mSupport5gBand", true, equalTo(configRequest.mSupport5gBand)); - collector.checkThat("mDiscoveryWindowInterval.length", 2, + collector.checkThat("mSupport6gBand", false, equalTo(configRequest.mSupport6gBand)); + collector.checkThat("mDiscoveryWindowInterval.length", 3, equalTo(configRequest.mDiscoveryWindowInterval.length)); collector.checkThat("mDiscoveryWindowInterval[2.4GHz]", ConfigRequest.DW_INTERVAL_NOT_INIT, equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_24GHZ])); collector.checkThat("mDiscoveryWindowInterval[5Hz]", ConfigRequest.DW_INTERVAL_NOT_INIT, equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_5GHZ])); + collector.checkThat("mDiscoveryWindowInterval[6Hz]", ConfigRequest.DW_INTERVAL_NOT_INIT, + equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_6GHZ])); } @Test @@ -593,12 +596,16 @@ public class WifiAwareManagerTest { final int clusterLow = 5; final int masterPreference = 55; final boolean supportBand5g = true; + final boolean supportBand6g = true; final int dwWindow5GHz = 3; + final int dwWindow6GHz = 4; ConfigRequest configRequest = new ConfigRequest.Builder().setClusterHigh(clusterHigh) .setClusterLow(clusterLow).setMasterPreference(masterPreference) .setSupport5gBand(supportBand5g) + .setSupport6gBand(supportBand6g) .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_5GHZ, dwWindow5GHz) + .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_6GHZ, dwWindow6GHz) .build(); collector.checkThat("mClusterHigh", clusterHigh, equalTo(configRequest.mClusterHigh)); @@ -606,12 +613,15 @@ public class WifiAwareManagerTest { collector.checkThat("mMasterPreference", masterPreference, equalTo(configRequest.mMasterPreference)); collector.checkThat("mSupport5gBand", supportBand5g, equalTo(configRequest.mSupport5gBand)); - collector.checkThat("mDiscoveryWindowInterval.length", 2, + collector.checkThat("mSupport6gBand", supportBand6g, equalTo(configRequest.mSupport6gBand)); + collector.checkThat("mDiscoveryWindowInterval.length", 3, equalTo(configRequest.mDiscoveryWindowInterval.length)); collector.checkThat("mDiscoveryWindowInterval[2.4GHz]", ConfigRequest.DW_INTERVAL_NOT_INIT, equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_24GHZ])); collector.checkThat("mDiscoveryWindowInterval[5GHz]", dwWindow5GHz, equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_5GHZ])); + collector.checkThat("mDiscoveryWindowInterval[6GHz]", dwWindow6GHz, + equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_6GHZ])); } @Test(expected = IllegalArgumentException.class) @@ -690,14 +700,18 @@ public class WifiAwareManagerTest { final int clusterLow = 25; final int masterPreference = 177; final boolean supportBand5g = true; + final boolean supportBand6g = false; final int dwWindow24GHz = 1; final int dwWindow5GHz = 5; + final int dwWindow6GHz = 4; ConfigRequest configRequest = new ConfigRequest.Builder().setClusterHigh(clusterHigh) .setClusterLow(clusterLow).setMasterPreference(masterPreference) .setSupport5gBand(supportBand5g) + .setSupport6gBand(supportBand6g) .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_24GHZ, dwWindow24GHz) .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_5GHZ, dwWindow5GHz) + .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_6GHZ, dwWindow6GHz) .build(); Parcel parcelW = Parcel.obtain(); -- cgit v1.2.3 From d0f5475b3da8635fd5c96eea9773b6cbc5896052 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Thu, 5 Dec 2019 10:19:39 -0800 Subject: WifiAwareManager: Add requestMacAddresses @hide API Allows RttService to use WifiManager class instead of using the AIDL object. Bug: 145746458 Test: Compiles Change-Id: I0949067ac7a56a6da802e8dc81eef08779a786eb --- wifi/java/android/net/wifi/aware/WifiAwareManager.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/aware/WifiAwareManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java index 7b37d652426d..2f29e4a4e34a 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java @@ -19,6 +19,7 @@ package android.net.wifi.aware; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemService; @@ -396,6 +397,17 @@ public class WifiAwareManager { } } + /** @hide */ + @RequiresPermission(android.Manifest.permission.NETWORK_STACK) + public void requestMacAddresses(int uid, List peerIds, + IWifiAwareMacAddressProvider callback) { + try { + mService.requestMacAddresses(uid, peerIds, callback); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** @hide */ public NetworkSpecifier createNetworkSpecifier(int clientId, int role, int sessionId, @NonNull PeerHandle peerHandle, @Nullable byte[] pmk, @Nullable String passphrase) { -- cgit v1.2.3 From 4bb69be2b0959359165f5f00f15a5e8561ffa827 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Thu, 5 Dec 2019 12:05:17 -0800 Subject: WifiNetworkSuggestion: Don't store packageName/uid The service will stamp the uid, package name of individual suggestions when it creates its internal representation for each suggestion (i.e ExtendedWifiNetworkSuggestion). This is to avoid using an @hide API inside WifiNetworkSuggestion to stamp the uid/package name of the app using a retrieved context. Bug: 144102365 Test: atest android.net.wifi Change-Id: I86651c76053b613d9eb9dc95ab51b07b11f23f16 --- .../android/net/wifi/WifiNetworkSuggestion.java | 49 +++------------- .../net/wifi/WifiNetworkSuggestionTest.java | 67 +++------------------- 2 files changed, 17 insertions(+), 99 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java index e78104d3da38..9fd29ae8d14a 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java +++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java @@ -23,12 +23,10 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; -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; import android.telephony.TelephonyManager; import android.text.TextUtils; @@ -46,7 +44,6 @@ import java.util.Objects; * {@link WifiManager#addNetworkSuggestions(List)}. */ public final class WifiNetworkSuggestion implements Parcelable { - /** * Builder used to create {@link WifiNetworkSuggestion} objects. */ @@ -563,9 +560,7 @@ public final class WifiNetworkSuggestion implements Parcelable { mPasspointConfiguration, mIsAppInteractionRequired, mIsUserInteractionRequired, - mIsUserAllowed, - Process.myUid(), - ActivityThread.currentApplication().getApplicationContext().getOpPackageName()); + mIsUserAllowed); } } @@ -592,19 +587,6 @@ public final class WifiNetworkSuggestion implements Parcelable { * @hide */ public final boolean isUserInteractionRequired; - - /** - * The UID of the process initializing this network suggestion. - * @hide - */ - public final int suggestorUid; - - /** - * The package name of the process initializing this network suggestion. - * @hide - */ - public final String suggestorPackageName; - /** * Whether app share credential with the user, allow user use provided credential to * connect network manually. @@ -619,8 +601,6 @@ public final class WifiNetworkSuggestion implements Parcelable { this.isAppInteractionRequired = false; this.isUserInteractionRequired = false; this.isUserAllowedToManuallyConnect = true; - this.suggestorUid = -1; - this.suggestorPackageName = null; } /** @hide */ @@ -628,18 +608,14 @@ public final class WifiNetworkSuggestion implements Parcelable { @Nullable PasspointConfiguration passpointConfiguration, boolean isAppInteractionRequired, boolean isUserInteractionRequired, - boolean isUserAllowedToManuallyConnect, - int suggestorUid, @NonNull String suggestorPackageName) { + boolean isUserAllowedToManuallyConnect) { checkNotNull(networkConfiguration); - checkNotNull(suggestorPackageName); this.wifiConfiguration = networkConfiguration; this.passpointConfiguration = passpointConfiguration; this.isAppInteractionRequired = isAppInteractionRequired; this.isUserInteractionRequired = isUserInteractionRequired; this.isUserAllowedToManuallyConnect = isUserAllowedToManuallyConnect; - this.suggestorUid = suggestorUid; - this.suggestorPackageName = suggestorPackageName; } public static final @NonNull Creator CREATOR = @@ -651,9 +627,7 @@ public final class WifiNetworkSuggestion implements Parcelable { in.readParcelable(null), // PasspointConfiguration in.readBoolean(), // isAppInteractionRequired in.readBoolean(), // isUserInteractionRequired - in.readBoolean(), // isSharedCredentialWithUser - in.readInt(), // suggestorUid - in.readString() // suggestorPackageName + in.readBoolean() // isSharedCredentialWithUser ); } @@ -675,15 +649,12 @@ public final class WifiNetworkSuggestion implements Parcelable { dest.writeBoolean(isAppInteractionRequired); dest.writeBoolean(isUserInteractionRequired); dest.writeBoolean(isUserAllowedToManuallyConnect); - dest.writeInt(suggestorUid); - dest.writeString(suggestorPackageName); } @Override public int hashCode() { return Objects.hash(wifiConfiguration.SSID, wifiConfiguration.BSSID, - wifiConfiguration.allowedKeyManagement, wifiConfiguration.FQDN, - suggestorUid, suggestorPackageName); + wifiConfiguration.allowedKeyManagement, wifiConfiguration.FQDN); } /** @@ -706,23 +677,19 @@ public final class WifiNetworkSuggestion implements Parcelable { && TextUtils.equals(this.wifiConfiguration.BSSID, lhs.wifiConfiguration.BSSID) && Objects.equals(this.wifiConfiguration.allowedKeyManagement, lhs.wifiConfiguration.allowedKeyManagement) - && TextUtils.equals(this.wifiConfiguration.FQDN, lhs.wifiConfiguration.FQDN) - && this.suggestorUid == lhs.suggestorUid - && TextUtils.equals(this.suggestorPackageName, lhs.suggestorPackageName); + && TextUtils.equals(this.wifiConfiguration.FQDN, lhs.wifiConfiguration.FQDN); } @Override public String toString() { - StringBuilder sb = new StringBuilder("WifiNetworkSuggestion [") - .append(", SSID=").append(wifiConfiguration.SSID) + 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(", isUserAllowedToManuallyConnect=").append(isUserAllowedToManuallyConnect) - .append(", suggestorUid=").append(suggestorUid) - .append(", suggestorPackageName=").append(suggestorPackageName) - .append("]"); + .append(" ]"); return sb.toString(); } } diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java index 8a5a0fd6805b..04aaa0bbcad0 100644 --- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java +++ b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java @@ -22,7 +22,6 @@ import android.net.MacAddress; import android.net.wifi.hotspot2.PasspointConfiguration; import android.net.wifi.hotspot2.PasspointTestUtils; import android.os.Parcel; -import android.os.Process; import androidx.test.filters.SmallTest; @@ -35,8 +34,6 @@ import org.junit.Test; public class WifiNetworkSuggestionTest { private static final int TEST_UID = 45677; private static final int TEST_UID_OTHER = 45673; - private static final String TEST_PACKAGE_NAME = "com.test.packagename"; - private static final String TEST_PACKAGE_NAME_OTHER = "com.test.packagenameother"; private static final String TEST_SSID = "\"Test123\""; private static final String TEST_BSSID = "12:12:12:12:12:12"; private static final String TEST_SSID_1 = "\"Test1234\""; @@ -55,7 +52,6 @@ public class WifiNetworkSuggestionTest { .setIsAppInteractionRequired(true) .build(); - assertEquals(Process.myUid(), suggestion.suggestorUid); assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID); assertTrue(suggestion.wifiConfiguration.allowedKeyManagement .get(WifiConfiguration.KeyMgmt.NONE)); @@ -448,7 +444,7 @@ public class WifiNetworkSuggestionTest { configuration.BSSID = TEST_BSSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion( - configuration, null, false, true, true, TEST_UID, TEST_PACKAGE_NAME); + configuration, null, false, true, true); Parcel parcelW = Parcel.obtain(); suggestion.writeToParcel(parcelW, 0); @@ -515,16 +511,14 @@ public class WifiNetworkSuggestionTest { configuration.BSSID = TEST_BSSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, null, true, false, true, TEST_UID, - TEST_PACKAGE_NAME); + new WifiNetworkSuggestion(configuration, null, true, false, true); WifiConfiguration configuration1 = new WifiConfiguration(); configuration1.SSID = TEST_SSID; configuration1.BSSID = TEST_BSSID; configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); WifiNetworkSuggestion suggestion1 = - new WifiNetworkSuggestion(configuration1, null, false, true, true, TEST_UID, - TEST_PACKAGE_NAME); + new WifiNetworkSuggestion(configuration1, null, false, true, true); assertEquals(suggestion, suggestion1); assertEquals(suggestion.hashCode(), suggestion1.hashCode()); @@ -540,15 +534,13 @@ public class WifiNetworkSuggestionTest { configuration.SSID = TEST_SSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, null, false, false, true, TEST_UID, - TEST_PACKAGE_NAME); + new WifiNetworkSuggestion(configuration, null, false, false, true); WifiConfiguration configuration1 = new WifiConfiguration(); configuration1.SSID = TEST_SSID_1; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion1 = - new WifiNetworkSuggestion(configuration1, null, false, false, true, TEST_UID, - TEST_PACKAGE_NAME); + new WifiNetworkSuggestion(configuration1, null, false, false, true); assertNotEquals(suggestion, suggestion1); } @@ -564,15 +556,13 @@ public class WifiNetworkSuggestionTest { configuration.BSSID = TEST_BSSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, null, false, false, true, TEST_UID, - TEST_PACKAGE_NAME); + new WifiNetworkSuggestion(configuration, null, false, false, true); WifiConfiguration configuration1 = new WifiConfiguration(); configuration1.SSID = TEST_SSID; configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion1 = - new WifiNetworkSuggestion(configuration1, null, false, false, true, TEST_UID, - TEST_PACKAGE_NAME); + new WifiNetworkSuggestion(configuration1, null, false, false, true); assertNotEquals(suggestion, suggestion1); } @@ -587,56 +577,17 @@ public class WifiNetworkSuggestionTest { configuration.SSID = TEST_SSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, null, false, false, true, TEST_UID, - TEST_PACKAGE_NAME); + new WifiNetworkSuggestion(configuration, null, false, false, true); WifiConfiguration configuration1 = new WifiConfiguration(); configuration1.SSID = TEST_SSID; configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); WifiNetworkSuggestion suggestion1 = - new WifiNetworkSuggestion(configuration1, null, false, false, true, TEST_UID, - TEST_PACKAGE_NAME); + new WifiNetworkSuggestion(configuration1, null, false, false, true); assertNotEquals(suggestion, suggestion1); } - /** - * Check NetworkSuggestion equals returns {@code false} for 2 network suggestions with the same - * SSID, BSSID and key mgmt, but different UID. - */ - @Test - public void testWifiNetworkSuggestionEqualsFailsWhenUidIsDifferent() { - WifiConfiguration configuration = new WifiConfiguration(); - configuration.SSID = TEST_SSID; - configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); - WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, null, false, false, true, TEST_UID, - TEST_PACKAGE_NAME); - - WifiNetworkSuggestion suggestion1 = - new WifiNetworkSuggestion(configuration, null, false, false, true, TEST_UID_OTHER, - TEST_PACKAGE_NAME); - - assertNotEquals(suggestion, suggestion1); - } - - /** - * Check NetworkSuggestion equals returns {@code false} for 2 network suggestions with the same - * SSID, BSSID and key mgmt, but different package name. - */ - @Test - public void testWifiNetworkSuggestionEqualsFailsWhenPackageNameIsDifferent() { - WifiConfiguration configuration = new WifiConfiguration(); - configuration.SSID = TEST_SSID; - configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); - WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion( - configuration, null, false, false, true, TEST_UID, TEST_PACKAGE_NAME); - - WifiNetworkSuggestion suggestion1 = new WifiNetworkSuggestion( - configuration, null, false, false, true, TEST_UID, TEST_PACKAGE_NAME_OTHER); - - assertNotEquals(suggestion, suggestion1); - } /** * Check NetworkSuggestion equals returns {@code true} for 2 Passpoint network suggestions with * same FQDN. -- cgit v1.2.3 From 5b62f3d496ebdb91ef60f01c1276b66cd8364e1a Mon Sep 17 00:00:00 2001 From: David Su Date: Fri, 6 Dec 2019 12:02:51 -0800 Subject: Copy libcore.utils.HexEncoding into Wifi module @CorePlatformApi's cannot be depended on by Wifi Mainline module. Thus create a copy and migrate usages over. Bug: 145409537 Test: atest FrameworksWifiApiTests Change-Id: If4133bdd9ac9ca005538a03592462d2e1365c0d8 --- .../java/android/net/wifi/aware/PublishConfig.java | 3 +- .../android/net/wifi/aware/SubscribeConfig.java | 3 +- .../wifi/aware/WifiAwareAgentNetworkSpecifier.java | 3 +- .../android/net/wifi/aware/WifiAwareManager.java | 3 +- wifi/java/android/net/wifi/util/HexEncoding.java | 183 +++++++++++++++++++++ .../net/wifi/aware/WifiAwareManagerTest.java | 3 +- .../src/android/net/wifi/util/HexEncodingTest.java | 130 +++++++++++++++ 7 files changed, 318 insertions(+), 10 deletions(-) create mode 100644 wifi/java/android/net/wifi/util/HexEncoding.java create mode 100644 wifi/tests/src/android/net/wifi/util/HexEncodingTest.java (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/aware/PublishConfig.java b/wifi/java/android/net/wifi/aware/PublishConfig.java index 1886b7ef4c8d..a8844c1d3812 100644 --- a/wifi/java/android/net/wifi/aware/PublishConfig.java +++ b/wifi/java/android/net/wifi/aware/PublishConfig.java @@ -19,11 +19,10 @@ package android.net.wifi.aware; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.net.wifi.util.HexEncoding; import android.os.Parcel; import android.os.Parcelable; -import libcore.util.HexEncoding; - import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.nio.charset.StandardCharsets; diff --git a/wifi/java/android/net/wifi/aware/SubscribeConfig.java b/wifi/java/android/net/wifi/aware/SubscribeConfig.java index f0f758170bf2..76780f421af2 100644 --- a/wifi/java/android/net/wifi/aware/SubscribeConfig.java +++ b/wifi/java/android/net/wifi/aware/SubscribeConfig.java @@ -19,11 +19,10 @@ package android.net.wifi.aware; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.net.wifi.util.HexEncoding; import android.os.Parcel; import android.os.Parcelable; -import libcore.util.HexEncoding; - import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.nio.charset.StandardCharsets; diff --git a/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java b/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java index 5ec4c8b13ee8..c66733472d0e 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java @@ -17,12 +17,11 @@ package android.net.wifi.aware; import android.net.NetworkSpecifier; +import android.net.wifi.util.HexEncoding; import android.os.Parcel; import android.os.Parcelable; import android.util.Log; -import libcore.util.HexEncoding; - import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; diff --git a/wifi/java/android/net/wifi/aware/WifiAwareManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java index 7b37d652426d..65a6c4d051cd 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java @@ -26,6 +26,7 @@ import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkRequest; import android.net.NetworkSpecifier; +import android.net.wifi.util.HexEncoding; import android.os.Binder; import android.os.Build; import android.os.Bundle; @@ -36,8 +37,6 @@ import android.os.Process; import android.os.RemoteException; import android.util.Log; -import libcore.util.HexEncoding; - import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; diff --git a/wifi/java/android/net/wifi/util/HexEncoding.java b/wifi/java/android/net/wifi/util/HexEncoding.java new file mode 100644 index 000000000000..9ebf947e2dc3 --- /dev/null +++ b/wifi/java/android/net/wifi/util/HexEncoding.java @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2014 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.util; + +/** + * Hexadecimal encoding where each byte is represented by two hexadecimal digits. + * + * Note: this is copied from {@link libcore.util.HexEncoding}. + * + * @hide + */ +public class HexEncoding { + + private static final char[] LOWER_CASE_DIGITS = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' + }; + + private static final char[] UPPER_CASE_DIGITS = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' + }; + + /** Hidden constructor to prevent instantiation. */ + private HexEncoding() {} + + /** + * Encodes the provided byte as a two-digit hexadecimal String value. + */ + public static String encodeToString(byte b, boolean upperCase) { + char[] digits = upperCase ? UPPER_CASE_DIGITS : LOWER_CASE_DIGITS; + char[] buf = new char[2]; // We always want two digits. + buf[0] = digits[(b >> 4) & 0xf]; + buf[1] = digits[b & 0xf]; + return new String(buf, 0, 2); + } + + /** + * Encodes the provided data as a sequence of hexadecimal characters. + */ + public static char[] encode(byte[] data) { + return encode(data, 0, data.length, true /* upperCase */); + } + + /** + * Encodes the provided data as a sequence of hexadecimal characters. + */ + public static char[] encode(byte[] data, boolean upperCase) { + return encode(data, 0, data.length, upperCase); + } + + /** + * Encodes the provided data as a sequence of hexadecimal characters. + */ + public static char[] encode(byte[] data, int offset, int len) { + return encode(data, offset, len, true /* upperCase */); + } + + /** + * Encodes the provided data as a sequence of hexadecimal characters. + */ + private static char[] encode(byte[] data, int offset, int len, boolean upperCase) { + char[] digits = upperCase ? UPPER_CASE_DIGITS : LOWER_CASE_DIGITS; + char[] result = new char[len * 2]; + for (int i = 0; i < len; i++) { + byte b = data[offset + i]; + int resultIndex = 2 * i; + result[resultIndex] = (digits[(b >> 4) & 0x0f]); + result[resultIndex + 1] = (digits[b & 0x0f]); + } + + return result; + } + + /** + * Encodes the provided data as a sequence of hexadecimal characters. + */ + public static String encodeToString(byte[] data) { + return encodeToString(data, true /* upperCase */); + } + + /** + * Encodes the provided data as a sequence of hexadecimal characters. + */ + public static String encodeToString(byte[] data, boolean upperCase) { + return new String(encode(data, upperCase)); + } + + /** + * Decodes the provided hexadecimal string into a byte array. Odd-length inputs + * are not allowed. + * + * Throws an {@code IllegalArgumentException} if the input is malformed. + */ + public static byte[] decode(String encoded) throws IllegalArgumentException { + return decode(encoded.toCharArray()); + } + + /** + * Decodes the provided hexadecimal string into a byte array. If {@code allowSingleChar} + * is {@code true} odd-length inputs are allowed and the first character is interpreted + * as the lower bits of the first result byte. + * + * Throws an {@code IllegalArgumentException} if the input is malformed. + */ + public static byte[] decode(String encoded, boolean allowSingleChar) + throws IllegalArgumentException { + return decode(encoded.toCharArray(), allowSingleChar); + } + + /** + * Decodes the provided hexadecimal string into a byte array. Odd-length inputs + * are not allowed. + * + * Throws an {@code IllegalArgumentException} if the input is malformed. + */ + public static byte[] decode(char[] encoded) throws IllegalArgumentException { + return decode(encoded, false); + } + + /** + * Decodes the provided hexadecimal string into a byte array. If {@code allowSingleChar} + * is {@code true} odd-length inputs are allowed and the first character is interpreted + * as the lower bits of the first result byte. + * + * Throws an {@code IllegalArgumentException} if the input is malformed. + */ + public static byte[] decode(char[] encoded, boolean allowSingleChar) + throws IllegalArgumentException { + int encodedLength = encoded.length; + int resultLengthBytes = (encodedLength + 1) / 2; + byte[] result = new byte[resultLengthBytes]; + + int resultOffset = 0; + int i = 0; + if (allowSingleChar) { + if ((encodedLength % 2) != 0) { + // Odd number of digits -- the first digit is the lower 4 bits of the first result + // byte. + result[resultOffset++] = (byte) toDigit(encoded, i); + i++; + } + } else { + if ((encodedLength % 2) != 0) { + throw new IllegalArgumentException("Invalid input length: " + encodedLength); + } + } + + for (; i < encodedLength; i += 2) { + result[resultOffset++] = (byte) ((toDigit(encoded, i) << 4) | toDigit(encoded, i + 1)); + } + + return result; + } + + private static int toDigit(char[] str, int offset) throws IllegalArgumentException { + // NOTE: that this isn't really a code point in the traditional sense, since we're + // just rejecting surrogate pairs outright. + int pseudoCodePoint = str[offset]; + + if ('0' <= pseudoCodePoint && pseudoCodePoint <= '9') { + return pseudoCodePoint - '0'; + } else if ('a' <= pseudoCodePoint && pseudoCodePoint <= 'f') { + return 10 + (pseudoCodePoint - 'a'); + } else if ('A' <= pseudoCodePoint && pseudoCodePoint <= 'F') { + return 10 + (pseudoCodePoint - 'A'); + } + + throw new IllegalArgumentException("Illegal char: " + str[offset] + " at offset " + offset); + } +} diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java index 3483ff8a4664..200c0e31cb22 100644 --- a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java +++ b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java @@ -36,6 +36,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.net.MacAddress; import android.net.wifi.RttManager; +import android.net.wifi.util.HexEncoding; import android.os.Build; import android.os.Handler; import android.os.IBinder; @@ -44,8 +45,6 @@ import android.os.test.TestLooper; import androidx.test.filters.SmallTest; -import libcore.util.HexEncoding; - import org.junit.Before; import org.junit.Rule; import org.junit.Test; diff --git a/wifi/tests/src/android/net/wifi/util/HexEncodingTest.java b/wifi/tests/src/android/net/wifi/util/HexEncodingTest.java new file mode 100644 index 000000000000..0d751389e244 --- /dev/null +++ b/wifi/tests/src/android/net/wifi/util/HexEncodingTest.java @@ -0,0 +1,130 @@ +/* + * 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.util; + +import static android.net.wifi.util.HexEncoding.decode; +import static android.net.wifi.util.HexEncoding.encode; +import static android.net.wifi.util.HexEncoding.encodeToString; + +import junit.framework.TestCase; + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Locale; + +/** Copied from {@link libcore.libcore.util.HexEncodingTest}. */ +public class HexEncodingTest extends TestCase { + + public void testEncodeByte() { + Object[][] testCases = new Object[][]{ + {0x01, "01"}, + {0x09, "09"}, + {0x0A, "0A"}, + {0x0F, "0F"}, + {0x10, "10"}, + {0x1F, "1F"}, + {0x20, "20"}, + {0x7F, "7F"}, + {0x80, "80"}, + {0xFF, "FF"}, + }; + for (Object[] testCase : testCases) { + Number toEncode = (Number) testCase[0]; + String expected = (String) testCase[1]; + + String actualUpper = encodeToString(toEncode.byteValue(), true /* upperCase */); + assertEquals(upper(expected), actualUpper); + + String actualLower = encodeToString(toEncode.byteValue(), false /* upperCase */); + assertEquals(lower(expected), actualLower); + } + } + + public void testEncodeBytes() { + Object[][] testCases = new Object[][]{ + {"avocados".getBytes(StandardCharsets.UTF_8), "61766F6361646F73"}, + }; + + for (Object[] testCase : testCases) { + byte[] bytes = (byte[]) testCase[0]; + String encodedLower = lower((String) testCase[1]); + String encodedUpper = upper((String) testCase[1]); + + assertArraysEqual(encodedUpper.toCharArray(), encode(bytes)); + assertArraysEqual(encodedUpper.toCharArray(), encode(bytes, true /* upperCase */)); + assertArraysEqual(encodedLower.toCharArray(), encode(bytes, false /* upperCase */)); + + assertArraysEqual(bytes, decode(encode(bytes), false /* allowSingleChar */)); + + // Make sure we can handle lower case hex encodings as well. + assertArraysEqual(bytes, + decode(encodedLower.toCharArray(), false /* allowSingleChar */)); + } + } + + public void testDecode_allow4Bit() { + assertArraysEqual(new byte[]{6}, decode("6".toCharArray(), true)); + assertArraysEqual(new byte[]{6, 0x76}, decode("676".toCharArray(), true)); + } + + public void testDecode_disallow4Bit() { + try { + decode("676".toCharArray(), false /* allowSingleChar */); + fail(); + } catch (IllegalArgumentException expected) { + } + } + + public void testDecode_invalid() { + try { + decode("DEADBARD".toCharArray(), false /* allowSingleChar */); + fail(); + } catch (IllegalArgumentException expected) { + } + + // This demonstrates a difference in behaviour from apache commons : apache + // commons uses Character.isDigit and would successfully decode a string with + // arabic and devanagari characters. + try { + decode("६१٧٥٥F6361646F73".toCharArray(), false /* allowSingleChar */); + fail(); + } catch (IllegalArgumentException expected) { + } + + try { + decode("#%6361646F73".toCharArray(), false /* allowSingleChar */); + fail(); + } catch (IllegalArgumentException expected) { + } + } + + private static void assertArraysEqual(char[] lhs, char[] rhs) { + assertEquals(new String(lhs), new String(rhs)); + } + + private static void assertArraysEqual(byte[] lhs, byte[] rhs) { + assertEquals(Arrays.toString(lhs), Arrays.toString(rhs)); + } + + private static String lower(String string) { + return string.toLowerCase(Locale.ROOT); + } + + private static String upper(String string) { + return string.toUpperCase(Locale.ROOT); + } +} -- cgit v1.2.3 From e4b59bcf08f13335f1f9919434ca81a3463e90ee Mon Sep 17 00:00:00 2001 From: David Su Date: Wed, 4 Dec 2019 16:32:11 -0800 Subject: WifiManager: Remove sync version of getWifiActivityEnergyInfo Remove synchronous version of getting the WifiActivityEnergyInfo since the async version is the official API. Bug: 145244073 Test: atest FrameworksWifiApiTests Change-Id: I71b21835746e6df111d994c77b0936f28a1e7394 --- wifi/java/android/net/wifi/IWifiManager.aidl | 3 --- wifi/java/android/net/wifi/WifiManager.java | 19 ------------------- .../java/com/android/server/wifi/BaseWifiService.java | 5 ++++- wifi/tests/src/android/net/wifi/WifiManagerTest.java | 12 ------------ 4 files changed, 4 insertions(+), 35 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index fccbcf7c101f..b52880e29e30 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -44,7 +44,6 @@ import android.net.wifi.WifiNetworkSuggestion; import android.os.Messenger; import android.os.ResultReceiver; import android.os.WorkSource; -import android.os.connectivity.WifiActivityEnergyInfo; /** * Interface that allows controlling and querying Wi-Fi connectivity. @@ -55,8 +54,6 @@ interface IWifiManager { long getSupportedFeatures(); - WifiActivityEnergyInfo reportActivityInfo(); - oneway void getWifiActivityEnergyInfoAsync(in IOnWifiActivityEnergyInfoListener listener); ParceledListSlice getConfiguredNetworks(String packageName, String featureId); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 0108d5aa936c..86c398b770b7 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -2378,25 +2378,6 @@ public class WifiManager { return isFeatureSupported(WIFI_FEATURE_AP_RAND_MAC); } - /** - * Return the record of {@link WifiActivityEnergyInfo} object that - * has the activity and energy info. This can be used to ascertain what - * the controller has been up to, since the last sample. - * - * @return a record with {@link WifiActivityEnergyInfo} or null if - * report is unavailable or unsupported - * @hide - */ - public WifiActivityEnergyInfo getControllerActivityEnergyInfo() { - try { - synchronized(this) { - return mService.reportActivityInfo(); - } - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - /** * Interface for Wi-Fi activity energy info listener. Should be implemented by applications and * set when calling {@link WifiManager#getWifiActivityEnergyInfoAsync}. diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index 367cfa069e74..2c27037d29aa 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -76,11 +76,14 @@ public class BaseWifiService extends IWifiManager.Stub { throw new UnsupportedOperationException(); } - @Override + /** @deprecated use {@link #getWifiActivityEnergyInfoAsync} instead */ + @Deprecated public WifiActivityEnergyInfo reportActivityInfo() { throw new UnsupportedOperationException(); } + /** @deprecated use {@link #getWifiActivityEnergyInfoAsync} instead */ + @Deprecated public void requestActivityInfo(ResultReceiver result) { throw new UnsupportedOperationException(); } diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index ac3304073809..f92d38c982b8 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -1707,18 +1707,6 @@ public class WifiManagerTest { assertFalse(mWifiManager.isEnhancedPowerReportingSupported()); } - /** - * Test behavior of {@link WifiManager#getControllerActivityEnergyInfo()} - */ - @Test - public void testGetControllerActivityEnergyInfo() throws Exception { - WifiActivityEnergyInfo activityEnergyInfo = - new WifiActivityEnergyInfo(5, 3, 3, 5, 5, 5); - when(mWifiService.reportActivityInfo()).thenReturn(activityEnergyInfo); - - assertEquals(activityEnergyInfo, mWifiManager.getControllerActivityEnergyInfo()); - } - /** * Tests that passing a null Executor to {@link WifiManager#getWifiActivityEnergyInfoAsync} * throws an exception. -- cgit v1.2.3 From f935a53508a0d7c56138754aa8e0d0728289fb38 Mon Sep 17 00:00:00 2001 From: Hugo Benichi Date: Tue, 10 Dec 2019 10:47:21 +0900 Subject: wifi: Remove deprecated aidl methods Bug: 122431221 Test: Compiled Change-Id: I7f4a1036d14f1e5feed716e1ad61521a526907ae --- wifi/java/com/android/server/wifi/BaseWifiService.java | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'wifi') diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index 534e609f9af4..23ab11a9bab1 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -513,19 +513,6 @@ public class BaseWifiService extends IWifiManager.Stub { throw new UnsupportedOperationException(); } - /** @deprecated replaced by {@link #registerScanResultsCallback(IScanResultsCallback)} */ - @Deprecated - public void registerScanResultsListener( - IBinder binder, IScanResultsListener listener, int listenerIdentifier) { - throw new UnsupportedOperationException(); - } - - /** @deprecated replaced by {@link #unregisterScanResultsCallback(IScanResultsCallback)} */ - @Deprecated - public void unregisterScanResultsListener(int listenerIdentifier) { - throw new UnsupportedOperationException(); - } - @Override public void registerScanResultsCallback(IScanResultsCallback callback) { throw new UnsupportedOperationException(); -- cgit v1.2.3 From d98deeb629dce7fc04e1dbaeed7bd87c49568e3b Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Tue, 10 Dec 2019 14:42:29 -0800 Subject: statsd: Allow wifi mainline module to log its metrics (contd) Also, stop relying on Statsd constants in WifiManager. Bug: 145821723 Test: Compiles Change-Id: Ie64b174863f5208ea9c23d500daf263bff6fc4bc --- wifi/java/android/net/wifi/WifiManager.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 86c398b770b7..50d62a0b627e 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1069,7 +1069,7 @@ public class WifiManager { * @deprecated This API is non-functional and will have no impact. */ @Deprecated - public static final int WIFI_MODE_FULL = WifiProtoEnums.WIFI_MODE_FULL; // 1 + public static final int WIFI_MODE_FULL = 1; /** * In this Wi-Fi lock mode, Wi-Fi will be kept active, @@ -1083,7 +1083,7 @@ public class WifiManager { * @deprecated This API is non-functional and will have no impact. */ @Deprecated - public static final int WIFI_MODE_SCAN_ONLY = WifiProtoEnums.WIFI_MODE_SCAN_ONLY; // 2 + public static final int WIFI_MODE_SCAN_ONLY = 2; /** * In this Wi-Fi lock mode, Wi-Fi will not go to power save. @@ -1102,7 +1102,7 @@ public class WifiManager { * When there is no support from the hardware, the {@link #WIFI_MODE_FULL_HIGH_PERF} * lock will have no impact. */ - public static final int WIFI_MODE_FULL_HIGH_PERF = WifiProtoEnums.WIFI_MODE_FULL_HIGH_PERF; // 3 + public static final int WIFI_MODE_FULL_HIGH_PERF = 3; /** * In this Wi-Fi lock mode, Wi-Fi will operate with a priority to achieve low latency. @@ -1132,8 +1132,8 @@ public class WifiManager { * lock will be effective when app is running in foreground and screen is on, * while the {@link #WIFI_MODE_FULL_HIGH_PERF} lock will take effect otherwise. */ - public static final int WIFI_MODE_FULL_LOW_LATENCY = - WifiProtoEnums.WIFI_MODE_FULL_LOW_LATENCY; // 4 + public static final int WIFI_MODE_FULL_LOW_LATENCY = 4; + /** Anything worse than or equal to this will show 0 bars. */ @UnsupportedAppUsage -- cgit v1.2.3 From 77f376fc0f0343b924e7005939f4647fcf18b6a4 Mon Sep 17 00:00:00 2001 From: David Su Date: Tue, 10 Dec 2019 22:04:13 -0800 Subject: WifiNetworAgentSpecifier - Stop importing @hide NetworkAgent NetworkAgent is @hide, only imported for JavaDoc. Remove import since once we build against @SystemApi stubs this will fail. Bug: 145409537 Test: compiles Change-Id: I569ba8bd1784c72bb5473e8bf9bb1cf93f351b77 --- wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java index 24aa23aec7ae..04d2e1a8b5dd 100644 --- a/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java +++ b/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java @@ -23,7 +23,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.net.MacAddress; import android.net.MatchAllNetworkSpecifier; -import android.net.NetworkAgent; import android.net.NetworkRequest; import android.net.NetworkSpecifier; import android.os.Parcel; @@ -120,7 +119,7 @@ public final class WifiNetworkAgentSpecifier extends NetworkSpecifier implements /** * Match {@link WifiNetworkSpecifier} in app's {@link NetworkRequest} with the - * {@link WifiNetworkAgentSpecifier} in wifi platform's {@link NetworkAgent}. + * {@link WifiNetworkAgentSpecifier} in wifi platform's {@link android.net.NetworkAgent}. */ public boolean satisfiesNetworkSpecifier(@NonNull WifiNetworkSpecifier ns) { // None of these should be null by construction. -- cgit v1.2.3 From 1c9126d3de486e3c47d7e5fe9cfb598c3a31f41e Mon Sep 17 00:00:00 2001 From: David Su Date: Tue, 10 Dec 2019 22:13:51 -0800 Subject: WifiEnterpriseConfig - Stop depending on constants from android.security.Credentials WifiEnterpriseConfig depends on @hide constants from android.security.Credentials. Since we can no longer reference @hide APIs once we compile against @SystemApi stubs, copy the constants into the Wifi module. Bug: 145409537 Test: compiles Change-Id: I0b57d622f4e0788a3fd45109ab2f12976b706087 --- .../android/net/wifi/WifiEnterpriseConfig.java | 29 ++++++++++++++++------ 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java index 449f95e8a161..66b0590511fc 100644 --- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java +++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java @@ -22,7 +22,6 @@ import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; -import android.security.Credentials; import android.text.TextUtils; import android.util.Log; @@ -93,10 +92,26 @@ public class WifiEnterpriseConfig implements Parcelable { */ public static final String ENGINE_DISABLE = "0"; + /** + * Key prefix for CA certificates. + * Note: copied from {@link android.security.Credentials#CA_CERTIFICATE} since it is @hide. + */ + private static final String CA_CERTIFICATE = "CACERT_"; + /** + * Key prefix for user certificates. + * Note: copied from {@link android.security.Credentials#USER_CERTIFICATE} since it is @hide. + */ + private static final String USER_CERTIFICATE = "USRCERT_"; + /** + * Key prefix for user private and secret keys. + * Note: copied from {@link android.security.Credentials#USER_PRIVATE_KEY} since it is @hide. + */ + private static final String USER_PRIVATE_KEY = "USRPKEY_"; + /** @hide */ - public static final String CA_CERT_PREFIX = KEYSTORE_URI + Credentials.CA_CERTIFICATE; + public static final String CA_CERT_PREFIX = KEYSTORE_URI + CA_CERTIFICATE; /** @hide */ - public static final String CLIENT_CERT_PREFIX = KEYSTORE_URI + Credentials.USER_CERTIFICATE; + public static final String CLIENT_CERT_PREFIX = KEYSTORE_URI + USER_CERTIFICATE; /** @hide */ public static final String CLIENT_CERT_KEY = "client_cert"; /** @hide */ @@ -659,7 +674,7 @@ public class WifiEnterpriseConfig implements Parcelable { if (i > 0) { sb.append(CA_CERT_ALIAS_DELIMITER); } - sb.append(encodeCaCertificateAlias(Credentials.CA_CERTIFICATE + aliases[i])); + sb.append(encodeCaCertificateAlias(CA_CERTIFICATE + aliases[i])); } setFieldValue(CA_CERT_KEY, sb.toString(), KEYSTORES_URI); } @@ -693,8 +708,8 @@ public class WifiEnterpriseConfig implements Parcelable { String[] aliases = TextUtils.split(values, CA_CERT_ALIAS_DELIMITER); for (int i = 0; i < aliases.length; i++) { aliases[i] = decodeCaCertificateAlias(aliases[i]); - if (aliases[i].startsWith(Credentials.CA_CERTIFICATE)) { - aliases[i] = aliases[i].substring(Credentials.CA_CERTIFICATE.length()); + if (aliases[i].startsWith(CA_CERTIFICATE)) { + aliases[i] = aliases[i].substring(CA_CERTIFICATE.length()); } } return aliases.length != 0 ? aliases : null; @@ -832,7 +847,7 @@ public class WifiEnterpriseConfig implements Parcelable { @SystemApi public void setClientCertificateAlias(@Nullable String alias) { setFieldValue(CLIENT_CERT_KEY, alias, CLIENT_CERT_PREFIX); - setFieldValue(PRIVATE_KEY_ID_KEY, alias, Credentials.USER_PRIVATE_KEY); + setFieldValue(PRIVATE_KEY_ID_KEY, alias, USER_PRIVATE_KEY); // Also, set engine parameters if (TextUtils.isEmpty(alias)) { setFieldValue(ENGINE_KEY, ENGINE_DISABLE); -- cgit v1.2.3 From 5f60a7a6b9398e0a5c8920bb7ca64fd0e23e7d43 Mon Sep 17 00:00:00 2001 From: lesl Date: Tue, 10 Dec 2019 15:45:00 +0800 Subject: wifi: Return SoftApConfiguration for cloud restore. Restore process might need to notify user because restored ap configuration requires the band conversion. Bug: 142752869 Test: frameworks/base/wifi/tests/ Change-Id: I409a4533f8feccc888f4b605fb9466e3be0b2e89 --- wifi/java/android/net/wifi/IWifiManager.aidl | 2 +- wifi/java/android/net/wifi/WifiManager.java | 15 ++++++++++----- wifi/java/com/android/server/wifi/BaseWifiService.java | 3 +-- 3 files changed, 12 insertions(+), 8 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index b52880e29e30..46efdd6f6aeb 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -186,7 +186,7 @@ interface IWifiManager byte[] retrieveSoftApBackupData(); - void restoreSoftApBackupData(in byte[] data); + SoftApConfiguration restoreSoftApBackupData(in byte[] data); void restoreSupplicantBackupData(in byte[] supplicantData, in byte[] ipConfigData); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 50d62a0b627e..3bcad2f87583 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -4686,10 +4686,13 @@ public class WifiManager { } /** - * Retrieve the soft ap config data to be backed to save current config data. + * Returns a byte stream representing the data that needs to be backed up to save the + * current soft ap config data. + * + * This soft ap config can be restored by calling {@link #restoreSoftApBackupData(byte[])} * @hide */ - @Nullable + @NonNull @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public byte[] retrieveSoftApBackupData() { @@ -4701,15 +4704,17 @@ public class WifiManager { } /** - * Restore soft ap config from the backed up data. + * Returns soft ap config from the backed up data. + * @param data byte stream in the same format produced by {@link #retrieveSoftApBackupData()} + * * @hide */ @Nullable @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - public void restoreSoftApBackupData(@NonNull byte[] data) { + public SoftApConfiguration restoreSoftApBackupData(@NonNull byte[] data) { try { - mService.restoreSoftApBackupData(data); + return mService.restoreSoftApBackupData(data); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index 524a53c03305..86392fa1b047 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -28,7 +28,6 @@ import android.net.wifi.INetworkRequestMatchCallback; import android.net.wifi.IOnWifiActivityEnergyInfoListener; import android.net.wifi.IOnWifiUsabilityStatsListener; import android.net.wifi.IScanResultsCallback; -import android.net.wifi.IScanResultsListener; import android.net.wifi.ISoftApCallback; import android.net.wifi.ISuggestionConnectionStatusListener; import android.net.wifi.ITrafficStateCallback; @@ -414,7 +413,7 @@ public class BaseWifiService extends IWifiManager.Stub { } @Override - public void restoreSoftApBackupData(byte[] data) { + public SoftApConfiguration restoreSoftApBackupData(byte[] data) { throw new UnsupportedOperationException(); } -- cgit v1.2.3 From b4345078132d2d227b3f891aa8fa0ecdc772076d Mon Sep 17 00:00:00 2001 From: David Su Date: Mon, 9 Dec 2019 17:47:45 -0800 Subject: Migrate to public version of CloseGuard Migrate to android.util.CloseGuard, which was exposed as a public API. Bug: 145831809 Test: atest FrameworksWifiApiTests Change-Id: I822cc2c080adb6902f2843e29204e71573d682ab --- wifi/java/android/net/wifi/WifiManager.java | 12 ++++++++---- wifi/java/android/net/wifi/aware/DiscoverySession.java | 7 ++++--- wifi/java/android/net/wifi/aware/WifiAwareSession.java | 7 ++++--- wifi/java/android/net/wifi/p2p/WifiP2pManager.java | 7 ++++--- 4 files changed, 20 insertions(+), 13 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 50d62a0b627e..250e94fe0e5e 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -51,16 +51,16 @@ import android.os.RemoteException; import android.os.WorkSource; import android.os.connectivity.WifiActivityEnergyInfo; import android.text.TextUtils; +import android.util.CloseGuard; import android.util.Log; import android.util.Pair; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; -import dalvik.system.CloseGuard; - import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.lang.ref.Reference; import java.lang.ref.WeakReference; import java.net.InetAddress; import java.util.ArrayList; @@ -3574,7 +3574,7 @@ public class WifiManager { */ public class LocalOnlyHotspotReservation implements AutoCloseable { - private final CloseGuard mCloseGuard = CloseGuard.get(); + private final CloseGuard mCloseGuard = new CloseGuard(); private final WifiConfiguration mConfig; private boolean mClosed = false; @@ -3601,6 +3601,8 @@ public class WifiManager { } } catch (Exception e) { Log.e(TAG, "Failed to stop Local Only Hotspot."); + } finally { + Reference.reachabilityFence(this); } } @@ -3725,7 +3727,7 @@ public class WifiManager { * @hide */ public class LocalOnlyHotspotSubscription implements AutoCloseable { - private final CloseGuard mCloseGuard = CloseGuard.get(); + private final CloseGuard mCloseGuard = new CloseGuard(); /** @hide */ @VisibleForTesting @@ -3740,6 +3742,8 @@ public class WifiManager { mCloseGuard.close(); } catch (Exception e) { Log.e(TAG, "Failed to unregister LocalOnlyHotspotObserver."); + } finally { + Reference.reachabilityFence(this); } } diff --git a/wifi/java/android/net/wifi/aware/DiscoverySession.java b/wifi/java/android/net/wifi/aware/DiscoverySession.java index d97f6fb02ac6..4d92ae174e6d 100644 --- a/wifi/java/android/net/wifi/aware/DiscoverySession.java +++ b/wifi/java/android/net/wifi/aware/DiscoverySession.java @@ -20,12 +20,12 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.net.NetworkSpecifier; +import android.util.CloseGuard; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; -import dalvik.system.CloseGuard; - +import java.lang.ref.Reference; import java.lang.ref.WeakReference; /** @@ -58,7 +58,7 @@ public class DiscoverySession implements AutoCloseable { /** @hide */ protected boolean mTerminated = false; - private final CloseGuard mCloseGuard = CloseGuard.get(); + private final CloseGuard mCloseGuard = new CloseGuard(); /** * Return the maximum permitted retry count when sending messages using @@ -108,6 +108,7 @@ public class DiscoverySession implements AutoCloseable { mTerminated = true; mMgr.clear(); mCloseGuard.close(); + Reference.reachabilityFence(this); } /** diff --git a/wifi/java/android/net/wifi/aware/WifiAwareSession.java b/wifi/java/android/net/wifi/aware/WifiAwareSession.java index 3c9781323c07..fe0872caf5f8 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareSession.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareSession.java @@ -23,12 +23,12 @@ import android.net.NetworkSpecifier; import android.os.Binder; import android.os.Handler; import android.os.Looper; +import android.util.CloseGuard; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; -import dalvik.system.CloseGuard; - +import java.lang.ref.Reference; import java.lang.ref.WeakReference; /** @@ -45,7 +45,7 @@ public class WifiAwareSession implements AutoCloseable { private final int mClientId; private boolean mTerminated = true; - private final CloseGuard mCloseGuard = CloseGuard.get(); + private final CloseGuard mCloseGuard = new CloseGuard(); /** @hide */ public WifiAwareSession(WifiAwareManager manager, Binder binder, int clientId) { @@ -80,6 +80,7 @@ public class WifiAwareSession implements AutoCloseable { mTerminated = true; mMgr.clear(); mCloseGuard.close(); + Reference.reachabilityFence(this); } /** @hide */ diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java index 1c2067980a79..6120e4e8a23a 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java @@ -44,15 +44,15 @@ import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.text.TextUtils; +import android.util.CloseGuard; import android.util.Log; import com.android.internal.util.AsyncChannel; import com.android.internal.util.Protocol; -import dalvik.system.CloseGuard; - import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.lang.ref.Reference; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -869,7 +869,7 @@ public class WifiP2pManager { private final Object mListenerMapLock = new Object(); private int mListenerKey = 0; - private final CloseGuard mCloseGuard = CloseGuard.get(); + private final CloseGuard mCloseGuard = new CloseGuard(); /** * Close the current P2P connection and indicate to the P2P service that connections @@ -888,6 +888,7 @@ public class WifiP2pManager { mAsyncChannel.disconnect(); mCloseGuard.close(); + Reference.reachabilityFence(this); } /** @hide */ -- cgit v1.2.3 From 9f8d8061ab30c2118c77e43a756d8bd3ad81232c Mon Sep 17 00:00:00 2001 From: Ahmed ElArabawy Date: Mon, 9 Dec 2019 16:16:51 -0800 Subject: Wifi: Replace dual_band with 5GHz band support As part of the support of the 6GHz band, the concept of dual-band is no longer valid since we have more than 2 bands supported by Android and can be checked on the device. This commit replaces checks on dual-band support with an explicit check on 5GHz band support. This commit also removes the feature flags of 5GHz/6GHz support, since these capabilities will be read from the overlay configs. Bug: 145936758 Bug: 139354972 Test: Manual Change-Id: I223ed2bc88c01f561d31abce4e2c91aa62da186f Merged-In: I223ed2bc88c01f561d31abce4e2c91aa62da186f --- wifi/java/android/net/wifi/IWifiManager.aidl | 4 +- wifi/java/android/net/wifi/WifiManager.java | 60 +++++++++------------- .../com/android/server/wifi/BaseWifiService.java | 14 ++++- .../src/android/net/wifi/WifiManagerTest.java | 22 +++++--- 4 files changed, 55 insertions(+), 45 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index b52880e29e30..0a1254de269d 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -108,7 +108,9 @@ interface IWifiManager String getCountryCode(); - boolean isDualBandSupported(); + boolean is5GHzBandSupported(); + + boolean is6GHzBandSupported(); boolean needs5GHzToAnyApBandConversion(); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 50d62a0b627e..295e05e71825 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -2156,8 +2156,6 @@ public class WifiManager { /** @hide */ public static final long WIFI_FEATURE_INFRA = 0x0001L; // Basic infrastructure mode /** @hide */ - public static final long WIFI_FEATURE_INFRA_5G = 0x0002L; // Support for 5 GHz Band - /** @hide */ public static final long WIFI_FEATURE_PASSPOINT = 0x0004L; // Support for GAS/ANQP /** @hide */ public static final long WIFI_FEATURE_P2P = 0x0008L; // Wifi-Direct @@ -2227,8 +2225,6 @@ public class WifiManager { public static final long WIFI_FEATURE_MBO = 0x800000000L; // MBO Support /** @hide */ public static final long WIFI_FEATURE_OCE = 0x1000000000L; // OCE Support - /** @hide */ - public static final long WIFI_FEATURE_INFRA_6G = 0x2000000000L; // Support 6 GHz band private long getSupportedFeatures() { try { @@ -2242,22 +2238,7 @@ public class WifiManager { return (getSupportedFeatures() & feature) == feature; } - /** - * @return true if this adapter supports 5 GHz band - */ - public boolean is5GHzBandSupported() { - return isFeatureSupported(WIFI_FEATURE_INFRA_5G); - } - - /** - * @return true if the device supports operating in the 6 GHz band and Wi-Fi is enabled, - * false otherwise. - */ - public boolean is6GHzBandSupported() { - return isFeatureSupported(WIFI_FEATURE_INFRA_6G); - } - - /** + /** * @return true if this adapter supports Passpoint * @hide */ @@ -2378,6 +2359,30 @@ public class WifiManager { return isFeatureSupported(WIFI_FEATURE_AP_RAND_MAC); } + /** + * Check if the chipset supports 5GHz band. + * @return {@code true} if supported, {@code false} otherwise. + */ + public boolean is5GHzBandSupported() { + try { + return mService.is5GHzBandSupported(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Check if the chipset supports 6GHz band. + * @return {@code true} if supported, {@code false} otherwise. + */ + public boolean is6GHzBandSupported() { + try { + return mService.is6GHzBandSupported(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Interface for Wi-Fi activity energy info listener. Should be implemented by applications and * set when calling {@link WifiManager#getWifiActivityEnergyInfoAsync}. @@ -2591,21 +2596,6 @@ public class WifiManager { } } - /** - * Check if the chipset supports dual frequency band (2.4 GHz and 5 GHz). - * No permissions are required to call this method. - * @return {@code true} if supported, {@code false} otherwise. - * @hide - */ - @SystemApi - public boolean isDualBandSupported() { - try { - return mService.isDualBandSupported(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - /** * Check if the device is dual mode capable i.e. supports concurrent STA + Soft AP. * diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index 524a53c03305..48f57b82b3e9 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -28,7 +28,6 @@ import android.net.wifi.INetworkRequestMatchCallback; import android.net.wifi.IOnWifiActivityEnergyInfoListener; import android.net.wifi.IOnWifiUsabilityStatsListener; import android.net.wifi.IScanResultsCallback; -import android.net.wifi.IScanResultsListener; import android.net.wifi.ISoftApCallback; import android.net.wifi.ISuggestionConnectionStatusListener; import android.net.wifi.ITrafficStateCallback; @@ -227,11 +226,22 @@ public class BaseWifiService extends IWifiManager.Stub { throw new UnsupportedOperationException(); } - @Override + /** @deprecated use {@link #is5GHzBandSupported} instead */ + @Deprecated public boolean isDualBandSupported() { throw new UnsupportedOperationException(); } + @Override + public boolean is5GHzBandSupported() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean is6GHzBandSupported() { + throw new UnsupportedOperationException(); + } + @Override public boolean needs5GHzToAnyApBandConversion() { throw new UnsupportedOperationException(); diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index f92d38c982b8..62ff9f65a1a7 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -1696,8 +1696,6 @@ public class WifiManagerTest { assertTrue(mWifiManager.isPasspointSupported()); assertTrue(mWifiManager.isP2pSupported()); assertFalse(mWifiManager.isPortableHotspotSupported()); - assertFalse(mWifiManager.is5GHzBandSupported()); - assertFalse(mWifiManager.is6GHzBandSupported()); assertFalse(mWifiManager.isDeviceToDeviceRttSupported()); assertFalse(mWifiManager.isDeviceToApRttSupported()); assertFalse(mWifiManager.isPreferredNetworkOffloadSupported()); @@ -1782,13 +1780,23 @@ public class WifiManagerTest { } /** - * Test behavior of {@link WifiManager#isDualBandSupported()} + * Test behavior of {@link WifiManager#is5GHzBandSupported()} */ @Test - public void testIsDualBandSupported() throws Exception { - when(mWifiService.isDualBandSupported()).thenReturn(true); - assertTrue(mWifiManager.isDualBandSupported()); - verify(mWifiService).isDualBandSupported(); + public void testIs5GHzBandSupported() throws Exception { + when(mWifiService.is5GHzBandSupported()).thenReturn(true); + assertTrue(mWifiManager.is5GHzBandSupported()); + verify(mWifiService).is5GHzBandSupported(); + } + + /** + * Test behavior of {@link WifiManager#is6GHzBandSupported()} + */ + @Test + public void testIs6GHzBandSupported() throws Exception { + when(mWifiService.is6GHzBandSupported()).thenReturn(true); + assertTrue(mWifiManager.is6GHzBandSupported()); + verify(mWifiService).is6GHzBandSupported(); } /** -- cgit v1.2.3 From 73450f20041295c8bf58a9a366bbcf017b6f4498 Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Thu, 12 Dec 2019 23:29:25 -0800 Subject: Wificond: transfer implementation to android.net.wifi Move implementation of wificond to frameworks/base (android.net.wifi) in prepration for making into a public API (which will be a wrapper around the AIDL). Bug: 140062898 Test: atest com.android.server.wifi Test: atest android.net.wifi Test: associates, soft AP client information received correctly Change-Id: I3c5ede95d0421a1e00078e0316e9a2e751156f3e --- wifi/java/android/net/wifi/WifiCondManager.java | 983 +++++++++++++++ .../android/net/wifi/wificond/ChannelSettings.java | 95 ++ .../android/net/wifi/wificond/HiddenNetwork.java | 87 ++ .../net/wifi/wificond/NativeScanResult.java | 115 ++ .../net/wifi/wificond/NativeWifiClient.java | 82 ++ .../java/android/net/wifi/wificond/PnoNetwork.java | 95 ++ .../android/net/wifi/wificond/PnoSettings.java | 105 ++ .../android/net/wifi/wificond/RadioChainInfo.java | 100 ++ .../net/wifi/wificond/SingleScanSettings.java | 119 ++ .../src/android/net/wifi/WifiCondManagerTest.java | 1281 ++++++++++++++++++++ .../net/wifi/wificond/NativeScanResultTest.java | 88 ++ .../android/net/wifi/wificond/PnoSettingsTest.java | 112 ++ .../net/wifi/wificond/SingleScanSettingsTest.java | 117 ++ 13 files changed, 3379 insertions(+) create mode 100644 wifi/java/android/net/wifi/WifiCondManager.java create mode 100644 wifi/java/android/net/wifi/wificond/ChannelSettings.java create mode 100644 wifi/java/android/net/wifi/wificond/HiddenNetwork.java create mode 100644 wifi/java/android/net/wifi/wificond/NativeScanResult.java create mode 100644 wifi/java/android/net/wifi/wificond/NativeWifiClient.java create mode 100644 wifi/java/android/net/wifi/wificond/PnoNetwork.java create mode 100644 wifi/java/android/net/wifi/wificond/PnoSettings.java create mode 100644 wifi/java/android/net/wifi/wificond/RadioChainInfo.java create mode 100644 wifi/java/android/net/wifi/wificond/SingleScanSettings.java create mode 100644 wifi/tests/src/android/net/wifi/WifiCondManagerTest.java create mode 100644 wifi/tests/src/android/net/wifi/wificond/NativeScanResultTest.java create mode 100644 wifi/tests/src/android/net/wifi/wificond/PnoSettingsTest.java create mode 100644 wifi/tests/src/android/net/wifi/wificond/SingleScanSettingsTest.java (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiCondManager.java b/wifi/java/android/net/wifi/WifiCondManager.java new file mode 100644 index 000000000000..9ae7e3a89706 --- /dev/null +++ b/wifi/java/android/net/wifi/WifiCondManager.java @@ -0,0 +1,983 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi; + +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.app.AlarmManager; +import android.content.Context; +import android.net.wifi.wificond.ChannelSettings; +import android.net.wifi.wificond.HiddenNetwork; +import android.net.wifi.wificond.NativeScanResult; +import android.net.wifi.wificond.NativeWifiClient; +import android.net.wifi.wificond.PnoSettings; +import android.net.wifi.wificond.SingleScanSettings; +import android.os.Binder; +import android.os.Handler; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.os.SystemClock; +import android.util.Log; + +import com.android.internal.annotations.VisibleForTesting; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * This class provides methods for WifiNative to send control commands to wificond. + * NOTE: This class should only be used from WifiNative. + * @hide + */ +public class WifiCondManager implements IBinder.DeathRecipient { + private static final String TAG = "WifiCondManager"; + private boolean mVerboseLoggingEnabled = false; + + /** + * The {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int) sendMgmtFrame()} + * timeout, in milliseconds, after which + * {@link SendMgmtFrameCallback#onFailure(int)} will be called with reason + * {@link #SEND_MGMT_FRAME_ERROR_TIMEOUT}. + */ + public static final int SEND_MGMT_FRAME_TIMEOUT_MS = 1000; + + private static final String TIMEOUT_ALARM_TAG = TAG + " Send Management Frame Timeout"; + + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"SCAN_TYPE_"}, + value = {SCAN_TYPE_SINGLE_SCAN, + SCAN_TYPE_PNO_SCAN}) + public @interface ScanResultType {} + + /** Get scan results for a single scan */ + public static final int SCAN_TYPE_SINGLE_SCAN = 0; + + /** Get scan results for Pno Scan */ + public static final int SCAN_TYPE_PNO_SCAN = 1; + + private AlarmManager mAlarmManager; + private Handler mEventHandler; + + // Cached wificond binder handlers. + private IWificond mWificond; + private HashMap mClientInterfaces = new HashMap<>(); + private HashMap mApInterfaces = new HashMap<>(); + private HashMap mWificondScanners = new HashMap<>(); + private HashMap mScanEventHandlers = new HashMap<>(); + private HashMap mPnoScanEventHandlers = new HashMap<>(); + private HashMap mApInterfaceListeners = new HashMap<>(); + private Runnable mDeathEventHandler; + /** + * Ensures that no more than one sendMgmtFrame operation runs concurrently. + */ + private AtomicBoolean mSendMgmtFrameInProgress = new AtomicBoolean(false); + + /** + * Interface for a callback to be used to handle scan results. + */ + public interface ScanEventCallback { + /** + * Called when scan results are available. + */ + void onScanResultReady(); + + /** + * Called when a scan has failed. + */ + void onScanFailed(); + } + + /** + * Interface for a callback to provide information about PNO scan request. + */ + public interface PnoScanRequestCallback { + /** + * Called when the PNO scan is requested. + */ + void onPnoRequestSucceeded(); + + /** + * Called when a PNO scan request fails. + */ + void onPnoRequestFailed(); + } + + private class ScanEventHandler extends IScanEvent.Stub { + private ScanEventCallback mCallback; + + ScanEventHandler(@NonNull ScanEventCallback callback) { + mCallback = callback; + } + + @Override + public void OnScanResultReady() { + Log.d(TAG, "Scan result ready event"); + mCallback.onScanResultReady(); + } + + @Override + public void OnScanFailed() { + Log.d(TAG, "Scan failed event"); + mCallback.onScanFailed(); + } + } + + /** + * Result of a signal poll. + */ + public static class SignalPollResult { + // RSSI value in dBM. + public int currentRssi; + //Transmission bit rate in Mbps. + public int txBitrate; + // Association frequency in MHz. + public int associationFrequency; + //Last received packet bit rate in Mbps. + public int rxBitrate; + } + + /** + * WiFi interface transimission counters. + */ + public static class TxPacketCounters { + // Number of successfully transmitted packets. + public int txSucceeded; + // Number of tramsmission failures. + public int txFailed; + } + + /** + * Callbacks for SoftAp interface. + */ + public interface SoftApListener { + /** + * Invoked when there is some fatal failure in the lower layers. + */ + void onFailure(); + + /** + * Invoked when the associated stations changes. + */ + void onConnectedClientsChanged(NativeWifiClient client, boolean isConnected); + + /** + * Invoked when the channel switch event happens. + */ + void onSoftApChannelSwitched(int frequency, int bandwidth); + } + + /** + * Callback to notify the results of a + * {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int) sendMgmtFrame()} call. + * Note: no callbacks will be triggered if the iface dies while sending a frame. + */ + public interface SendMgmtFrameCallback { + /** + * Called when the management frame was successfully sent and ACKed by the recipient. + * @param elapsedTimeMs The elapsed time between when the management frame was sent and when + * the ACK was processed, in milliseconds, as measured by wificond. + * This includes the time that the send frame spent queuing before it + * was sent, any firmware retries, and the time the received ACK spent + * queuing before it was processed. + */ + void onAck(int elapsedTimeMs); + + /** + * Called when the send failed. + * @param reason The error code for the failure. + */ + void onFailure(@SendMgmtFrameError int reason); + } + + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"SEND_MGMT_FRAME_ERROR_"}, + value = {SEND_MGMT_FRAME_ERROR_UNKNOWN, + SEND_MGMT_FRAME_ERROR_MCS_UNSUPPORTED, + SEND_MGMT_FRAME_ERROR_NO_ACK, + SEND_MGMT_FRAME_ERROR_TIMEOUT, + SEND_MGMT_FRAME_ERROR_ALREADY_STARTED}) + public @interface SendMgmtFrameError {} + + // Send management frame error codes + + /** + * Unknown error occurred during call to + * {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int) sendMgmtFrame()}. + */ + public static final int SEND_MGMT_FRAME_ERROR_UNKNOWN = 1; + + /** + * Specifying the MCS rate in + * {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int) sendMgmtFrame()} is not + * supported by this device. + */ + public static final int SEND_MGMT_FRAME_ERROR_MCS_UNSUPPORTED = 2; + + /** + * Driver reported that no ACK was received for the frame transmitted using + * {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int) sendMgmtFrame()}. + */ + public static final int SEND_MGMT_FRAME_ERROR_NO_ACK = 3; + + /** + * Error code for when the driver fails to report on the status of the frame sent by + * {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int) sendMgmtFrame()} + * after {@link #SEND_MGMT_FRAME_TIMEOUT_MS} milliseconds. + */ + public static final int SEND_MGMT_FRAME_ERROR_TIMEOUT = 4; + + /** + * An existing call to + * {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int) sendMgmtFrame()} + * is in progress. Another frame cannot be sent until the first call completes. + */ + public static final int SEND_MGMT_FRAME_ERROR_ALREADY_STARTED = 5; + + + public WifiCondManager(Context context) { + mAlarmManager = (AlarmManager) context.getSystemService(AlarmManager.class); + mEventHandler = new Handler(context.getMainLooper()); + } + + @VisibleForTesting + public WifiCondManager(Context context, IWificond wificond) { + this(context); + mWificond = wificond; + } + + private class PnoScanEventHandler extends IPnoScanEvent.Stub { + private ScanEventCallback mCallback; + + PnoScanEventHandler(@NonNull ScanEventCallback callback) { + mCallback = callback; + } + + @Override + public void OnPnoNetworkFound() { + Log.d(TAG, "Pno scan result event"); + mCallback.onScanResultReady(); + } + + @Override + public void OnPnoScanFailed() { + Log.d(TAG, "Pno Scan failed event"); + mCallback.onScanFailed(); + } + } + + /** + * Listener for AP Interface events. + */ + private class ApInterfaceEventCallback extends IApInterfaceEventCallback.Stub { + private SoftApListener mSoftApListener; + + ApInterfaceEventCallback(SoftApListener listener) { + mSoftApListener = listener; + } + + @Override + public void onConnectedClientsChanged(NativeWifiClient client, boolean isConnected) { + if (mVerboseLoggingEnabled) { + Log.d(TAG, "onConnectedClientsChanged called with " + + client.macAddress + " isConnected: " + isConnected); + } + + mSoftApListener.onConnectedClientsChanged(client, isConnected); + } + + @Override + public void onSoftApChannelSwitched(int frequency, int bandwidth) { + mSoftApListener.onSoftApChannelSwitched(frequency, bandwidth); + } + } + + /** + * Callback triggered by wificond. + */ + private class SendMgmtFrameEvent extends ISendMgmtFrameEvent.Stub { + private SendMgmtFrameCallback mCallback; + private AlarmManager.OnAlarmListener mTimeoutCallback; + /** + * ensures that mCallback is only called once + */ + private boolean mWasCalled; + + private void runIfFirstCall(Runnable r) { + if (mWasCalled) return; + mWasCalled = true; + + mSendMgmtFrameInProgress.set(false); + r.run(); + } + + SendMgmtFrameEvent(@NonNull SendMgmtFrameCallback callback) { + mCallback = callback; + // called in main thread + mTimeoutCallback = () -> runIfFirstCall(() -> { + if (mVerboseLoggingEnabled) { + Log.e(TAG, "Timed out waiting for ACK"); + } + mCallback.onFailure(SEND_MGMT_FRAME_ERROR_TIMEOUT); + }); + mWasCalled = false; + + mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, + SystemClock.elapsedRealtime() + SEND_MGMT_FRAME_TIMEOUT_MS, + TIMEOUT_ALARM_TAG, mTimeoutCallback, mEventHandler); + } + + // called in binder thread + @Override + public void OnAck(int elapsedTimeMs) { + // post to main thread + mEventHandler.post(() -> runIfFirstCall(() -> { + mAlarmManager.cancel(mTimeoutCallback); + mCallback.onAck(elapsedTimeMs); + })); + } + + // called in binder thread + @Override + public void OnFailure(int reason) { + // post to main thread + mEventHandler.post(() -> runIfFirstCall(() -> { + mAlarmManager.cancel(mTimeoutCallback); + mCallback.onFailure(reason); + })); + } + } + + /** + * Called by the binder subsystem upon remote object death. + * Invoke all the register death handlers and clear state. + */ + @Override + public void binderDied() { + mEventHandler.post(() -> { + Log.e(TAG, "Wificond died!"); + clearState(); + // Invalidate the global wificond handle on death. Will be refreshed + // on the next setup call. + mWificond = null; + if (mDeathEventHandler != null) { + mDeathEventHandler.run(); + } + }); + } + + /** Enable or disable verbose logging of WificondControl. + * @param enable True to enable verbose logging. False to disable verbose logging. + */ + public void enableVerboseLogging(boolean enable) { + mVerboseLoggingEnabled = enable; + } + + /** + * Initializes wificond & registers a death notification for wificond. + * This method clears any existing state in wificond daemon. + * + * @return Returns true on success. + */ + public boolean initialize(@NonNull Runnable deathEventHandler) { + if (mDeathEventHandler != null) { + Log.e(TAG, "Death handler already present"); + } + mDeathEventHandler = deathEventHandler; + tearDownInterfaces(); + return true; + } + + /** + * Helper method to retrieve the global wificond handle and register for + * death notifications. + */ + private boolean retrieveWificondAndRegisterForDeath() { + if (mWificond != null) { + if (mVerboseLoggingEnabled) { + Log.d(TAG, "Wificond handle already retrieved"); + } + // We already have a wificond handle. + return true; + } + IBinder binder = ServiceManager.getService(Context.WIFI_COND_SERVICE); + mWificond = IWificond.Stub.asInterface(binder); + if (mWificond == null) { + Log.e(TAG, "Failed to get reference to wificond"); + return false; + } + try { + mWificond.asBinder().linkToDeath(this, 0); + } catch (RemoteException e) { + Log.e(TAG, "Failed to register death notification for wificond"); + // The remote has already died. + return false; + } + return true; + } + + /** + * Setup interface for client mode via wificond. + * @return true on success. + */ + public boolean setupInterfaceForClientMode(@NonNull String ifaceName, + @NonNull ScanEventCallback scanCallback, @NonNull ScanEventCallback pnoScanCallback) { + Log.d(TAG, "Setting up interface for client mode"); + if (!retrieveWificondAndRegisterForDeath()) { + return false; + } + + IClientInterface clientInterface = null; + try { + clientInterface = mWificond.createClientInterface(ifaceName); + } catch (RemoteException e1) { + Log.e(TAG, "Failed to get IClientInterface due to remote exception"); + return false; + } + + if (clientInterface == null) { + Log.e(TAG, "Could not get IClientInterface instance from wificond"); + return false; + } + Binder.allowBlocking(clientInterface.asBinder()); + + // Refresh Handlers + mClientInterfaces.put(ifaceName, clientInterface); + try { + IWifiScannerImpl wificondScanner = clientInterface.getWifiScannerImpl(); + if (wificondScanner == null) { + Log.e(TAG, "Failed to get WificondScannerImpl"); + return false; + } + mWificondScanners.put(ifaceName, wificondScanner); + Binder.allowBlocking(wificondScanner.asBinder()); + ScanEventHandler scanEventHandler = new ScanEventHandler(scanCallback); + mScanEventHandlers.put(ifaceName, scanEventHandler); + wificondScanner.subscribeScanEvents(scanEventHandler); + PnoScanEventHandler pnoScanEventHandler = new PnoScanEventHandler(pnoScanCallback); + mPnoScanEventHandlers.put(ifaceName, pnoScanEventHandler); + wificondScanner.subscribePnoScanEvents(pnoScanEventHandler); + } catch (RemoteException e) { + Log.e(TAG, "Failed to refresh wificond scanner due to remote exception"); + } + + return true; + } + + /** + * Teardown a specific STA interface configured in wificond. + * + * @return Returns true on success. + */ + public boolean tearDownClientInterface(@NonNull String ifaceName) { + if (getClientInterface(ifaceName) == null) { + Log.e(TAG, "No valid wificond client interface handler"); + return false; + } + try { + IWifiScannerImpl scannerImpl = mWificondScanners.get(ifaceName); + if (scannerImpl != null) { + scannerImpl.unsubscribeScanEvents(); + scannerImpl.unsubscribePnoScanEvents(); + } + } catch (RemoteException e) { + Log.e(TAG, "Failed to unsubscribe wificond scanner due to remote exception"); + return false; + } + + if (mWificond == null) { + Log.e(TAG, "Reference to wifiCond is null"); + return false; + } + + boolean success; + try { + success = mWificond.tearDownClientInterface(ifaceName); + } catch (RemoteException e1) { + Log.e(TAG, "Failed to teardown client interface due to remote exception"); + return false; + } + if (!success) { + Log.e(TAG, "Failed to teardown client interface"); + return false; + } + + mClientInterfaces.remove(ifaceName); + mWificondScanners.remove(ifaceName); + mScanEventHandlers.remove(ifaceName); + mPnoScanEventHandlers.remove(ifaceName); + return true; + } + + /** + * Setup interface for softAp mode via wificond. + * @return true on success. + */ + public boolean setupInterfaceForSoftApMode(@NonNull String ifaceName) { + Log.d(TAG, "Setting up interface for soft ap mode"); + if (!retrieveWificondAndRegisterForDeath()) { + return false; + } + + IApInterface apInterface = null; + try { + apInterface = mWificond.createApInterface(ifaceName); + } catch (RemoteException e1) { + Log.e(TAG, "Failed to get IApInterface due to remote exception"); + return false; + } + + if (apInterface == null) { + Log.e(TAG, "Could not get IApInterface instance from wificond"); + return false; + } + Binder.allowBlocking(apInterface.asBinder()); + + // Refresh Handlers + mApInterfaces.put(ifaceName, apInterface); + return true; + } + + /** + * Teardown a specific AP interface configured in wificond. + * + * @return Returns true on success. + */ + public boolean tearDownSoftApInterface(@NonNull String ifaceName) { + if (getApInterface(ifaceName) == null) { + Log.e(TAG, "No valid wificond ap interface handler"); + return false; + } + + if (mWificond == null) { + Log.e(TAG, "Reference to wifiCond is null"); + return false; + } + + boolean success; + try { + success = mWificond.tearDownApInterface(ifaceName); + } catch (RemoteException e1) { + Log.e(TAG, "Failed to teardown AP interface due to remote exception"); + return false; + } + if (!success) { + Log.e(TAG, "Failed to teardown AP interface"); + return false; + } + mApInterfaces.remove(ifaceName); + mApInterfaceListeners.remove(ifaceName); + return true; + } + + /** + * Teardown all interfaces configured in wificond. + * @return Returns true on success. + */ + public boolean tearDownInterfaces() { + Log.d(TAG, "tearing down interfaces in wificond"); + // Explicitly refresh the wificodn handler because |tearDownInterfaces()| + // could be used to cleanup before we setup any interfaces. + if (!retrieveWificondAndRegisterForDeath()) { + return false; + } + + try { + for (Map.Entry entry : mWificondScanners.entrySet()) { + entry.getValue().unsubscribeScanEvents(); + entry.getValue().unsubscribePnoScanEvents(); + } + mWificond.tearDownInterfaces(); + clearState(); + return true; + } catch (RemoteException e) { + Log.e(TAG, "Failed to tear down interfaces due to remote exception"); + } + + return false; + } + + /** Helper function to look up the interface handle using name */ + private IClientInterface getClientInterface(@NonNull String ifaceName) { + return mClientInterfaces.get(ifaceName); + } + + /** + * Request signal polling to wificond. + * @param ifaceName Name of the interface. + * Returns an SignalPollResult object. + * Returns null on failure. + */ + public SignalPollResult signalPoll(@NonNull String ifaceName) { + IClientInterface iface = getClientInterface(ifaceName); + if (iface == null) { + Log.e(TAG, "No valid wificond client interface handler"); + return null; + } + + int[] resultArray; + try { + resultArray = iface.signalPoll(); + if (resultArray == null || resultArray.length != 4) { + Log.e(TAG, "Invalid signal poll result from wificond"); + return null; + } + } catch (RemoteException e) { + Log.e(TAG, "Failed to do signal polling due to remote exception"); + return null; + } + SignalPollResult pollResult = new SignalPollResult(); + pollResult.currentRssi = resultArray[0]; + pollResult.txBitrate = resultArray[1]; + pollResult.associationFrequency = resultArray[2]; + pollResult.rxBitrate = resultArray[3]; + return pollResult; + } + + /** + * Fetch TX packet counters on current connection from wificond. + * @param ifaceName Name of the interface. + * Returns an TxPacketCounters object. + * Returns null on failure. + */ + public TxPacketCounters getTxPacketCounters(@NonNull String ifaceName) { + IClientInterface iface = getClientInterface(ifaceName); + if (iface == null) { + Log.e(TAG, "No valid wificond client interface handler"); + return null; + } + + int[] resultArray; + try { + resultArray = iface.getPacketCounters(); + if (resultArray == null || resultArray.length != 2) { + Log.e(TAG, "Invalid signal poll result from wificond"); + return null; + } + } catch (RemoteException e) { + Log.e(TAG, "Failed to do signal polling due to remote exception"); + return null; + } + TxPacketCounters counters = new TxPacketCounters(); + counters.txSucceeded = resultArray[0]; + counters.txFailed = resultArray[1]; + return counters; + } + + /** Helper function to look up the scanner impl handle using name */ + private IWifiScannerImpl getScannerImpl(@NonNull String ifaceName) { + return mWificondScanners.get(ifaceName); + } + + /** + * Fetch the latest scan result from kernel via wificond. + * @param ifaceName Name of the interface. + * @return Returns an array of native scan results or an empty array on failure. + */ + @NonNull public List getScanResults(@NonNull String ifaceName, + @ScanResultType int scanType) { + IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); + if (scannerImpl == null) { + Log.e(TAG, "No valid wificond scanner interface handler"); + return new ArrayList<>(); + } + List results = null; + try { + if (scanType == SCAN_TYPE_SINGLE_SCAN) { + results = Arrays.asList(scannerImpl.getScanResults()); + } else { + results = Arrays.asList(scannerImpl.getPnoScanResults()); + } + } catch (RemoteException e1) { + Log.e(TAG, "Failed to create ScanDetail ArrayList"); + } + if (results == null) { + results = new ArrayList<>(); + } + if (mVerboseLoggingEnabled) { + Log.d(TAG, "get " + results.size() + " scan results from wificond"); + } + + return results; + } + + /** + * Return scan type for the parcelable {@link SingleScanSettings} + */ + private static int getScanType(@WifiScanner.ScanType int scanType) { + switch (scanType) { + case WifiScanner.SCAN_TYPE_LOW_LATENCY: + return IWifiScannerImpl.SCAN_TYPE_LOW_SPAN; + case WifiScanner.SCAN_TYPE_LOW_POWER: + return IWifiScannerImpl.SCAN_TYPE_LOW_POWER; + case WifiScanner.SCAN_TYPE_HIGH_ACCURACY: + return IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY; + default: + throw new IllegalArgumentException("Invalid scan type " + scanType); + } + } + + /** + * Start a scan using wificond for the given parameters. + * @param ifaceName Name of the interface. + * @param scanType Type of scan to perform. + * @param freqs list of frequencies to scan for, if null scan all supported channels. + * @param hiddenNetworkSSIDs List of hidden networks to be scanned for. + * @return Returns true on success. + */ + public boolean scan(@NonNull String ifaceName, @WifiScanner.ScanType int scanType, + Set freqs, List hiddenNetworkSSIDs) { + IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); + if (scannerImpl == null) { + Log.e(TAG, "No valid wificond scanner interface handler"); + return false; + } + SingleScanSettings settings = new SingleScanSettings(); + try { + settings.scanType = getScanType(scanType); + } catch (IllegalArgumentException e) { + Log.e(TAG, "Invalid scan type ", e); + return false; + } + settings.channelSettings = new ArrayList<>(); + settings.hiddenNetworks = new ArrayList<>(); + + if (freqs != null) { + for (Integer freq : freqs) { + ChannelSettings channel = new ChannelSettings(); + channel.frequency = freq; + settings.channelSettings.add(channel); + } + } + if (hiddenNetworkSSIDs != null) { + for (byte[] ssid : hiddenNetworkSSIDs) { + HiddenNetwork network = new HiddenNetwork(); + network.ssid = ssid; + + // settings.hiddenNetworks is expected to be very small, so this shouldn't cause + // any performance issues. + if (!settings.hiddenNetworks.contains(network)) { + settings.hiddenNetworks.add(network); + } + } + } + + try { + return scannerImpl.scan(settings); + } catch (RemoteException e1) { + Log.e(TAG, "Failed to request scan due to remote exception"); + } + return false; + } + + /** + * Start PNO scan. + * @param ifaceName Name of the interface. + * @param pnoSettings Pno scan configuration. + * @return true on success. + */ + public boolean startPnoScan(@NonNull String ifaceName, PnoSettings pnoSettings, + PnoScanRequestCallback callback) { + IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); + if (scannerImpl == null) { + Log.e(TAG, "No valid wificond scanner interface handler"); + return false; + } + + try { + boolean success = scannerImpl.startPnoScan(pnoSettings); + if (success) { + callback.onPnoRequestSucceeded(); + } else { + callback.onPnoRequestFailed(); + } + return success; + } catch (RemoteException e1) { + Log.e(TAG, "Failed to start pno scan due to remote exception"); + } + return false; + } + + /** + * Stop PNO scan. + * @param ifaceName Name of the interface. + * @return true on success. + */ + public boolean stopPnoScan(@NonNull String ifaceName) { + IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); + if (scannerImpl == null) { + Log.e(TAG, "No valid wificond scanner interface handler"); + return false; + } + try { + return scannerImpl.stopPnoScan(); + } catch (RemoteException e1) { + Log.e(TAG, "Failed to stop pno scan due to remote exception"); + } + return false; + } + + /** + * Abort ongoing single scan. + * @param ifaceName Name of the interface. + */ + public void abortScan(@NonNull String ifaceName) { + IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); + if (scannerImpl == null) { + Log.e(TAG, "No valid wificond scanner interface handler"); + return; + } + try { + scannerImpl.abortScan(); + } catch (RemoteException e1) { + Log.e(TAG, "Failed to request abortScan due to remote exception"); + } + } + + /** + * Query the list of valid frequencies for the provided band. + * The result depends on the on the country code that has been set. + * + * @param band as specified by one of the WifiScanner.WIFI_BAND_* constants. + * The following bands are supported {@link @WifiScanner.WifiBandBasic}: + * WifiScanner.WIFI_BAND_24_GHZ + * WifiScanner.WIFI_BAND_5_GHZ + * WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY + * WifiScanner.WIFI_BAND_6_GHZ + * @return frequencies vector of valid frequencies (MHz), or null for error. + * @throws IllegalArgumentException if band is not recognized. + */ + public int [] getChannelsForBand(@WifiScanner.WifiBandBasic int band) { + if (mWificond == null) { + Log.e(TAG, "No valid wificond scanner interface handler"); + return null; + } + try { + switch (band) { + case WifiScanner.WIFI_BAND_24_GHZ: + return mWificond.getAvailable2gChannels(); + case WifiScanner.WIFI_BAND_5_GHZ: + return mWificond.getAvailable5gNonDFSChannels(); + case WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY: + return mWificond.getAvailableDFSChannels(); + case WifiScanner.WIFI_BAND_6_GHZ: + return mWificond.getAvailable6gChannels(); + default: + throw new IllegalArgumentException("unsupported band " + band); + } + } catch (RemoteException e1) { + Log.e(TAG, "Failed to request getChannelsForBand due to remote exception"); + } + return null; + } + + /** Helper function to look up the interface handle using name */ + private IApInterface getApInterface(@NonNull String ifaceName) { + return mApInterfaces.get(ifaceName); + } + + /** + * Register the provided listener for SoftAp events. + * + * @param ifaceName Name of the interface. + * @param listener Callback for AP events. + * @return true on success, false otherwise. + */ + public boolean registerApListener(@NonNull String ifaceName, SoftApListener listener) { + IApInterface iface = getApInterface(ifaceName); + if (iface == null) { + Log.e(TAG, "No valid ap interface handler"); + return false; + } + try { + IApInterfaceEventCallback callback = new ApInterfaceEventCallback(listener); + mApInterfaceListeners.put(ifaceName, callback); + boolean success = iface.registerCallback(callback); + if (!success) { + Log.e(TAG, "Failed to register ap callback."); + return false; + } + } catch (RemoteException e) { + Log.e(TAG, "Exception in registering AP callback: " + e); + return false; + } + return true; + } + + /** + * See {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int)} + */ + public void sendMgmtFrame(@NonNull String ifaceName, @NonNull byte[] frame, + @NonNull SendMgmtFrameCallback callback, int mcs) { + + if (callback == null) { + Log.e(TAG, "callback cannot be null!"); + return; + } + + if (frame == null) { + Log.e(TAG, "frame cannot be null!"); + callback.onFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN); + return; + } + + // TODO (b/112029045) validate mcs + IClientInterface clientInterface = getClientInterface(ifaceName); + if (clientInterface == null) { + Log.e(TAG, "No valid wificond client interface handler"); + callback.onFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN); + return; + } + + if (!mSendMgmtFrameInProgress.compareAndSet(false, true)) { + Log.e(TAG, "An existing management frame transmission is in progress!"); + callback.onFailure(SEND_MGMT_FRAME_ERROR_ALREADY_STARTED); + return; + } + + SendMgmtFrameEvent sendMgmtFrameEvent = new SendMgmtFrameEvent(callback); + try { + clientInterface.SendMgmtFrame(frame, sendMgmtFrameEvent, mcs); + } catch (RemoteException e) { + Log.e(TAG, "Exception while starting link probe: " + e); + // Call sendMgmtFrameEvent.OnFailure() instead of callback.onFailure() so that + // sendMgmtFrameEvent can clean up internal state, such as cancelling the timer. + sendMgmtFrameEvent.OnFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN); + } + } + + /** + * Clear all internal handles. + */ + private void clearState() { + // Refresh handlers + mClientInterfaces.clear(); + mWificondScanners.clear(); + mPnoScanEventHandlers.clear(); + mScanEventHandlers.clear(); + mApInterfaces.clear(); + mApInterfaceListeners.clear(); + mSendMgmtFrameInProgress.set(false); + } +} diff --git a/wifi/java/android/net/wifi/wificond/ChannelSettings.java b/wifi/java/android/net/wifi/wificond/ChannelSettings.java new file mode 100644 index 000000000000..c2d65b581491 --- /dev/null +++ b/wifi/java/android/net/wifi/wificond/ChannelSettings.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2016 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.wificond; + +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Log; + +import java.util.Objects; + +/** + * ChannelSettings for wificond + * + * @hide + */ +public class ChannelSettings implements Parcelable { + private static final String TAG = "ChannelSettings"; + + public int frequency; + + /** public constructor */ + public ChannelSettings() { } + + /** override comparator */ + @Override + public boolean equals(Object rhs) { + if (this == rhs) return true; + if (!(rhs instanceof ChannelSettings)) { + return false; + } + ChannelSettings channel = (ChannelSettings) rhs; + if (channel == null) { + return false; + } + return frequency == channel.frequency; + } + + /** override hash code */ + @Override + public int hashCode() { + return Objects.hash(frequency); + } + + /** implement Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** + * implement Parcelable interface + * |flags| is ignored. + **/ + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(frequency); + } + + /** implement Parcelable interface */ + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + /** + * Caller is responsible for providing a valid parcel. + */ + @Override + public ChannelSettings createFromParcel(Parcel in) { + ChannelSettings result = new ChannelSettings(); + result.frequency = in.readInt(); + if (in.dataAvail() != 0) { + Log.e(TAG, "Found trailing data after parcel parsing."); + } + + return result; + } + + @Override + public ChannelSettings[] newArray(int size) { + return new ChannelSettings[size]; + } + }; +} diff --git a/wifi/java/android/net/wifi/wificond/HiddenNetwork.java b/wifi/java/android/net/wifi/wificond/HiddenNetwork.java new file mode 100644 index 000000000000..38dacea77488 --- /dev/null +++ b/wifi/java/android/net/wifi/wificond/HiddenNetwork.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2016 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.wificond; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.Arrays; + +/** + * HiddenNetwork for wificond + * + * @hide + */ +public class HiddenNetwork implements Parcelable { + private static final String TAG = "HiddenNetwork"; + + public byte[] ssid; + + /** public constructor */ + public HiddenNetwork() { } + + /** override comparator */ + @Override + public boolean equals(Object rhs) { + if (this == rhs) return true; + if (!(rhs instanceof HiddenNetwork)) { + return false; + } + HiddenNetwork network = (HiddenNetwork) rhs; + return Arrays.equals(ssid, network.ssid); + } + + /** override hash code */ + @Override + public int hashCode() { + return Arrays.hashCode(ssid); + } + + /** implement Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** + * implement Parcelable interface + * |flags| is ignored. + */ + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeByteArray(ssid); + } + + /** implement Parcelable interface */ + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + /** + * Caller is responsible for providing a valid parcel. + */ + @Override + public HiddenNetwork createFromParcel(Parcel in) { + HiddenNetwork result = new HiddenNetwork(); + result.ssid = in.createByteArray(); + return result; + } + + @Override + public HiddenNetwork[] newArray(int size) { + return new HiddenNetwork[size]; + } + }; +} diff --git a/wifi/java/android/net/wifi/wificond/NativeScanResult.java b/wifi/java/android/net/wifi/wificond/NativeScanResult.java new file mode 100644 index 000000000000..ff8e935da8c0 --- /dev/null +++ b/wifi/java/android/net/wifi/wificond/NativeScanResult.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2016 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.wificond; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.ArrayList; +import java.util.BitSet; +import java.util.List; + +/** + * ScanResult from wificond + * + * @hide + */ +public class NativeScanResult implements Parcelable { + private static final int CAPABILITY_SIZE = 16; + + public byte[] ssid; + public byte[] bssid; + public byte[] infoElement; + public int frequency; + public int signalMbm; + public long tsf; + public BitSet capability; + public boolean associated; + public List radioChainInfos; + + /** public constructor */ + public NativeScanResult() { } + + /** copy constructor */ + public NativeScanResult(NativeScanResult source) { + ssid = source.ssid.clone(); + bssid = source.bssid.clone(); + infoElement = source.infoElement.clone(); + frequency = source.frequency; + signalMbm = source.signalMbm; + tsf = source.tsf; + capability = (BitSet) source.capability.clone(); + associated = source.associated; + } + + /** implement Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** implement Parcelable interface */ + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeByteArray(ssid); + out.writeByteArray(bssid); + out.writeByteArray(infoElement); + out.writeInt(frequency); + out.writeInt(signalMbm); + out.writeLong(tsf); + int capabilityInt = 0; + for (int i = 0; i < CAPABILITY_SIZE; i++) { + if (capability.get(i)) { + capabilityInt |= 1 << i; + } + } + out.writeInt(capabilityInt); + out.writeInt(associated ? 1 : 0); + out.writeTypedList(radioChainInfos); + } + + /** implement Parcelable interface */ + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @Override + public NativeScanResult createFromParcel(Parcel in) { + NativeScanResult result = new NativeScanResult(); + result.ssid = in.createByteArray(); + result.bssid = in.createByteArray(); + result.infoElement = in.createByteArray(); + result.frequency = in.readInt(); + result.signalMbm = in.readInt(); + result.tsf = in.readLong(); + int capabilityInt = in.readInt(); + result.capability = new BitSet(CAPABILITY_SIZE); + for (int i = 0; i < CAPABILITY_SIZE; i++) { + if ((capabilityInt & (1 << i)) != 0) { + result.capability.set(i); + } + } + result.associated = (in.readInt() != 0); + result.radioChainInfos = new ArrayList<>(); + in.readTypedList(result.radioChainInfos, RadioChainInfo.CREATOR); + return result; + } + + @Override + public NativeScanResult[] newArray(int size) { + return new NativeScanResult[size]; + } + }; +} diff --git a/wifi/java/android/net/wifi/wificond/NativeWifiClient.java b/wifi/java/android/net/wifi/wificond/NativeWifiClient.java new file mode 100644 index 000000000000..4994ebd33216 --- /dev/null +++ b/wifi/java/android/net/wifi/wificond/NativeWifiClient.java @@ -0,0 +1,82 @@ +/* + * 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.wificond; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.Arrays; + +/** + * NativeWifiClient for wificond + * + * @hide + */ +public class NativeWifiClient implements Parcelable { + public byte[] macAddress; + + /** public constructor */ + public NativeWifiClient() { } + + /** override comparator */ + @Override + public boolean equals(Object rhs) { + if (this == rhs) return true; + if (!(rhs instanceof NativeWifiClient)) { + return false; + } + NativeWifiClient other = (NativeWifiClient) rhs; + return Arrays.equals(macAddress, other.macAddress); + } + + /** override hash code */ + @Override + public int hashCode() { + return Arrays.hashCode(macAddress); + } + + /** implement Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** + * implement Parcelable interface + * |flag| is ignored. + */ + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeByteArray(macAddress); + } + + /** implement Parcelable interface */ + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @Override + public NativeWifiClient createFromParcel(Parcel in) { + NativeWifiClient result = new NativeWifiClient(); + result.macAddress = in.createByteArray(); + return result; + } + + @Override + public NativeWifiClient[] newArray(int size) { + return new NativeWifiClient[size]; + } + }; +} diff --git a/wifi/java/android/net/wifi/wificond/PnoNetwork.java b/wifi/java/android/net/wifi/wificond/PnoNetwork.java new file mode 100644 index 000000000000..f923fd384a90 --- /dev/null +++ b/wifi/java/android/net/wifi/wificond/PnoNetwork.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2016 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.wificond; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.Arrays; +import java.util.Objects; + +/** + * PnoNetwork for wificond + * + * @hide + */ +public class PnoNetwork implements Parcelable { + + public boolean isHidden; + public byte[] ssid; + public int[] frequencies; + + /** public constructor */ + public PnoNetwork() { } + + /** override comparator */ + @Override + public boolean equals(Object rhs) { + if (this == rhs) return true; + if (!(rhs instanceof PnoNetwork)) { + return false; + } + PnoNetwork network = (PnoNetwork) rhs; + return Arrays.equals(ssid, network.ssid) + && Arrays.equals(frequencies, network.frequencies) + && isHidden == network.isHidden; + } + + /** override hash code */ + @Override + public int hashCode() { + return Objects.hash( + isHidden, + Arrays.hashCode(ssid), + Arrays.hashCode(frequencies)); + } + + /** implement Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** + * implement Parcelable interface + * |flag| is ignored. + */ + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(isHidden ? 1 : 0); + out.writeByteArray(ssid); + out.writeIntArray(frequencies); + } + + /** implement Parcelable interface */ + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @Override + public PnoNetwork createFromParcel(Parcel in) { + PnoNetwork result = new PnoNetwork(); + result.isHidden = in.readInt() != 0 ? true : false; + result.ssid = in.createByteArray(); + result.frequencies = in.createIntArray(); + return result; + } + + @Override + public PnoNetwork[] newArray(int size) { + return new PnoNetwork[size]; + } + }; +} diff --git a/wifi/java/android/net/wifi/wificond/PnoSettings.java b/wifi/java/android/net/wifi/wificond/PnoSettings.java new file mode 100644 index 000000000000..96cf24fdfb81 --- /dev/null +++ b/wifi/java/android/net/wifi/wificond/PnoSettings.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2016 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.wificond; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.ArrayList; +import java.util.Objects; + +/** + * PnoSettings for wificond + * + * @hide + */ +public class PnoSettings implements Parcelable { + public int intervalMs; + public int min2gRssi; + public int min5gRssi; + public int min6gRssi; + public ArrayList pnoNetworks; + + /** public constructor */ + public PnoSettings() { } + + /** override comparator */ + @Override + public boolean equals(Object rhs) { + if (this == rhs) return true; + if (!(rhs instanceof PnoSettings)) { + return false; + } + PnoSettings settings = (PnoSettings) rhs; + if (settings == null) { + return false; + } + return intervalMs == settings.intervalMs + && min2gRssi == settings.min2gRssi + && min5gRssi == settings.min5gRssi + && min6gRssi == settings.min6gRssi + && pnoNetworks.equals(settings.pnoNetworks); + } + + /** override hash code */ + @Override + public int hashCode() { + return Objects.hash(intervalMs, min2gRssi, min5gRssi, min6gRssi, pnoNetworks); + } + + /** implement Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** + * implement Parcelable interface + * |flag| is ignored. + **/ + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(intervalMs); + out.writeInt(min2gRssi); + out.writeInt(min5gRssi); + out.writeInt(min6gRssi); + out.writeTypedList(pnoNetworks); + } + + /** implement Parcelable interface */ + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @Override + public PnoSettings createFromParcel(Parcel in) { + PnoSettings result = new PnoSettings(); + result.intervalMs = in.readInt(); + result.min2gRssi = in.readInt(); + result.min5gRssi = in.readInt(); + result.min6gRssi = in.readInt(); + + result.pnoNetworks = new ArrayList(); + in.readTypedList(result.pnoNetworks, PnoNetwork.CREATOR); + + return result; + } + + @Override + public PnoSettings[] newArray(int size) { + return new PnoSettings[size]; + } + }; +} diff --git a/wifi/java/android/net/wifi/wificond/RadioChainInfo.java b/wifi/java/android/net/wifi/wificond/RadioChainInfo.java new file mode 100644 index 000000000000..2b03450b1357 --- /dev/null +++ b/wifi/java/android/net/wifi/wificond/RadioChainInfo.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2016 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.wificond; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.Objects; + +/** + * RadioChainInfo for wificond + * + * @hide + */ +public class RadioChainInfo implements Parcelable { + private static final String TAG = "RadioChainInfo"; + + public int chainId; + public int level; + + + /** public constructor */ + public RadioChainInfo() { } + + public RadioChainInfo(int chainId, int level) { + this.chainId = chainId; + this.level = level; + } + + /** override comparator */ + @Override + public boolean equals(Object rhs) { + if (this == rhs) return true; + if (!(rhs instanceof RadioChainInfo)) { + return false; + } + RadioChainInfo chainInfo = (RadioChainInfo) rhs; + if (chainInfo == null) { + return false; + } + return chainId == chainInfo.chainId && level == chainInfo.level; + } + + /** override hash code */ + @Override + public int hashCode() { + return Objects.hash(chainId, level); + } + + + /** implement Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** + * implement Parcelable interface + * |flags| is ignored. + */ + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(chainId); + out.writeInt(level); + } + + /** implement Parcelable interface */ + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + /** + * Caller is responsible for providing a valid parcel. + */ + @Override + public RadioChainInfo createFromParcel(Parcel in) { + RadioChainInfo result = new RadioChainInfo(); + result.chainId = in.readInt(); + result.level = in.readInt(); + return result; + } + + @Override + public RadioChainInfo[] newArray(int size) { + return new RadioChainInfo[size]; + } + }; +} diff --git a/wifi/java/android/net/wifi/wificond/SingleScanSettings.java b/wifi/java/android/net/wifi/wificond/SingleScanSettings.java new file mode 100644 index 000000000000..8065c01a7f89 --- /dev/null +++ b/wifi/java/android/net/wifi/wificond/SingleScanSettings.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2016 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.wificond; + +import android.net.wifi.IWifiScannerImpl; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Log; + +import java.util.ArrayList; +import java.util.Objects; + +/** + * SingleScanSettings for wificond + * + * @hide + */ +public class SingleScanSettings implements Parcelable { + private static final String TAG = "SingleScanSettings"; + + public int scanType; + public ArrayList channelSettings; + public ArrayList hiddenNetworks; + + /** public constructor */ + public SingleScanSettings() { } + + /** override comparator */ + @Override + public boolean equals(Object rhs) { + if (this == rhs) return true; + if (!(rhs instanceof SingleScanSettings)) { + return false; + } + SingleScanSettings settings = (SingleScanSettings) rhs; + if (settings == null) { + return false; + } + return scanType == settings.scanType + && channelSettings.equals(settings.channelSettings) + && hiddenNetworks.equals(settings.hiddenNetworks); + } + + /** override hash code */ + @Override + public int hashCode() { + return Objects.hash(scanType, channelSettings, hiddenNetworks); + } + + + /** implement Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + private static boolean isValidScanType(int scanType) { + return scanType == IWifiScannerImpl.SCAN_TYPE_LOW_SPAN + || scanType == IWifiScannerImpl.SCAN_TYPE_LOW_POWER + || scanType == IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY; + } + + /** + * implement Parcelable interface + * |flags| is ignored. + */ + @Override + public void writeToParcel(Parcel out, int flags) { + if (!isValidScanType(scanType)) { + Log.wtf(TAG, "Invalid scan type " + scanType); + } + out.writeInt(scanType); + out.writeTypedList(channelSettings); + out.writeTypedList(hiddenNetworks); + } + + /** implement Parcelable interface */ + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + /** + * Caller is responsible for providing a valid parcel. + */ + @Override + public SingleScanSettings createFromParcel(Parcel in) { + SingleScanSettings result = new SingleScanSettings(); + result.scanType = in.readInt(); + if (!isValidScanType(result.scanType)) { + Log.wtf(TAG, "Invalid scan type " + result.scanType); + } + result.channelSettings = new ArrayList(); + in.readTypedList(result.channelSettings, ChannelSettings.CREATOR); + result.hiddenNetworks = new ArrayList(); + in.readTypedList(result.hiddenNetworks, HiddenNetwork.CREATOR); + if (in.dataAvail() != 0) { + Log.e(TAG, "Found trailing data after parcel parsing."); + } + return result; + } + + @Override + public SingleScanSettings[] newArray(int size) { + return new SingleScanSettings[size]; + } + }; +} diff --git a/wifi/tests/src/android/net/wifi/WifiCondManagerTest.java b/wifi/tests/src/android/net/wifi/WifiCondManagerTest.java new file mode 100644 index 000000000000..48a9afa1d961 --- /dev/null +++ b/wifi/tests/src/android/net/wifi/WifiCondManagerTest.java @@ -0,0 +1,1281 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Matchers.argThat; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyLong; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +import android.app.AlarmManager; +import android.app.test.TestAlarmManager; +import android.content.Context; +import android.net.wifi.util.HexEncoding; +import android.net.wifi.wificond.ChannelSettings; +import android.net.wifi.wificond.HiddenNetwork; +import android.net.wifi.wificond.NativeWifiClient; +import android.net.wifi.wificond.PnoNetwork; +import android.net.wifi.wificond.PnoSettings; +import android.net.wifi.wificond.SingleScanSettings; +import android.os.Handler; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.test.TestLooper; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.AdditionalMatchers; +import org.mockito.ArgumentCaptor; +import org.mockito.ArgumentMatcher; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.CharacterCodingException; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Unit tests for {@link android.net.wifi.WifiCondManager}. + */ +@SmallTest +public class WifiCondManagerTest { + @Mock + private IWificond mWificond; + @Mock + private IBinder mWifiCondBinder; + @Mock + private IClientInterface mClientInterface; + @Mock + private IWifiScannerImpl mWifiScannerImpl; + @Mock + private IApInterface mApInterface; + @Mock + private WifiCondManager.SoftApListener mSoftApListener; + @Mock + private WifiCondManager.SendMgmtFrameCallback mSendMgmtFrameCallback; + @Mock + private WifiCondManager.ScanEventCallback mNormalScanCallback; + @Mock + private WifiCondManager.ScanEventCallback mPnoScanCallback; + @Mock + private WifiCondManager.PnoScanRequestCallback mPnoScanRequestCallback; + @Mock + private Context mContext; + private TestLooper mLooper; + private TestAlarmManager mTestAlarmManager; + private AlarmManager mAlarmManager; + private WifiCondManager mWificondControl; + private static final String TEST_INTERFACE_NAME = "test_wlan_if"; + private static final String TEST_INTERFACE_NAME1 = "test_wlan_if1"; + private static final String TEST_INVALID_INTERFACE_NAME = "asdf"; + private static final byte[] TEST_SSID = + new byte[]{'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'}; + private static final byte[] TEST_PSK = + new byte[]{'T', 'e', 's', 't'}; + + private static final Set SCAN_FREQ_SET = + new HashSet() {{ + add(2410); + add(2450); + add(5050); + add(5200); + }}; + private static final String TEST_QUOTED_SSID_1 = "\"testSsid1\""; + private static final String TEST_QUOTED_SSID_2 = "\"testSsid2\""; + private static final int[] TEST_FREQUENCIES_1 = {}; + private static final int[] TEST_FREQUENCIES_2 = {2500, 5124}; + + private static final List SCAN_HIDDEN_NETWORK_SSID_LIST = + new ArrayList() {{ + add(LocalNativeUtil.byteArrayFromArrayList( + LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_1))); + add(LocalNativeUtil.byteArrayFromArrayList( + LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_2))); + }}; + + private static final PnoSettings TEST_PNO_SETTINGS = + new PnoSettings() {{ + intervalMs = 6000; + pnoNetworks = new ArrayList<>(); + PnoNetwork network = new PnoNetwork(); + network.ssid = LocalNativeUtil.byteArrayFromArrayList( + LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_1)); + network.isHidden = true; + network.frequencies = TEST_FREQUENCIES_1; + pnoNetworks.add(network); + network.ssid = LocalNativeUtil.byteArrayFromArrayList( + LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_2)); + network.isHidden = false; + network.frequencies = TEST_FREQUENCIES_2; + pnoNetworks.add(network); + }}; + + private static final int TEST_MCS_RATE = 5; + private static final int TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS = 100; + private static final byte[] TEST_PROBE_FRAME = { + 0x40, 0x00, 0x3c, 0x00, (byte) 0xa8, (byte) 0xbd, 0x27, 0x5b, + 0x33, 0x72, (byte) 0xf4, (byte) 0xf5, (byte) 0xe8, 0x51, (byte) 0x9e, 0x09, + (byte) 0xa8, (byte) 0xbd, 0x27, 0x5b, 0x33, 0x72, (byte) 0xb0, 0x66, + 0x00, 0x00 + }; + + @Before + public void setUp() throws Exception { + // Setup mocks for successful WificondControl operation. Failure case mocks should be + // created in specific tests + MockitoAnnotations.initMocks(this); + + mTestAlarmManager = new TestAlarmManager(); + mAlarmManager = mTestAlarmManager.getAlarmManager(); + when(mContext.getSystemServiceName(AlarmManager.class)).thenReturn(Context.ALARM_SERVICE); + when(mContext.getSystemService(AlarmManager.class)).thenReturn(mAlarmManager); + + mLooper = new TestLooper(); + when(mContext.getMainLooper()).thenReturn(mLooper.getLooper()); + + when(mWificond.asBinder()).thenReturn(mWifiCondBinder); + when(mClientInterface.getWifiScannerImpl()).thenReturn(mWifiScannerImpl); + when(mWificond.createClientInterface(any())).thenReturn(mClientInterface); + when(mWificond.createApInterface(any())).thenReturn(mApInterface); + when(mWificond.tearDownClientInterface(any())).thenReturn(true); + when(mWificond.tearDownApInterface(any())).thenReturn(true); + when(mClientInterface.getWifiScannerImpl()).thenReturn(mWifiScannerImpl); + when(mClientInterface.getInterfaceName()).thenReturn(TEST_INTERFACE_NAME); + mWificondControl = new WifiCondManager(mContext, mWificond); + assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, + mNormalScanCallback, mPnoScanCallback)); + } + + /** + * Verifies that setupInterfaceForClientMode(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testSetupInterfaceForClientMode() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + verify(mWificond).createClientInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that setupInterfaceForClientMode(TEST_INTERFACE_NAME) calls subscribeScanEvents(). + */ + @Test + public void testSetupInterfaceForClientModeCallsScanEventSubscripiton() throws Exception { + verify(mWifiScannerImpl).subscribeScanEvents(any(IScanEvent.class)); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownClientInterface() throws Exception { + when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(true); + + assertTrue(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); + verify(mWifiScannerImpl).unsubscribeScanEvents(); + verify(mWifiScannerImpl).unsubscribePnoScanEvents(); + verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownClientInterfaceOnInvalidIface() throws Exception { + when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME1)).thenReturn(true); + + assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME1)); + verify(mWifiScannerImpl, never()).unsubscribeScanEvents(); + verify(mWifiScannerImpl, never()).unsubscribePnoScanEvents(); + verify(mWificond, never()).tearDownClientInterface(any()); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownClientInterfaceFailDueToExceptionScannerUnsubscribe() throws Exception { + when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(true); + doThrow(new RemoteException()).when(mWifiScannerImpl).unsubscribeScanEvents(); + + assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); + verify(mWifiScannerImpl).unsubscribeScanEvents(); + verify(mWifiScannerImpl, never()).unsubscribePnoScanEvents(); + verify(mWificond, never()).tearDownClientInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownClientInterfaceErrorWhenWificondFailed() throws Exception { + when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(false); + + assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); + verify(mWifiScannerImpl).unsubscribeScanEvents(); + verify(mWifiScannerImpl).unsubscribePnoScanEvents(); + verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that the client handles are cleared after teardown. + */ + @Test + public void testTeardownClientInterfaceClearsHandles() throws Exception { + testTeardownClientInterface(); + + assertNull(mWificondControl.signalPoll(TEST_INTERFACE_NAME)); + verify(mClientInterface, never()).signalPoll(); + + assertFalse(mWificondControl.scan( + TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_LATENCY, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); + verify(mWifiScannerImpl, never()).scan(any()); + } + + /** + * Verifies that setupInterfaceForSoftApMode(TEST_INTERFACE_NAME) calls wificond. + */ + @Test + public void testSetupInterfaceForSoftApMode() throws Exception { + when(mWificond.createApInterface(TEST_INTERFACE_NAME)).thenReturn(mApInterface); + + assertEquals(true, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME)); + verify(mWificond).createApInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that setupInterfaceForSoftAp() returns null when wificond is not started. + */ + @Test + public void testSetupInterfaceForSoftApModeErrorWhenWificondIsNotStarted() throws Exception { + // Invoke wificond death handler to clear the handle. + mWificondControl.binderDied(); + mLooper.dispatchAll(); + + assertEquals(false, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME)); + } + + /** + * Verifies that setupInterfaceForSoftApMode(TEST_INTERFACE_NAME) returns null when wificond + * failed to setup AP interface. + */ + @Test + public void testSetupInterfaceForSoftApModeErrorWhenWificondFailedToSetupInterface() + throws Exception { + when(mWificond.createApInterface(TEST_INTERFACE_NAME)).thenReturn(null); + + assertEquals(false, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME)); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownSoftApInterface() throws Exception { + testSetupInterfaceForSoftApMode(); + when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME)).thenReturn(true); + + assertTrue(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME)); + verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that tearDownSoftapInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownSoftApInterfaceOnInvalidIface() throws Exception { + testSetupInterfaceForSoftApMode(); + when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME1)).thenReturn(true); + + assertFalse(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME1)); + verify(mWificond, never()).tearDownApInterface(any()); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownSoftApInterfaceErrorWhenWificondFailed() throws Exception { + testSetupInterfaceForSoftApMode(); + when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME)).thenReturn(false); + + assertFalse(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME)); + verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that the SoftAp handles are cleared after teardown. + */ + @Test + public void testTeardownSoftApInterfaceClearsHandles() throws Exception { + testTeardownSoftApInterface(); + + assertFalse(mWificondControl.registerApListener( + TEST_INTERFACE_NAME, mSoftApListener)); + verify(mApInterface, never()).registerCallback(any()); + } + + /** + * Verifies that we can setup concurrent interfaces. + */ + @Test + public void testSetupMultipleInterfaces() throws Exception { + when(mWificond.createApInterface(TEST_INTERFACE_NAME1)).thenReturn(mApInterface); + + assertEquals(true, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME1)); + + verify(mWificond).createClientInterface(TEST_INTERFACE_NAME); + verify(mWificond).createApInterface(TEST_INTERFACE_NAME1); + } + + /** + * Verifies that we can setup concurrent interfaces. + */ + @Test + public void testTeardownMultipleInterfaces() throws Exception { + testSetupMultipleInterfaces(); + assertTrue(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); + assertTrue(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME1)); + + verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME); + verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME1); + } + + /** + * Verifies that tearDownInterfaces() calls wificond. + */ + @Test + public void testTearDownInterfaces() throws Exception { + assertTrue(mWificondControl.tearDownInterfaces()); + verify(mWificond).tearDownInterfaces(); + } + + /** + * Verifies that tearDownInterfaces() calls unsubscribeScanEvents() when there was + * a configured client interface. + */ + @Test + public void testTearDownInterfacesRemovesScanEventSubscription() throws Exception { + assertTrue(mWificondControl.tearDownInterfaces()); + verify(mWifiScannerImpl).unsubscribeScanEvents(); + } + + + /** + * Verifies that tearDownInterfaces() returns false when wificond is not started. + */ + @Test + public void testTearDownInterfacesErrorWhenWificondIsNotStarterd() throws Exception { + // Invoke wificond death handler to clear the handle. + mWificondControl.binderDied(); + mLooper.dispatchAll(); + assertFalse(mWificondControl.tearDownInterfaces()); + } + + /** + * Verifies that signalPoll() calls wificond. + */ + @Test + public void testSignalPoll() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + + mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, mNormalScanCallback, + mPnoScanCallback); + mWificondControl.signalPoll(TEST_INTERFACE_NAME); + verify(mClientInterface).signalPoll(); + } + + /** + * Verifies that signalPoll() returns null when there is no configured client interface. + */ + @Test + public void testSignalPollErrorWhenNoClientInterfaceConfigured() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + + // Configure client interface. + assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, + mNormalScanCallback, mPnoScanCallback)); + + // Tear down interfaces. + assertTrue(mWificondControl.tearDownInterfaces()); + + // Signal poll should fail. + assertEquals(null, mWificondControl.signalPoll(TEST_INTERFACE_NAME)); + } + + /** + * Verifies that getTxPacketCounters() calls wificond. + */ + @Test + public void testGetTxPacketCounters() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + + mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, mNormalScanCallback, + mPnoScanCallback); + mWificondControl.getTxPacketCounters(TEST_INTERFACE_NAME); + verify(mClientInterface).getPacketCounters(); + } + + /** + * Verifies that getTxPacketCounters() returns null when there is no configured client + * interface. + */ + @Test + public void testGetTxPacketCountersErrorWhenNoClientInterfaceConfigured() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + + // Configure client interface. + assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, + mNormalScanCallback, mPnoScanCallback)); + + // Tear down interfaces. + assertTrue(mWificondControl.tearDownInterfaces()); + + // Signal poll should fail. + assertEquals(null, mWificondControl.getTxPacketCounters(TEST_INTERFACE_NAME)); + } + + /** + * Verifies that getScanResults() returns null when there is no configured client + * interface. + */ + @Test + public void testGetScanResultsErrorWhenNoClientInterfaceConfigured() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + + // Configure client interface. + assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, + mNormalScanCallback, mPnoScanCallback)); + + // Tear down interfaces. + assertTrue(mWificondControl.tearDownInterfaces()); + + // getScanResults should fail. + assertEquals(0, + mWificondControl.getScanResults(TEST_INTERFACE_NAME, + WifiCondManager.SCAN_TYPE_SINGLE_SCAN).size()); + } + + /** + * Verifies that Scan() can convert input parameters to SingleScanSettings correctly. + */ + @Test + public void testScan() throws Exception { + when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true); + assertTrue(mWificondControl.scan( + TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_POWER, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); + verify(mWifiScannerImpl).scan(argThat(new ScanMatcher( + IWifiScannerImpl.SCAN_TYPE_LOW_POWER, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST))); + } + + /** + * Verifies that Scan() removes duplicates hiddenSsids passed in from input. + */ + @Test + public void testScanWithDuplicateHiddenSsids() throws Exception { + when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true); + // Create a list of hiddenSsid that has a duplicate element + List hiddenSsidWithDup = new ArrayList<>(SCAN_HIDDEN_NETWORK_SSID_LIST); + hiddenSsidWithDup.add(SCAN_HIDDEN_NETWORK_SSID_LIST.get(0)); + assertEquals(hiddenSsidWithDup.get(0), + hiddenSsidWithDup.get(hiddenSsidWithDup.size() - 1)); + // Pass the List with duplicate elements into scan() + assertTrue(mWificondControl.scan( + TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_POWER, + SCAN_FREQ_SET, hiddenSsidWithDup)); + // But the argument passed down should have the duplicate removed. + verify(mWifiScannerImpl).scan(argThat(new ScanMatcher( + IWifiScannerImpl.SCAN_TYPE_LOW_POWER, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST))); + } + + /** + * Verifies that Scan() can handle null input parameters correctly. + */ + @Test + public void testScanNullParameters() throws Exception { + when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true); + assertTrue(mWificondControl.scan( + TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_HIGH_ACCURACY, null, null)); + verify(mWifiScannerImpl).scan(argThat(new ScanMatcher( + IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY, null, null))); + } + + /** + * Verifies that Scan() can handle wificond scan failure. + */ + @Test + public void testScanFailure() throws Exception { + when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(false); + assertFalse(mWificondControl.scan( + TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_LATENCY, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); + verify(mWifiScannerImpl).scan(any(SingleScanSettings.class)); + } + + /** + * Verifies that Scan() can handle invalid type. + */ + @Test + public void testScanFailureDueToInvalidType() throws Exception { + assertFalse(mWificondControl.scan( + TEST_INTERFACE_NAME, 100, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); + verify(mWifiScannerImpl, never()).scan(any(SingleScanSettings.class)); + } + + /** + * Verifies that startPnoScan() can convert input parameters to PnoSettings correctly. + */ + @Test + public void testStartPnoScan() throws Exception { + when(mWifiScannerImpl.startPnoScan(any(PnoSettings.class))).thenReturn(true); + assertTrue(mWificondControl.startPnoScan(TEST_INTERFACE_NAME, TEST_PNO_SETTINGS, + mPnoScanRequestCallback)); + verify(mWifiScannerImpl).startPnoScan(argThat(new PnoScanMatcher(TEST_PNO_SETTINGS))); + verify(mPnoScanRequestCallback).onPnoRequestSucceeded(); + } + + /** + * Verifies that stopPnoScan() calls underlying wificond. + */ + @Test + public void testStopPnoScan() throws Exception { + when(mWifiScannerImpl.stopPnoScan()).thenReturn(true); + assertTrue(mWificondControl.stopPnoScan(TEST_INTERFACE_NAME)); + verify(mWifiScannerImpl).stopPnoScan(); + } + + /** + * Verifies that stopPnoScan() can handle wificond failure. + */ + @Test + public void testStopPnoScanFailure() throws Exception { + + when(mWifiScannerImpl.stopPnoScan()).thenReturn(false); + assertFalse(mWificondControl.stopPnoScan(TEST_INTERFACE_NAME)); + verify(mWifiScannerImpl).stopPnoScan(); + } + + /** + * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon scan + * result event. + */ + @Test + public void testScanResultEvent() throws Exception { + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(IScanEvent.class); + verify(mWifiScannerImpl).subscribeScanEvents(messageCaptor.capture()); + IScanEvent scanEvent = messageCaptor.getValue(); + assertNotNull(scanEvent); + scanEvent.OnScanResultReady(); + + verify(mNormalScanCallback).onScanResultReady(); + } + + /** + * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon scan + * failed event. + */ + @Test + public void testScanFailedEvent() throws Exception { + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(IScanEvent.class); + verify(mWifiScannerImpl).subscribeScanEvents(messageCaptor.capture()); + IScanEvent scanEvent = messageCaptor.getValue(); + assertNotNull(scanEvent); + scanEvent.OnScanFailed(); + + verify(mNormalScanCallback).onScanFailed(); + } + + /** + * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon pno scan + * result event. + */ + @Test + public void testPnoScanResultEvent() throws Exception { + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(IPnoScanEvent.class); + verify(mWifiScannerImpl).subscribePnoScanEvents(messageCaptor.capture()); + IPnoScanEvent pnoScanEvent = messageCaptor.getValue(); + assertNotNull(pnoScanEvent); + pnoScanEvent.OnPnoNetworkFound(); + verify(mPnoScanCallback).onScanResultReady(); + } + + /** + * Verifies that WificondControl can invoke WifiMetrics pno scan count methods upon pno event. + */ + @Test + public void testPnoScanEventsForMetrics() throws Exception { + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(IPnoScanEvent.class); + verify(mWifiScannerImpl).subscribePnoScanEvents(messageCaptor.capture()); + IPnoScanEvent pnoScanEvent = messageCaptor.getValue(); + assertNotNull(pnoScanEvent); + + pnoScanEvent.OnPnoNetworkFound(); + verify(mPnoScanCallback).onScanResultReady(); + + pnoScanEvent.OnPnoScanFailed(); + verify(mPnoScanCallback).onScanFailed(); + } + + /** + * Verifies that startPnoScan() can invoke WifiMetrics pno scan count methods correctly. + */ + @Test + public void testStartPnoScanForMetrics() throws Exception { + when(mWifiScannerImpl.startPnoScan(any(PnoSettings.class))).thenReturn(false); + + assertFalse(mWificondControl.startPnoScan(TEST_INTERFACE_NAME, TEST_PNO_SETTINGS, + mPnoScanRequestCallback)); + verify(mPnoScanRequestCallback).onPnoRequestFailed(); + } + + /** + * Verifies that abortScan() calls underlying wificond. + */ + @Test + public void testAbortScan() throws Exception { + mWificondControl.abortScan(TEST_INTERFACE_NAME); + verify(mWifiScannerImpl).abortScan(); + } + + /** + * Ensures that the Ap interface callbacks are forwarded to the + * SoftApListener used for starting soft AP. + */ + @Test + public void testSoftApListenerInvocation() throws Exception { + testSetupInterfaceForSoftApMode(); + + WifiConfiguration config = new WifiConfiguration(); + config.SSID = new String(TEST_SSID, StandardCharsets.UTF_8); + + when(mApInterface.registerCallback(any())).thenReturn(true); + + final ArgumentCaptor apInterfaceCallbackCaptor = + ArgumentCaptor.forClass(IApInterfaceEventCallback.class); + + assertTrue(mWificondControl.registerApListener( + TEST_INTERFACE_NAME, mSoftApListener)); + verify(mApInterface).registerCallback(apInterfaceCallbackCaptor.capture()); + + final NativeWifiClient testClient = new NativeWifiClient(); + apInterfaceCallbackCaptor.getValue().onConnectedClientsChanged(testClient, true); + verify(mSoftApListener).onConnectedClientsChanged(eq(testClient), eq(true)); + + int channelFrequency = 2437; + int channelBandwidth = IApInterfaceEventCallback.BANDWIDTH_20; + apInterfaceCallbackCaptor.getValue().onSoftApChannelSwitched(channelFrequency, + channelBandwidth); + verify(mSoftApListener).onSoftApChannelSwitched(eq(channelFrequency), eq(channelBandwidth)); + } + + /** + * Verifies registration and invocation of wificond death handler. + */ + @Test + public void testRegisterDeathHandler() throws Exception { + Runnable deathHandler = mock(Runnable.class); + assertTrue(mWificondControl.initialize(deathHandler)); + verify(mWificond).tearDownInterfaces(); + mWificondControl.binderDied(); + mLooper.dispatchAll(); + verify(deathHandler).run(); + } + + /** + * Verifies handling of wificond death and ensures that all internal state is cleared and + * handlers are invoked. + */ + @Test + public void testDeathHandling() throws Exception { + Runnable deathHandler = mock(Runnable.class); + assertTrue(mWificondControl.initialize(deathHandler)); + + testSetupInterfaceForClientMode(); + + mWificondControl.binderDied(); + mLooper.dispatchAll(); + verify(deathHandler).run(); + + // The handles should be cleared after death. + assertNull(mWificondControl.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ)); + verify(mWificond, never()).getAvailable5gNonDFSChannels(); + } + + /** + * sendMgmtFrame() should fail if a null callback is passed in. + */ + @Test + public void testSendMgmtFrameNullCallback() throws Exception { + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, null, TEST_MCS_RATE); + + verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt()); + } + + /** + * sendMgmtFrame() should fail if a null frame is passed in. + */ + @Test + public void testSendMgmtFrameNullFrame() throws Exception { + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, null, + mSendMgmtFrameCallback, TEST_MCS_RATE); + + verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt()); + verify(mSendMgmtFrameCallback).onFailure(anyInt()); + } + + /** + * sendMgmtFrame() should fail if an interface name that does not exist is passed in. + */ + @Test + public void testSendMgmtFrameInvalidInterfaceName() throws Exception { + mWificondControl.sendMgmtFrame(TEST_INVALID_INTERFACE_NAME, TEST_PROBE_FRAME, + mSendMgmtFrameCallback, TEST_MCS_RATE); + + verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt()); + verify(mSendMgmtFrameCallback).onFailure(anyInt()); + } + + /** + * sendMgmtFrame() should fail if it is called a second time before the first call completed. + */ + @Test + public void testSendMgmtFrameCalledTwiceBeforeFinished() throws Exception { + WifiCondManager.SendMgmtFrameCallback cb1 = mock( + WifiCondManager.SendMgmtFrameCallback.class); + WifiCondManager.SendMgmtFrameCallback cb2 = mock( + WifiCondManager.SendMgmtFrameCallback.class); + + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, cb1, TEST_MCS_RATE); + verify(cb1, never()).onFailure(anyInt()); + verify(mClientInterface, times(1)) + .SendMgmtFrame(AdditionalMatchers.aryEq(TEST_PROBE_FRAME), + any(), eq(TEST_MCS_RATE)); + + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, cb2, TEST_MCS_RATE); + verify(cb2).onFailure(WifiCondManager.SEND_MGMT_FRAME_ERROR_ALREADY_STARTED); + // verify SendMgmtFrame() still was only called once i.e. not called again + verify(mClientInterface, times(1)) + .SendMgmtFrame(any(), any(), anyInt()); + } + + /** + * Tests that when a RemoteException is triggered on AIDL call, onFailure() is called only once. + */ + @Test + public void testSendMgmtFrameThrowsException() throws Exception { + WifiCondManager.SendMgmtFrameCallback cb = mock( + WifiCondManager.SendMgmtFrameCallback.class); + + final ArgumentCaptor sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + + doThrow(new RemoteException()).when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + + final ArgumentCaptor alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, + cb, TEST_MCS_RATE); + mLooper.dispatchAll(); + + verify(cb).onFailure(anyInt()); + verify(mAlarmManager).cancel(eq(alarmListenerCaptor.getValue())); + + sendMgmtFrameEventCaptor.getValue().OnFailure( + WifiCondManager.SEND_MGMT_FRAME_ERROR_UNKNOWN); + mLooper.dispatchAll(); + + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + mLooper.dispatchAll(); + + verifyNoMoreInteractions(cb); + } + + /** + * Tests that the onAck() callback is triggered correctly. + */ + @Test + public void testSendMgmtFrameSuccess() throws Exception { + WifiCondManager.SendMgmtFrameCallback cb = mock( + WifiCondManager.SendMgmtFrameCallback.class); + + final ArgumentCaptor sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + doNothing().when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + final ArgumentCaptor alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, cb, TEST_MCS_RATE); + + sendMgmtFrameEventCaptor.getValue().OnAck(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS); + mLooper.dispatchAll(); + verify(cb).onAck(eq(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS)); + verify(cb, never()).onFailure(anyInt()); + verify(mAlarmManager).cancel(eq(alarmListenerCaptor.getValue())); + + // verify that even if timeout is triggered afterwards, SendMgmtFrameCallback is not + // triggered again + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + mLooper.dispatchAll(); + verify(cb, times(1)).onAck(anyInt()); + verify(cb, never()).onFailure(anyInt()); + } + + /** + * Tests that the onFailure() callback is triggered correctly. + */ + @Test + public void testSendMgmtFrameFailure() throws Exception { + WifiCondManager.SendMgmtFrameCallback cb = mock( + WifiCondManager.SendMgmtFrameCallback.class); + + final ArgumentCaptor sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + doNothing().when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + final ArgumentCaptor alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, cb, TEST_MCS_RATE); + + sendMgmtFrameEventCaptor.getValue().OnFailure( + WifiCondManager.SEND_MGMT_FRAME_ERROR_UNKNOWN); + mLooper.dispatchAll(); + verify(cb, never()).onAck(anyInt()); + verify(cb).onFailure(WifiCondManager.SEND_MGMT_FRAME_ERROR_UNKNOWN); + verify(mAlarmManager).cancel(eq(alarmListenerCaptor.getValue())); + + // verify that even if timeout is triggered afterwards, SendMgmtFrameCallback is not + // triggered again + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + mLooper.dispatchAll(); + verify(cb, never()).onAck(anyInt()); + verify(cb, times(1)).onFailure(anyInt()); + } + + /** + * Tests that the onTimeout() callback is triggered correctly. + */ + @Test + public void testSendMgmtFrameTimeout() throws Exception { + WifiCondManager.SendMgmtFrameCallback cb = mock( + WifiCondManager.SendMgmtFrameCallback.class); + + final ArgumentCaptor sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + doNothing().when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + final ArgumentCaptor alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, cb, TEST_MCS_RATE); + + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + mLooper.dispatchAll(); + verify(cb, never()).onAck(anyInt()); + verify(cb).onFailure(WifiCondManager.SEND_MGMT_FRAME_ERROR_TIMEOUT); + + // verify that even if onAck() callback is triggered after timeout, + // SendMgmtFrameCallback is not triggered again + sendMgmtFrameEventCaptor.getValue().OnAck(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS); + mLooper.dispatchAll(); + verify(cb, never()).onAck(anyInt()); + verify(cb, times(1)).onFailure(anyInt()); + } + + /** + * Tests every possible test outcome followed by every other test outcome to ensure that the + * internal state is reset correctly between calls. + * i.e. (success, success), (success, failure), (success, timeout), + * (failure, failure), (failure, success), (failure, timeout), + * (timeout, timeout), (timeout, success), (timeout, failure) + * + * Also tests that internal state is reset correctly after a transient AIDL RemoteException. + */ + @Test + public void testSendMgmtFrameMixed() throws Exception { + testSendMgmtFrameThrowsException(); + testSendMgmtFrameSuccess(); + testSendMgmtFrameSuccess(); + testSendMgmtFrameFailure(); + testSendMgmtFrameFailure(); + testSendMgmtFrameTimeout(); + testSendMgmtFrameTimeout(); + testSendMgmtFrameSuccess(); + testSendMgmtFrameTimeout(); + testSendMgmtFrameFailure(); + testSendMgmtFrameSuccess(); + } + + /** + * Tests that OnAck() does not perform any non-thread-safe operations on the binder thread. + * + * The sequence of instructions are: + * 1. post onAlarm() onto main thread + * 2. OnAck() + * 3. mLooper.dispatchAll() + * + * The actual order of execution is: + * 1. binder thread portion of OnAck() + * 2. onAlarm() (which purely executes on the main thread) + * 3. main thread portion of OnAck() + * + * If the binder thread portion of OnAck() is not thread-safe, it can possibly mess up + * onAlarm(). Tests that this does not occur. + */ + @Test + public void testSendMgmtFrameTimeoutAckThreadSafe() throws Exception { + final ArgumentCaptor sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + doNothing().when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + final ArgumentCaptor alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, + mSendMgmtFrameCallback, TEST_MCS_RATE); + + // AlarmManager should post the onAlarm() callback onto the handler, but since we are + // triggering onAlarm() ourselves during the test, manually post onto handler + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + // OnAck posts to the handler + sendMgmtFrameEventCaptor.getValue().OnAck(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS); + mLooper.dispatchAll(); + verify(mSendMgmtFrameCallback, never()).onAck(anyInt()); + verify(mSendMgmtFrameCallback).onFailure(WifiCondManager.SEND_MGMT_FRAME_ERROR_TIMEOUT); + } + + /** + * See {@link #testSendMgmtFrameTimeoutAckThreadSafe()}. This test replaces OnAck() with + * OnFailure(). + */ + @Test + public void testSendMgmtFrameTimeoutFailureThreadSafe() throws Exception { + final ArgumentCaptor sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + doNothing().when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + final ArgumentCaptor alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, + mSendMgmtFrameCallback, TEST_MCS_RATE); + + // AlarmManager should post the onAlarm() callback onto the handler, but since we are + // triggering onAlarm() ourselves during the test, manually post onto handler + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + // OnFailure posts to the handler + sendMgmtFrameEventCaptor.getValue().OnFailure( + WifiCondManager.SEND_MGMT_FRAME_ERROR_UNKNOWN); + mLooper.dispatchAll(); + verify(mSendMgmtFrameCallback).onFailure(WifiCondManager.SEND_MGMT_FRAME_ERROR_TIMEOUT); + } + + // Create a ArgumentMatcher which captures a SingleScanSettings parameter and checks if it + // matches the provided frequency set and ssid set. + private class ScanMatcher implements ArgumentMatcher { + int mExpectedScanType; + private final Set mExpectedFreqs; + private final List mExpectedSsids; + + ScanMatcher(int expectedScanType, Set expectedFreqs, List expectedSsids) { + this.mExpectedScanType = expectedScanType; + this.mExpectedFreqs = expectedFreqs; + this.mExpectedSsids = expectedSsids; + } + + @Override + public boolean matches(SingleScanSettings settings) { + if (settings.scanType != mExpectedScanType) { + return false; + } + ArrayList channelSettings = settings.channelSettings; + ArrayList hiddenNetworks = settings.hiddenNetworks; + if (mExpectedFreqs != null) { + Set freqSet = new HashSet(); + for (ChannelSettings channel : channelSettings) { + freqSet.add(channel.frequency); + } + if (!mExpectedFreqs.equals(freqSet)) { + return false; + } + } else { + if (channelSettings != null && channelSettings.size() > 0) { + return false; + } + } + + if (mExpectedSsids != null) { + List ssidSet = new ArrayList<>(); + for (HiddenNetwork network : hiddenNetworks) { + ssidSet.add(network.ssid); + } + if (!mExpectedSsids.equals(ssidSet)) { + return false; + } + + } else { + if (hiddenNetworks != null && hiddenNetworks.size() > 0) { + return false; + } + } + return true; + } + + @Override + public String toString() { + return "ScanMatcher{mExpectedFreqs=" + mExpectedFreqs + + ", mExpectedSsids=" + mExpectedSsids + '}'; + } + } + + // Create a ArgumentMatcher which captures a PnoSettings parameter and checks if it + // matches the WifiNative.PnoSettings; + private class PnoScanMatcher implements ArgumentMatcher { + private final PnoSettings mExpectedPnoSettings; + + PnoScanMatcher(PnoSettings expectedPnoSettings) { + this.mExpectedPnoSettings = expectedPnoSettings; + } + + @Override + public boolean matches(PnoSettings settings) { + if (mExpectedPnoSettings == null) { + return false; + } + if (settings.intervalMs != mExpectedPnoSettings.intervalMs + || settings.min2gRssi != mExpectedPnoSettings.min2gRssi + || settings.min5gRssi != mExpectedPnoSettings.min5gRssi + || settings.min6gRssi != mExpectedPnoSettings.min6gRssi) { + return false; + } + if (settings.pnoNetworks == null || mExpectedPnoSettings.pnoNetworks == null) { + return false; + } + if (settings.pnoNetworks.size() != mExpectedPnoSettings.pnoNetworks.size()) { + return false; + } + + for (int i = 0; i < settings.pnoNetworks.size(); i++) { + if (!Arrays.equals(settings.pnoNetworks.get(i).ssid, + mExpectedPnoSettings.pnoNetworks.get(i).ssid)) { + return false; + } + if (settings.pnoNetworks.get(i).isHidden != mExpectedPnoSettings.pnoNetworks.get( + i).isHidden) { + return false; + } + if (!Arrays.equals(settings.pnoNetworks.get(i).frequencies, + mExpectedPnoSettings.pnoNetworks.get(i).frequencies)) { + return false; + } + } + return true; + } + + @Override + public String toString() { + return "PnoScanMatcher{" + "mExpectedPnoSettings=" + mExpectedPnoSettings + '}'; + } + } + + private static class LocalNativeUtil { + private static final int SSID_BYTES_MAX_LEN = 32; + + /** + * Converts an ArrayList of UTF_8 byte values to string. + * The string will either be: + * a) UTF-8 String encapsulated in quotes (if all the bytes are UTF-8 encodeable and non + * null), + * or + * b) Hex string with no delimiters. + * + * @param bytes List of bytes for ssid. + * @throws IllegalArgumentException for null bytes. + */ + public static String bytesToHexOrQuotedString(ArrayList bytes) { + if (bytes == null) { + throw new IllegalArgumentException("null ssid bytes"); + } + byte[] byteArray = byteArrayFromArrayList(bytes); + // Check for 0's in the byte stream in which case we cannot convert this into a string. + if (!bytes.contains(Byte.valueOf((byte) 0))) { + CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder(); + try { + CharBuffer decoded = decoder.decode(ByteBuffer.wrap(byteArray)); + return "\"" + decoded.toString() + "\""; + } catch (CharacterCodingException cce) { + } + } + return hexStringFromByteArray(byteArray); + } + + /** + * Converts an ssid string to an arraylist of UTF_8 byte values. + * These forms are acceptable: + * a) UTF-8 String encapsulated in quotes, or + * b) Hex string with no delimiters. + * + * @param ssidStr String to be converted. + * @throws IllegalArgumentException for null string. + */ + public static ArrayList decodeSsid(String ssidStr) { + ArrayList ssidBytes = hexOrQuotedStringToBytes(ssidStr); + if (ssidBytes.size() > SSID_BYTES_MAX_LEN) { + throw new IllegalArgumentException( + "ssid bytes size out of range: " + ssidBytes.size()); + } + return ssidBytes; + } + + /** + * Convert from an array list of Byte to an array of primitive bytes. + */ + public static byte[] byteArrayFromArrayList(ArrayList bytes) { + byte[] byteArray = new byte[bytes.size()]; + int i = 0; + for (Byte b : bytes) { + byteArray[i++] = b; + } + return byteArray; + } + + /** + * Converts a byte array to hex string. + * + * @param bytes List of bytes for ssid. + * @throws IllegalArgumentException for null bytes. + */ + public static String hexStringFromByteArray(byte[] bytes) { + if (bytes == null) { + throw new IllegalArgumentException("null hex bytes"); + } + return new String(HexEncoding.encode(bytes)).toLowerCase(); + } + + /** + * Converts an string to an arraylist of UTF_8 byte values. + * These forms are acceptable: + * a) UTF-8 String encapsulated in quotes, or + * b) Hex string with no delimiters. + * + * @param str String to be converted. + * @throws IllegalArgumentException for null string. + */ + public static ArrayList hexOrQuotedStringToBytes(String str) { + if (str == null) { + throw new IllegalArgumentException("null string"); + } + int length = str.length(); + if ((length > 1) && (str.charAt(0) == '"') && (str.charAt(length - 1) == '"')) { + str = str.substring(1, str.length() - 1); + return stringToByteArrayList(str); + } else { + return byteArrayToArrayList(hexStringToByteArray(str)); + } + } + + /** + * Convert the string to byte array list. + * + * @return the UTF_8 char byte values of str, as an ArrayList. + * @throws IllegalArgumentException if a null or unencodable string is sent. + */ + public static ArrayList stringToByteArrayList(String str) { + if (str == null) { + throw new IllegalArgumentException("null string"); + } + // Ensure that the provided string is UTF_8 encoded. + CharsetEncoder encoder = StandardCharsets.UTF_8.newEncoder(); + try { + ByteBuffer encoded = encoder.encode(CharBuffer.wrap(str)); + byte[] byteArray = new byte[encoded.remaining()]; + encoded.get(byteArray); + return byteArrayToArrayList(byteArray); + } catch (CharacterCodingException cce) { + throw new IllegalArgumentException("cannot be utf-8 encoded", cce); + } + } + + /** + * Convert from an array of primitive bytes to an array list of Byte. + */ + public static ArrayList byteArrayToArrayList(byte[] bytes) { + ArrayList byteList = new ArrayList<>(); + for (Byte b : bytes) { + byteList.add(b); + } + return byteList; + } + + /** + * Converts a hex string to byte array. + * + * @param hexStr String to be converted. + * @throws IllegalArgumentException for null string. + */ + public static byte[] hexStringToByteArray(String hexStr) { + if (hexStr == null) { + throw new IllegalArgumentException("null hex string"); + } + return HexEncoding.decode(hexStr.toCharArray(), false); + } + } +} diff --git a/wifi/tests/src/android/net/wifi/wificond/NativeScanResultTest.java b/wifi/tests/src/android/net/wifi/wificond/NativeScanResultTest.java new file mode 100644 index 000000000000..06f12f7f37ea --- /dev/null +++ b/wifi/tests/src/android/net/wifi/wificond/NativeScanResultTest.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.wificond; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import android.os.Parcel; + +import androidx.test.filters.SmallTest; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.BitSet; + +/** + * Unit tests for {@link android.net.wifi.wificond.NativeScanResult}. + */ +@SmallTest +public class NativeScanResultTest { + + private static final byte[] TEST_SSID = + new byte[] {'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'}; + private static final byte[] TEST_BSSID = + new byte[] {(byte) 0x12, (byte) 0xef, (byte) 0xa1, + (byte) 0x2c, (byte) 0x97, (byte) 0x8b}; + private static final byte[] TEST_INFO_ELEMENT = + new byte[] {(byte) 0x01, (byte) 0x03, (byte) 0x12, (byte) 0xbe, (byte) 0xff}; + private static final int TEST_FREQUENCY = 2456; + private static final int TEST_SIGNAL_MBM = -45; + private static final long TEST_TSF = 34455441; + private static final BitSet TEST_CAPABILITY = new BitSet(16) {{ set(2); set(5); }}; + private static final boolean TEST_ASSOCIATED = true; + private static final int[] RADIO_CHAIN_IDS = { 0, 1 }; + private static final int[] RADIO_CHAIN_LEVELS = { -56, -65 }; + + /** + * NativeScanResult object can be serialized and deserialized, while keeping the + * values unchanged. + */ + @Test + public void canSerializeAndDeserialize() { + NativeScanResult scanResult = new NativeScanResult(); + scanResult.ssid = TEST_SSID; + scanResult.bssid = TEST_BSSID; + scanResult.infoElement = TEST_INFO_ELEMENT; + scanResult.frequency = TEST_FREQUENCY; + scanResult.signalMbm = TEST_SIGNAL_MBM; + scanResult.tsf = TEST_TSF; + scanResult.capability = TEST_CAPABILITY; + scanResult.associated = TEST_ASSOCIATED; + scanResult.radioChainInfos = new ArrayList<>(Arrays.asList( + new RadioChainInfo(RADIO_CHAIN_IDS[0], RADIO_CHAIN_LEVELS[0]), + new RadioChainInfo(RADIO_CHAIN_IDS[1], RADIO_CHAIN_LEVELS[1]))); + Parcel parcel = Parcel.obtain(); + scanResult.writeToParcel(parcel, 0); + // Rewind the pointer to the head of the parcel. + parcel.setDataPosition(0); + NativeScanResult scanResultDeserialized = NativeScanResult.CREATOR.createFromParcel(parcel); + + assertArrayEquals(scanResult.ssid, scanResultDeserialized.ssid); + assertArrayEquals(scanResult.bssid, scanResultDeserialized.bssid); + assertArrayEquals(scanResult.infoElement, scanResultDeserialized.infoElement); + assertEquals(scanResult.frequency, scanResultDeserialized.frequency); + assertEquals(scanResult.signalMbm, scanResultDeserialized.signalMbm); + assertEquals(scanResult.tsf, scanResultDeserialized.tsf); + assertEquals(scanResult.capability, scanResultDeserialized.capability); + assertEquals(scanResult.associated, scanResultDeserialized.associated); + assertTrue(scanResult.radioChainInfos.containsAll(scanResultDeserialized.radioChainInfos)); + } +} diff --git a/wifi/tests/src/android/net/wifi/wificond/PnoSettingsTest.java b/wifi/tests/src/android/net/wifi/wificond/PnoSettingsTest.java new file mode 100644 index 000000000000..775acc70d134 --- /dev/null +++ b/wifi/tests/src/android/net/wifi/wificond/PnoSettingsTest.java @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.wificond; + +import static org.junit.Assert.assertEquals; + +import android.os.Parcel; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; + +/** + * Unit tests for {@link android.net.wifi.wificond.PnoSettingsResult}. + */ +@SmallTest +public class PnoSettingsTest { + + private static final byte[] TEST_SSID_1 = + new byte[] {'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'}; + private static final byte[] TEST_SSID_2 = + new byte[] {'A', 'n', 'd', 'r', 'o', 'i', 'd', 'T', 'e', 's', 't'}; + private static final int[] TEST_FREQUENCIES_1 = {}; + private static final int[] TEST_FREQUENCIES_2 = {2500, 5124}; + private static final int TEST_INTERVAL_MS = 30000; + private static final int TEST_MIN_2G_RSSI = -60; + private static final int TEST_MIN_5G_RSSI = -65; + private static final int TEST_VALUE = 42; + + private PnoNetwork mPnoNetwork1; + private PnoNetwork mPnoNetwork2; + + @Before + public void setUp() { + mPnoNetwork1 = new PnoNetwork(); + mPnoNetwork1.ssid = TEST_SSID_1; + mPnoNetwork1.isHidden = true; + mPnoNetwork1.frequencies = TEST_FREQUENCIES_1; + + mPnoNetwork2 = new PnoNetwork(); + mPnoNetwork2.ssid = TEST_SSID_2; + mPnoNetwork2.isHidden = false; + mPnoNetwork2.frequencies = TEST_FREQUENCIES_2; + } + + /** + * PnoSettings object can be serialized and deserialized, while keeping the + * values unchanged. + */ + @Test + public void canSerializeAndDeserialize() { + PnoSettings pnoSettings = new PnoSettings(); + pnoSettings.intervalMs = TEST_INTERVAL_MS; + pnoSettings.min2gRssi = TEST_MIN_2G_RSSI; + pnoSettings.min5gRssi = TEST_MIN_5G_RSSI; + pnoSettings.pnoNetworks = new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2)); + + Parcel parcel = Parcel.obtain(); + pnoSettings.writeToParcel(parcel, 0); + // Rewind the pointer to the head of the parcel. + parcel.setDataPosition(0); + PnoSettings pnoSettingsDeserialized = PnoSettings.CREATOR.createFromParcel(parcel); + + assertEquals(pnoSettings, pnoSettingsDeserialized); + assertEquals(pnoSettings.hashCode(), pnoSettingsDeserialized.hashCode()); + } + + /** + * Tests usage of {@link PnoSettings} as a HashMap key type. + */ + @Test + public void testAsHashMapKey() { + PnoSettings pnoSettings1 = new PnoSettings(); + pnoSettings1.intervalMs = TEST_INTERVAL_MS; + pnoSettings1.min2gRssi = TEST_MIN_2G_RSSI; + pnoSettings1.min5gRssi = TEST_MIN_5G_RSSI; + pnoSettings1.pnoNetworks = new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2)); + + PnoSettings pnoSettings2 = new PnoSettings(); + pnoSettings2.intervalMs = TEST_INTERVAL_MS; + pnoSettings2.min2gRssi = TEST_MIN_2G_RSSI; + pnoSettings2.min5gRssi = TEST_MIN_5G_RSSI; + pnoSettings2.pnoNetworks = new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2)); + + assertEquals(pnoSettings1, pnoSettings2); + assertEquals(pnoSettings1.hashCode(), pnoSettings2.hashCode()); + + HashMap map = new HashMap<>(); + map.put(pnoSettings1, TEST_VALUE); + + assertEquals(TEST_VALUE, map.get(pnoSettings2).intValue()); + } +} diff --git a/wifi/tests/src/android/net/wifi/wificond/SingleScanSettingsTest.java b/wifi/tests/src/android/net/wifi/wificond/SingleScanSettingsTest.java new file mode 100644 index 000000000000..ef598397c12e --- /dev/null +++ b/wifi/tests/src/android/net/wifi/wificond/SingleScanSettingsTest.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.wificond; + +import static org.junit.Assert.assertEquals; + +import android.net.wifi.IWifiScannerImpl; +import android.os.Parcel; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; + +/** + * Unit tests for {@link android.net.wifi.wificond.SingleScanSettingsResult}. + */ +@SmallTest +public class SingleScanSettingsTest { + + private static final byte[] TEST_SSID_1 = + new byte[] {'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'}; + private static final byte[] TEST_SSID_2 = + new byte[] {'A', 'n', 'd', 'r', 'o', 'i', 'd', 'T', 'e', 's', 't'}; + private static final int TEST_FREQUENCY_1 = 2456; + private static final int TEST_FREQUENCY_2 = 5215; + private static final int TEST_VALUE = 42; + + private ChannelSettings mChannelSettings1; + private ChannelSettings mChannelSettings2; + private HiddenNetwork mHiddenNetwork1; + private HiddenNetwork mHiddenNetwork2; + + @Before + public void setUp() { + mChannelSettings1 = new ChannelSettings(); + mChannelSettings1.frequency = TEST_FREQUENCY_1; + mChannelSettings2 = new ChannelSettings(); + mChannelSettings2.frequency = TEST_FREQUENCY_2; + + mHiddenNetwork1 = new HiddenNetwork(); + mHiddenNetwork1.ssid = TEST_SSID_1; + mHiddenNetwork2 = new HiddenNetwork(); + mHiddenNetwork2.ssid = TEST_SSID_2; + } + + /** + * SingleScanSettings object can be serialized and deserialized, while keeping the + * values unchanged. + */ + @Test + public void canSerializeAndDeserialize() { + SingleScanSettings scanSettings = new SingleScanSettings(); + scanSettings.scanType = IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY; + + scanSettings.channelSettings = + new ArrayList<>(Arrays.asList(mChannelSettings1, mChannelSettings2)); + scanSettings.hiddenNetworks = + new ArrayList<>(Arrays.asList(mHiddenNetwork1, mHiddenNetwork2)); + + Parcel parcel = Parcel.obtain(); + scanSettings.writeToParcel(parcel, 0); + // Rewind the pointer to the head of the parcel. + parcel.setDataPosition(0); + SingleScanSettings scanSettingsDeserialized = + SingleScanSettings.CREATOR.createFromParcel(parcel); + + assertEquals(scanSettings, scanSettingsDeserialized); + assertEquals(scanSettings.hashCode(), scanSettingsDeserialized.hashCode()); + } + + /** + * Tests usage of {@link SingleScanSettings} as a HashMap key type. + */ + @Test + public void testAsHashMapKey() { + SingleScanSettings scanSettings1 = new SingleScanSettings(); + scanSettings1.scanType = IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY; + scanSettings1.channelSettings = + new ArrayList<>(Arrays.asList(mChannelSettings1, mChannelSettings2)); + scanSettings1.hiddenNetworks = + new ArrayList<>(Arrays.asList(mHiddenNetwork1, mHiddenNetwork2)); + + SingleScanSettings scanSettings2 = new SingleScanSettings(); + scanSettings2.scanType = IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY; + scanSettings2.channelSettings = + new ArrayList<>(Arrays.asList(mChannelSettings1, mChannelSettings2)); + scanSettings2.hiddenNetworks = + new ArrayList<>(Arrays.asList(mHiddenNetwork1, mHiddenNetwork2)); + + assertEquals(scanSettings1, scanSettings2); + assertEquals(scanSettings1.hashCode(), scanSettings2.hashCode()); + + HashMap map = new HashMap<>(); + map.put(scanSettings1, TEST_VALUE); + + assertEquals(TEST_VALUE, map.get(scanSettings2).intValue()); + } +} -- cgit v1.2.3 From 7aeebcafadf63be9877a4b29e446fddd270e3daf Mon Sep 17 00:00:00 2001 From: David Su Date: Fri, 13 Dec 2019 15:13:03 -0800 Subject: Add FrameworksWifiApiTests to MTS Bug: 146163587 Test: compiles Change-Id: Id871be333e0216892e49adeb4a8080262439b6b9 --- wifi/tests/Android.mk | 4 +++- wifi/tests/AndroidTest.xml | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'wifi') diff --git a/wifi/tests/Android.mk b/wifi/tests/Android.mk index 3453d6ec827f..d2c385b46eb1 100644 --- a/wifi/tests/Android.mk +++ b/wifi/tests/Android.mk @@ -59,6 +59,8 @@ LOCAL_JAVA_LIBRARIES := \ LOCAL_PACKAGE_NAME := FrameworksWifiApiTests LOCAL_PRIVATE_PLATFORM_APIS := true -LOCAL_COMPATIBILITY_SUITE := device-tests +LOCAL_COMPATIBILITY_SUITE := \ + device-tests \ + mts \ include $(BUILD_PACKAGE) diff --git a/wifi/tests/AndroidTest.xml b/wifi/tests/AndroidTest.xml index cae19e46c6af..987fee79fefd 100644 --- a/wifi/tests/AndroidTest.xml +++ b/wifi/tests/AndroidTest.xml @@ -14,7 +14,7 @@ limitations under the License. --> - + -- cgit v1.2.3 From 094ba71ffb05cb66b2447891419e0cbf556823e0 Mon Sep 17 00:00:00 2001 From: David Su Date: Fri, 13 Dec 2019 15:14:04 -0800 Subject: FrameworksWifiApiTests runtest.sh: do not run with root `adb root` is unnecessary, remove. Bug: 146163587 Test: frameworks/base/wifi/tests/runtests.sh Change-Id: Ibcdca8e6557d7ff6d17c7dc97ad16466b6bdbf4d --- wifi/tests/runtests.sh | 1 - 1 file changed, 1 deletion(-) (limited to 'wifi') diff --git a/wifi/tests/runtests.sh b/wifi/tests/runtests.sh index 7a0dfb08fcfe..4024371dd97d 100755 --- a/wifi/tests/runtests.sh +++ b/wifi/tests/runtests.sh @@ -16,7 +16,6 @@ $ANDROID_BUILD_TOP/build/soong/soong_ui.bash --make-mode MODULES-IN-frameworks-b set -x # print commands -adb root adb wait-for-device TARGET_ARCH=$($ANDROID_BUILD_TOP/build/soong/soong_ui.bash --dumpvar-mode TARGET_ARCH) -- cgit v1.2.3 From c6c5327471188475df836965084499bc3e8e1368 Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Fri, 13 Dec 2019 18:30:13 -0800 Subject: [AWARE] Add API to expose supported cipher suites Provide a new Aware capabilities API which exposes the supported cipher suites. These cipher suites are used to negotiate the data- path. The framework automatially selects the strongest cipher suite when it initiates a negotiation. Bug: 145697276 Bug: 111446262 Test: atest com.android.server.wifi.aware Test: (CTS) atest SingleDeviceTest Change-Id: Ic9ec46a2aa578fa97cb174ca9745c5320ff07b52 --- .../android/net/wifi/aware/Characteristics.java | 37 +++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/aware/Characteristics.java b/wifi/java/android/net/wifi/aware/Characteristics.java index e2cf4dc02659..d5fd48e9e7b3 100644 --- a/wifi/java/android/net/wifi/aware/Characteristics.java +++ b/wifi/java/android/net/wifi/aware/Characteristics.java @@ -16,10 +16,14 @@ package android.net.wifi.aware; +import android.annotation.IntDef; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + /** * The characteristics of the Wi-Fi Aware implementation. */ @@ -31,6 +35,8 @@ public final class Characteristics implements Parcelable { "key_max_service_specific_info_length"; /** @hide */ public static final String KEY_MAX_MATCH_FILTER_LENGTH = "key_max_match_filter_length"; + /** @hide */ + public static final String KEY_SUPPORTED_CIPHER_SUITES = "key_supported_cipher_suites"; private Bundle mCharacteristics = new Bundle(); @@ -71,12 +77,41 @@ public final class Characteristics implements Parcelable { * {@link PublishConfig.Builder#setMatchFilter(java.util.List)} and * {@link SubscribeConfig.Builder#setMatchFilter(java.util.List)}. * - * @return A positive integer, maximum legngth of byte array for Aware discovery match filter. + * @return A positive integer, maximum length of byte array for Aware discovery match filter. */ public int getMaxMatchFilterLength() { return mCharacteristics.getInt(KEY_MAX_MATCH_FILTER_LENGTH); } + /** @hide */ + @IntDef(flag = true, prefix = { "WIFI_AWARE_CIPHER_SUITE_" }, value = { + WIFI_AWARE_CIPHER_SUITE_NCS_SK_128, + WIFI_AWARE_CIPHER_SUITE_NCS_SK_256, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface WifiAwareCipherSuites {} + + /** + * Wi-Fi Aware supported ciphier suite representing NCS SK 128: 128 bit shared-key. + */ + public static final int WIFI_AWARE_CIPHER_SUITE_NCS_SK_128 = 1 << 0; + + /** + * Wi-Fi Aware supported ciphier suite representing NCS SK 256: 256 bit shared-key. + */ + public static final int WIFI_AWARE_CIPHER_SUITE_NCS_SK_256 = 1 << 1; + + /** + * Returns the set of cipher suites supported by the device for use in Wi-Fi Aware data-paths. + * The device automatically picks the strongest cipher suite when initiating a data-path setup. + * + * @return A set of flags from {@link #WIFI_AWARE_CIPHER_SUITE_NCS_SK_128}, or + * {@link #WIFI_AWARE_CIPHER_SUITE_NCS_SK_256}. + */ + public @WifiAwareCipherSuites int getSupportedCipherSuites() { + return mCharacteristics.getInt(KEY_SUPPORTED_CIPHER_SUITES); + } + @Override public void writeToParcel(Parcel dest, int flags) { dest.writeBundle(mCharacteristics); -- cgit v1.2.3 From 754fcc20c5b631bd5818e6c9fe3cc83dda2fd1b9 Mon Sep 17 00:00:00 2001 From: David Su Date: Wed, 4 Sep 2019 14:31:58 -0700 Subject: Split framework-wifi.jar out of framework.jar Build framework-wifi against framework-minus-apex. Build framework-minus-apex against "framework-wifi-stubs". Build framework.jar against framework-wifi since a few bundled apps/tests still use @hide Wifi APIs. framework-minus-apex now only has @SystemApi dependencies on framework-wifi. Bug: 140299412 Test: atest FrameworksWifiTest FrameworksWifiApiTests Change-Id: I3ada1dc7e8186c566cfbf7ad3d3b49878ae9860d --- wifi/Android.bp | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 wifi/Android.bp (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp new file mode 100644 index 000000000000..e0b9ff336093 --- /dev/null +++ b/wifi/Android.bp @@ -0,0 +1,97 @@ +// 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. + + +filegroup { + name: "framework-wifi-updatable-sources", + srcs: [ + "java/**/*.java", + "java/**/*.aidl", + ], + exclude_srcs: [ + ":framework-wifi-non-updatable-sources" + ], + path: "java", +} + +filegroup { + name: "framework-wifi-non-updatable-sources", + srcs: [ + // TODO(b/146011398) package android.net.wifi is now split amongst 2 jars: framework.jar and + // framework-wifi.jar. This is not a good idea, should move WifiNetworkScoreCache + // to a separate package. + "java/android/net/wifi/WifiNetworkScoreCache.java", + "java/android/net/wifi/WifiCondManager.java", + "java/android/net/wifi/wificond/*.java", + ":libwificond_ipc_aidl", + ], +} + +java_library { + name: "framework-wifi", + sdk_version: "core_platform", // TODO(b/140299412) should be core_current + libs: [ + "framework-minus-apex", // TODO(b/140299412) should be framework-system-stubs + ], + srcs: [ + ":framework-wifi-updatable-sources", + ], + installable: true, + optimize: { + enabled: false + } +} + +metalava_wifi_docs_args = + "--hide-package com.android.server " + + "--error UnhiddenSystemApi " + + "--hide RequiresPermission " + + "--hide MissingPermission " + + "--hide BroadcastBehavior " + + "--hide HiddenSuperclass " + + "--hide DeprecationMismatch " + + "--hide UnavailableSymbol " + + "--hide SdkConstant " + + "--hide HiddenTypeParameter " + + "--hide Todo --hide Typo " + + "--hide HiddenTypedefConstant " + + "--show-annotation android.annotation.SystemApi " + +droidstubs { + name: "framework-wifi-stubs-srcs", + srcs: [ + ":framework-annotations", + ":framework-wifi-updatable-sources", + ], + aidl: { + include_dirs: ["frameworks/base/core/java"], + }, + args: metalava_wifi_docs_args, + sdk_version: "core_current", + libs: ["android_system_stubs_current"], +} + +java_library { + name: "framework-wifi-stubs", + srcs: [":framework-wifi-stubs-srcs"], + aidl: { + export_include_dirs: [ + "java", + ], + }, + sdk_version: "core_current", + libs: ["android_system_stubs_current"], + installable: false, +} + -- cgit v1.2.3 From 130441b131fc0978f75a042059661484d1aa3e9d Mon Sep 17 00:00:00 2001 From: David Su Date: Sat, 14 Dec 2019 21:37:20 -0800 Subject: Create WifiAnnotations and jarjar into framework @IntDef annotations defined in the Wifi module are @hide and cannot be referenced from the rest of framework. Create a separate class for Wifi annotations that can be jarjar'ed into external clients. Bug: 140299412 Test: compiles Change-Id: I5beac976b4d12fb2c01f46cb46f9c54ab54618ea --- wifi/Android.bp | 5 +++ wifi/java/android/net/wifi/WifiAnnotations.java | 51 +++++++++++++++++++++++++ wifi/java/android/net/wifi/WifiCondManager.java | 6 +-- wifi/java/android/net/wifi/WifiScanner.java | 20 +--------- 4 files changed, 60 insertions(+), 22 deletions(-) create mode 100644 wifi/java/android/net/wifi/WifiAnnotations.java (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index e0b9ff336093..26064cbc2fb1 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -38,6 +38,11 @@ filegroup { ], } +filegroup { + name: "framework-wifi-annotations", + srcs: ["java/android/net/wifi/WifiAnnotations.java"], +} + java_library { name: "framework-wifi", sdk_version: "core_platform", // TODO(b/140299412) should be core_current diff --git a/wifi/java/android/net/wifi/WifiAnnotations.java b/wifi/java/android/net/wifi/WifiAnnotations.java new file mode 100644 index 000000000000..4a7dee138971 --- /dev/null +++ b/wifi/java/android/net/wifi/WifiAnnotations.java @@ -0,0 +1,51 @@ +/* + * 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.annotation.IntDef; +import android.annotation.StringDef; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Wifi annotations meant to be statically linked into client modules, since they cannot be + * exposed as @SystemApi. + * + * e.g. {@link IntDef}, {@link StringDef} + * + * @hide + */ +public final class WifiAnnotations { + private WifiAnnotations() {} + + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"SCAN_TYPE_"}, value = { + WifiScanner.SCAN_TYPE_LOW_LATENCY, + WifiScanner.SCAN_TYPE_LOW_POWER, + WifiScanner.SCAN_TYPE_HIGH_ACCURACY}) + public @interface ScanType {} + + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"WIFI_BAND_"}, value = { + WifiScanner.WIFI_BAND_UNSPECIFIED, + WifiScanner.WIFI_BAND_24_GHZ, + WifiScanner.WIFI_BAND_5_GHZ, + WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY, + WifiScanner.WIFI_BAND_6_GHZ}) + public @interface WifiBandBasic {} +} diff --git a/wifi/java/android/net/wifi/WifiCondManager.java b/wifi/java/android/net/wifi/WifiCondManager.java index 9ae7e3a89706..c05ba347ab5c 100644 --- a/wifi/java/android/net/wifi/WifiCondManager.java +++ b/wifi/java/android/net/wifi/WifiCondManager.java @@ -725,7 +725,7 @@ public class WifiCondManager implements IBinder.DeathRecipient { /** * Return scan type for the parcelable {@link SingleScanSettings} */ - private static int getScanType(@WifiScanner.ScanType int scanType) { + private static int getScanType(@WifiAnnotations.ScanType int scanType) { switch (scanType) { case WifiScanner.SCAN_TYPE_LOW_LATENCY: return IWifiScannerImpl.SCAN_TYPE_LOW_SPAN; @@ -746,7 +746,7 @@ public class WifiCondManager implements IBinder.DeathRecipient { * @param hiddenNetworkSSIDs List of hidden networks to be scanned for. * @return Returns true on success. */ - public boolean scan(@NonNull String ifaceName, @WifiScanner.ScanType int scanType, + public boolean scan(@NonNull String ifaceName, @WifiAnnotations.ScanType int scanType, Set freqs, List hiddenNetworkSSIDs) { IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); if (scannerImpl == null) { @@ -868,7 +868,7 @@ public class WifiCondManager implements IBinder.DeathRecipient { * @return frequencies vector of valid frequencies (MHz), or null for error. * @throws IllegalArgumentException if band is not recognized. */ - public int [] getChannelsForBand(@WifiScanner.WifiBandBasic int band) { + public int [] getChannelsForBand(@WifiAnnotations.WifiBandBasic int band) { if (mWificond == null) { Log.e(TAG, "No valid wificond scanner interface handler"); return null; diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index 760497b727cd..8fedda48aa0d 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -89,16 +89,6 @@ public class WifiScanner { /** 6 GHz band */ public static final int WIFI_BAND_6_GHZ = 1 << WIFI_BAND_INDEX_6_GHZ; - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = {"WIFI_BAND_"}, value = { - WIFI_BAND_UNSPECIFIED, - WIFI_BAND_24_GHZ, - WIFI_BAND_5_GHZ, - WIFI_BAND_5_GHZ_DFS_ONLY, - WIFI_BAND_6_GHZ}) - public @interface WifiBandBasic {} - /** * Combination of bands * Note that those are only the common band combinations, @@ -249,14 +239,6 @@ public class WifiScanner { */ public static final int REPORT_EVENT_NO_BATCH = (1 << 2); - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = {"SCAN_TYPE_"}, value = { - SCAN_TYPE_LOW_LATENCY, - SCAN_TYPE_LOW_POWER, - SCAN_TYPE_HIGH_ACCURACY}) - public @interface ScanType {} - /** * Optimize the scan for lower latency. * @see ScanSettings#type @@ -354,7 +336,7 @@ public class WifiScanner { * {@link #SCAN_TYPE_HIGH_ACCURACY}. * Default value: {@link #SCAN_TYPE_LOW_LATENCY}. */ - @ScanType + @WifiAnnotations.ScanType @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public int type = SCAN_TYPE_LOW_LATENCY; /** -- cgit v1.2.3 From 64c392c86f108e76f21c000e93c9ef1dc6884ced Mon Sep 17 00:00:00 2001 From: Ahmed ElArabawy Date: Fri, 6 Dec 2019 22:59:04 -0800 Subject: Wifi: Update AP Bands to include 6GHz This commit updates the frequency bands to include 6GHz band. The bands are represented as bitmask to allow combination of them. Bug: 139354972 Test: atest com.android.wifi.server Change-Id: Ib9c2cfa0f29489ca8e94c8e60f87a929cfea9158 --- .../java/android/net/wifi/SoftApConfiguration.java | 88 +++++++++++++++++----- wifi/java/android/net/wifi/WifiManager.java | 9 ++- .../android/net/wifi/SoftApConfigurationTest.java | 4 +- 3 files changed, 75 insertions(+), 26 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java index d755053e60d2..fd8a924bdbee 100644 --- a/wifi/java/android/net/wifi/SoftApConfiguration.java +++ b/wifi/java/android/net/wifi/SoftApConfiguration.java @@ -60,32 +60,77 @@ public final class SoftApConfiguration implements Parcelable { * @hide */ @SystemApi - public static final int BAND_2GHZ = 0; + public static final int BAND_2GHZ = 1 << 0; /** * 5GHz band. * @hide */ @SystemApi - public static final int BAND_5GHZ = 1; + public static final int BAND_5GHZ = 1 << 1; /** - * Device is allowed to choose the optimal band (2Ghz or 5Ghz) based on device capability, + * 6GHz band. + * @hide + */ + @SystemApi + public static final int BAND_6GHZ = 1 << 2; + + /** + * Device is allowed to choose the optimal band (2Ghz, 5Ghz, 6Ghz) based on device capability, * operating country code and current radio conditions. * @hide */ @SystemApi - public static final int BAND_ANY = -1; + public static final int BAND_ANY = BAND_2GHZ | BAND_5GHZ | BAND_6GHZ; /** @hide */ @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = { "BAND_TYPE_" }, value = { + @IntDef(flag = true, prefix = { "BAND_TYPE_" }, value = { BAND_2GHZ, BAND_5GHZ, - BAND_ANY, + BAND_6GHZ, }) public @interface BandType {} + private static boolean isBandValid(@BandType int band) { + return ((band != 0) && ((band & ~BAND_ANY) == 0)); + } + + private static final int MIN_CH_2G_BAND = 1; + private static final int MAX_CH_2G_BAND = 14; + private static final int MIN_CH_5G_BAND = 34; + private static final int MAX_CH_5G_BAND = 196; + private static final int MIN_CH_6G_BAND = 1; + private static final int MAX_CH_6G_BAND = 253; + + + + private static boolean isChannelBandPairValid(int channel, @BandType int band) { + switch (band) { + case BAND_2GHZ: + if (channel < MIN_CH_2G_BAND || channel > MAX_CH_2G_BAND) { + return false; + } + break; + + case BAND_5GHZ: + if (channel < MIN_CH_5G_BAND || channel > MAX_CH_5G_BAND) { + return false; + } + break; + + case BAND_6GHZ: + if (channel < MIN_CH_6G_BAND || channel > MAX_CH_6G_BAND) { + return false; + } + break; + default: + return false; + } + return true; + } + /** * SSID for the AP, or null for a framework-determined SSID. */ @@ -439,39 +484,42 @@ public final class SoftApConfiguration implements Parcelable { *

    *

  • If not set, defaults to BAND_2GHZ {@link @BandType}.
  • * - * @param band One of the band types from {@link @BandType}. + * @param band One or combination of the band types from {@link @BandType}. * @return Builder for chaining. */ @NonNull public Builder setBand(@BandType int band) { - switch (band) { - case BAND_2GHZ: - break; - case BAND_5GHZ: - break; - case BAND_ANY: - break; - default: - throw new IllegalArgumentException("Invalid band type"); + if (!isBandValid(band)) { + throw new IllegalArgumentException("Invalid band type"); } mBand = band; + // Since band preference is specified, no specific channel is selected. + mChannel = 0; return this; } /** - * Specifies the channel for the AP. + * Specifies the channel and associated band for the AP. * * The channel which AP resides on. Valid channels are country dependent. - * Use the special channel value 0 to have the framework auto-select a valid channel - * from the band configured with {@link #setBand(@BandType int)}. + * The default for the channel is a the special value 0 to have the framework + * auto-select a valid channel from the band configured with + * {@link #setBand(@BandType int)}. + * Note, since 6GHz band use the same channel numbering of 2.4GHz and 5GHZ bands, + * the caller needs to pass the band containing the selected channel. * *

    *

  • If not set, defaults to 0.
  • * @param channel operating channel of the AP. + * @param band containing this channel. * @return Builder for chaining. */ @NonNull - public Builder setChannel(int channel) { + public Builder setChannel(int channel, @BandType int band) { + if (!isChannelBandPairValid(channel, band)) { + throw new IllegalArgumentException("Invalid band type"); + } + mBand = band; mChannel = channel; return this; } diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 9691bda2cf73..7327326175a3 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1153,6 +1153,7 @@ public class WifiManager { @UnsupportedAppUsage public static final int RSSI_LEVELS = 5; + //TODO (b/146346676): This needs to be removed, not used in the code. /** * Auto settings in the driver. The driver could choose to operate on both * 2.4 GHz and 5 GHz or make a dynamic decision on selecting the band. @@ -2600,10 +2601,10 @@ public class WifiManager { * Check if the device is dual mode capable i.e. supports concurrent STA + Soft AP. * * If the device is dual mode capable, it may require conversion of the user's Soft AP band - * selection {@link WifiConfiguration#apBand} from {@link WifiConfiguration#AP_BAND_5GHZ} to - * {@link WifiConfiguration#AP_BAND_ANY}, since if the device is connected to a 5GHz DFS - * channel as a STA, it may be unable to honor a request to start Soft AP on the same DFS - * channel. + * selection {@link SoftApConfiguration#mBand} from {@link SoftApConfiguration#BAND_5GHZ} to + * include also {@link SoftApConfiguration#BAND_2GHZ}, since if the device is connected to a + * 5GHz DFS channel as a STA, it may be unable to honor a request to start Soft AP on the same + * DFS channel. * * @return {@code true} if dual mode STA + AP is supported by this device, {@code false} * otherwise. diff --git a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java index b8d3e413f1d2..60125e372cd5 100644 --- a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java @@ -91,13 +91,13 @@ public class SoftApConfigurationTest { SoftApConfiguration original = new SoftApConfiguration.Builder() .setWpa2Passphrase("secretsecret") .setBand(SoftApConfiguration.BAND_ANY) - .setChannel(149) + .setChannel(149, SoftApConfiguration.BAND_5GHZ) .setHiddenSsid(true) .build(); assertThat(original.getWpa2Passphrase()).isEqualTo("secretsecret"); assertThat(original.getSecurityType()).isEqualTo( SoftApConfiguration.SECURITY_TYPE_WPA2_PSK); - assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_ANY); + assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_5GHZ); assertThat(original.getChannel()).isEqualTo(149); assertThat(original.isHiddenSsid()).isEqualTo(true); -- cgit v1.2.3 From 0c2ebe2bbf46122c2b8c8a46a06460c91f13f11d Mon Sep 17 00:00:00 2001 From: Anton Hansson Date: Tue, 17 Dec 2019 10:03:52 +0000 Subject: Make wifi module use shared metalava args Also (hopefully) temporarily filter out com.android.server from the stubs, as the wifi module has a server class in it. Bug: 137191822 Test: m Change-Id: I2c62fc16c676305e9ee739285f49656075f38b97 --- wifi/Android.bp | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 26064cbc2fb1..08115ecb6b2b 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -58,21 +58,6 @@ java_library { } } -metalava_wifi_docs_args = - "--hide-package com.android.server " + - "--error UnhiddenSystemApi " + - "--hide RequiresPermission " + - "--hide MissingPermission " + - "--hide BroadcastBehavior " + - "--hide HiddenSuperclass " + - "--hide DeprecationMismatch " + - "--hide UnavailableSymbol " + - "--hide SdkConstant " + - "--hide HiddenTypeParameter " + - "--hide Todo --hide Typo " + - "--hide HiddenTypedefConstant " + - "--show-annotation android.annotation.SystemApi " - droidstubs { name: "framework-wifi-stubs-srcs", srcs: [ @@ -82,7 +67,7 @@ droidstubs { aidl: { include_dirs: ["frameworks/base/core/java"], }, - args: metalava_wifi_docs_args, + defaults: [ "framework-module-stubs-defaults-systemapi" ], sdk_version: "core_current", libs: ["android_system_stubs_current"], } -- cgit v1.2.3 From 8f24cd9db311c5b474bce0ec2bdc9e48c4a3e193 Mon Sep 17 00:00:00 2001 From: David Su Date: Tue, 17 Dec 2019 21:08:00 -0800 Subject: Expose getters for WifiP2pConfig fields CTS cannot test @hide fields, need public getters. Bug: 146463839 Test: atest WifiP2pConfigTest Change-Id: Iaa6cb069fb445d65778c8c6b6a238a82160d376f --- wifi/java/android/net/wifi/p2p/WifiP2pConfig.java | 35 +++++++++++++++++------ wifi/java/android/net/wifi/p2p/WifiP2pGroup.java | 7 ++--- 2 files changed, 28 insertions(+), 14 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java index 495b1bb9ba82..c9bca4f20f03 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java @@ -48,21 +48,29 @@ public class WifiP2pConfig implements Parcelable { */ public WpsInfo wps; - /** - * The network name of a group, should be configured by helper method - */ + /** Get the network name of this P2P configuration, or null if unset. */ + @Nullable + public String getNetworkName() { + return networkName; + } + /** @hide */ public String networkName = ""; - /** - * The passphrase of a group, should be configured by helper method - */ + /** Get the passphrase of this P2P configuration, or null if unset. */ + @Nullable + public String getPassphrase() { + return passphrase; + } + /** @hide */ public String passphrase = ""; - /** - * The required band for Group Owner - */ + /** Get the required band for the group owner. */ + public int getGroupOwnerBand() { + return groupOwnerBand; + } + /** @hide */ public int groupOwnerBand = GROUP_OWNER_BAND_AUTO; @@ -123,6 +131,15 @@ public class WifiP2pConfig implements Parcelable { @UnsupportedAppUsage public int netId = WifiP2pGroup.PERSISTENT_NET_ID; + /** + * Get the network ID of this P2P configuration. + * @return either a non-negative network ID, or one of {@link WifiP2pGroup#PERSISTENT_NET_ID} or + * {@link WifiP2pGroup#TEMPORARY_NET_ID}. + */ + public int getNetworkId() { + return netId; + } + public WifiP2pConfig() { //set defaults wps = new WpsInfo(); diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java index f9d1266cf804..d8c50f2ed5f8 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java @@ -39,18 +39,15 @@ public class WifiP2pGroup implements Parcelable { /** * The temporary network id. - * - * @hide + * @see #getNetworkId() */ - @UnsupportedAppUsage public static final int TEMPORARY_NET_ID = -1; /** * The persistent network id. * If a matching persistent profile is found, use it. * Otherwise, create a new persistent profile. - * - * @hide + * @see #getNetworkId() */ public static final int PERSISTENT_NET_ID = -2; -- cgit v1.2.3 From 3db58a6149c43d9a8e8517e14fd4518b25699f4f Mon Sep 17 00:00:00 2001 From: lesl Date: Mon, 16 Dec 2019 17:04:54 +0800 Subject: wifi: remove softap restore method since new API supported in R New API: retrieveSoftApBackupData/restoreSoftApBackupData Bug: 144368124 Test: atest frameworks/base/wifi/tests/ Change-Id: I0f417f1e035ee92ee163c6f5ae86a4b1833fa6c8 --- wifi/java/android/net/wifi/WifiConfiguration.java | 55 ---------------------- .../android/net/wifi/WifiConfigurationTest.java | 30 ------------ 2 files changed, 85 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index d068fc681ae7..580c34a5cd6a 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -36,14 +36,9 @@ import android.os.SystemClock; import android.os.UserHandle; import android.telephony.TelephonyManager; import android.text.TextUtils; -import android.util.BackupUtils; import android.util.Log; import android.util.SparseArray; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Arrays; @@ -2768,54 +2763,4 @@ public class WifiConfiguration implements Parcelable { return new WifiConfiguration[size]; } }; - - /** - * Serialize the Soft AP configuration contained in this object for backup. - * @hide - */ - @NonNull - // TODO(b/144368124): this method should be removed once we migrate to SoftApConfiguration - public byte[] getBytesForBackup() throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DataOutputStream out = new DataOutputStream(baos); - - out.writeInt(BACKUP_VERSION); - BackupUtils.writeString(out, SSID); - out.writeInt(apBand); - out.writeInt(apChannel); - BackupUtils.writeString(out, preSharedKey); - out.writeInt(getAuthType()); - out.writeBoolean(hiddenSSID); - return baos.toByteArray(); - } - - /** - * Deserialize a byte array containing Soft AP configuration into a WifiConfiguration object. - * @return The deserialized WifiConfiguration containing Soft AP configuration, or null if - * the version contains a bad dataset e.g. Version 1 - * @throws BackupUtils.BadVersionException if the version is unrecognized - * @hide - */ - @Nullable - // TODO(b/144368124): this method should be removed once we migrate to SoftApConfiguration - public static WifiConfiguration getWifiConfigFromBackup(@NonNull DataInputStream in) - throws IOException, BackupUtils.BadVersionException { - WifiConfiguration config = new WifiConfiguration(); - int version = in.readInt(); - if (version < 1 || version > BACKUP_VERSION) { - throw new BackupUtils.BadVersionException("Unknown Backup Serialization Version"); - } - - if (version == 1) return null; // Version 1 is a bad dataset. - - config.SSID = BackupUtils.readString(in); - config.apBand = in.readInt(); - config.apChannel = in.readInt(); - config.preSharedKey = BackupUtils.readString(in); - config.allowedKeyManagement.set(in.readInt()); - if (version >= 3) { - config.hiddenSSID = in.readBoolean(); - } - return config; - } } diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java index 7e38e147427f..1f0eae715d1f 100644 --- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java @@ -32,9 +32,6 @@ import androidx.test.filters.SmallTest; import org.junit.Before; import org.junit.Test; -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; - /** * Unit tests for {@link android.net.wifi.WifiConfiguration}. */ @@ -195,33 +192,6 @@ public class WifiConfigurationTest { assertEquals(config.updateIdentifier, copyConfig.updateIdentifier); } - /** - * Verifies that the serialization/de-serialization for softap config works. - */ - @Test - public void testSoftApConfigBackupAndRestore() throws Exception { - WifiConfiguration config = new WifiConfiguration(); - config.SSID = "TestAP"; - config.apBand = WifiConfiguration.AP_BAND_5GHZ; - config.apChannel = 40; - config.allowedKeyManagement.set(KeyMgmt.WPA2_PSK); - config.preSharedKey = "TestPsk"; - config.hiddenSSID = true; - - byte[] data = config.getBytesForBackup(); - ByteArrayInputStream bais = new ByteArrayInputStream(data); - DataInputStream in = new DataInputStream(bais); - WifiConfiguration restoredConfig = WifiConfiguration.getWifiConfigFromBackup(in); - - assertEquals(config.SSID, restoredConfig.SSID); - assertEquals(config.preSharedKey, restoredConfig.preSharedKey); - assertEquals(config.getAuthType(), restoredConfig.getAuthType()); - assertEquals(config.apBand, restoredConfig.apBand); - assertEquals(config.apChannel, restoredConfig.apChannel); - assertEquals(config.hiddenSSID, restoredConfig.hiddenSSID); - } - - /** * Verifies that getKeyIdForCredentials returns the expected string for Enterprise networks * @throws Exception -- cgit v1.2.3 From 5eac974c590a33d09a5486042aca7ee0e7f795ad Mon Sep 17 00:00:00 2001 From: David Su Date: Wed, 18 Dec 2019 15:16:24 -0800 Subject: Convert FrameworksWifiApiTests mk to bp Generated using androidmk script. Bug: 146513037 Test: atest FrameworksWifiApiTests Change-Id: Idb2bc2cf1413d2051408aecd9a824ef281ebe6dc --- wifi/tests/Android.bp | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++ wifi/tests/Android.mk | 66 -------------------------------------------------- 2 files changed, 67 insertions(+), 66 deletions(-) create mode 100644 wifi/tests/Android.bp delete mode 100644 wifi/tests/Android.mk (limited to 'wifi') diff --git a/wifi/tests/Android.bp b/wifi/tests/Android.bp new file mode 100644 index 000000000000..f54d40eb0887 --- /dev/null +++ b/wifi/tests/Android.bp @@ -0,0 +1,67 @@ +// Copyright (C) 2016 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. + +// Make test APK +// ============================================================ + +// This list is generated from the java source files in this module +// The list is a comma separated list of class names with * matching zero or more characters. +// Example: +// Input files: src/com/android/server/wifi/Test.java src/com/android/server/wifi/AnotherTest.java +// Generated exclude list: com.android.server.wifi.Test*,com.android.server.wifi.AnotherTest* + +// Filter all src files to just java files +local_java_files = ["__builtin_func:filter %.java <'LOCAL_SRC_FILES' unset>"] +// Transform java file names into full class names. +// This only works if the class name matches the file name and the directory structure +// matches the package. +local_classes = ["__builtin_func:subst / . __builtin_func:patsubst src/%.java % <'local_java_files' unset>"] +// Convert class name list to jacoco exclude list +// This appends a * to all classes and replace the space separators with commas. +// These patterns will match all classes in this module and their inner classes. +jacoco_exclude = ["__builtin_func:subst <'space' unset> <'comma' unset> __builtin_func:patsubst % %* <'local_classes' unset>"] + +jacoco_include = ["android.net.wifi.*"] + +android_test { + name: "FrameworksWifiApiTests", + + srcs: ["**/*.java"], + + jacoco: { + include_filter: jacoco_include, + exclude_filter: jacoco_exclude, + }, + + static_libs: [ + "androidx.test.rules", + "core-test-rules", + "guava", + "mockito-target-minus-junit4", + "net-tests-utils", + "frameworks-base-testutils", + "truth-prebuilt", + ], + + libs: [ + "android.test.runner", + "android.test.base", + ], + + platform_apis: true, + test_suites: [ + "device-tests", + "mts", + ], +} diff --git a/wifi/tests/Android.mk b/wifi/tests/Android.mk deleted file mode 100644 index d2c385b46eb1..000000000000 --- a/wifi/tests/Android.mk +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright (C) 2016 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. - -LOCAL_PATH:= $(call my-dir) - -# Make test APK -# ============================================================ -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := tests - -LOCAL_SRC_FILES := $(call all-subdir-java-files) - -# This list is generated from the java source files in this module -# The list is a comma separated list of class names with * matching zero or more characters. -# Example: -# Input files: src/com/android/server/wifi/Test.java src/com/android/server/wifi/AnotherTest.java -# Generated exclude list: com.android.server.wifi.Test*,com.android.server.wifi.AnotherTest* - -# Filter all src files to just java files -local_java_files := $(filter %.java,$(LOCAL_SRC_FILES)) -# Transform java file names into full class names. -# This only works if the class name matches the file name and the directory structure -# matches the package. -local_classes := $(subst /,.,$(patsubst src/%.java,%,$(local_java_files))) -# Convert class name list to jacoco exclude list -# This appends a * to all classes and replace the space separators with commas. -# These patterns will match all classes in this module and their inner classes. -jacoco_exclude := $(subst $(space),$(comma),$(patsubst %,%*,$(local_classes))) - -jacoco_include := android.net.wifi.* - -LOCAL_JACK_COVERAGE_INCLUDE_FILTER := $(jacoco_include) -LOCAL_JACK_COVERAGE_EXCLUDE_FILTER := $(jacoco_exclude) - -LOCAL_STATIC_JAVA_LIBRARIES := \ - androidx.test.rules \ - core-test-rules \ - guava \ - mockito-target-minus-junit4 \ - net-tests-utils \ - frameworks-base-testutils \ - truth-prebuilt \ - -LOCAL_JAVA_LIBRARIES := \ - android.test.runner \ - android.test.base \ - -LOCAL_PACKAGE_NAME := FrameworksWifiApiTests -LOCAL_PRIVATE_PLATFORM_APIS := true -LOCAL_COMPATIBILITY_SUITE := \ - device-tests \ - mts \ - -include $(BUILD_PACKAGE) -- cgit v1.2.3 From 90ed10582dea42c660feda7bfc243d81d953fe6e Mon Sep 17 00:00:00 2001 From: David Su Date: Wed, 18 Dec 2019 18:20:28 -0800 Subject: framework-wifi: default build rule for tests Create a java_default build rule for tests that need to build against @hide APIs from framework-wifi. Visibility is restricted to select tests for now. Also restricted visibility for framework-wifi itself. Bug: 146513037 Test: compiles Change-Id: Ia6dec8cf0202e0417d54a480c1715190b03e5e3e --- wifi/Android.bp | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 08115ecb6b2b..d7a85c5f75cc 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -43,11 +43,19 @@ filegroup { srcs: ["java/android/net/wifi/WifiAnnotations.java"], } +// list of tests that are allowed to access @hide APIs from framework-wifi +test_access_hidden_api_whitelist = [ + "//frameworks/base/wifi/tests", + "//frameworks/opt/net/wifi/tests/wifitests:__subpackages__", +] + java_library { name: "framework-wifi", - sdk_version: "core_platform", // TODO(b/140299412) should be core_current + // TODO(b/140299412) should be core_current once we build against framework-system-stubs + sdk_version: "core_platform", libs: [ - "framework-minus-apex", // TODO(b/140299412) should be framework-system-stubs + // TODO(b/140299412) should be framework-system-stubs once we fix all @hide dependencies + "framework-minus-apex", ], srcs: [ ":framework-wifi-updatable-sources", @@ -55,7 +63,11 @@ java_library { installable: true, optimize: { enabled: false - } + }, + visibility: [ + "//frameworks/base", // TODO(b/140299412) remove once all dependencies are fixed + "//frameworks/opt/net/wifi/service:__subpackages__", + ] + test_access_hidden_api_whitelist, } droidstubs { @@ -85,3 +97,16 @@ java_library { installable: false, } +// defaults for tests that need to build against framework-wifi's @hide APIs +java_defaults { + name: "framework-wifi-test-defaults", + sdk_version: "core_platform", // tests can use @CorePlatformApi's + libs: [ + "framework-wifi", + "framework-minus-apex", + + // if sdk_version="" this gets automatically included, but here we need to add manually. + "framework-res", + ], + visibility: test_access_hidden_api_whitelist, +} -- cgit v1.2.3 From ff7b3326cd83bc16e2d4e0235792738b03fb9a5b Mon Sep 17 00:00:00 2001 From: David Su Date: Wed, 18 Dec 2019 18:31:11 -0800 Subject: FrameworksWifiApiTests: build against framework-wifi Give Wifi API unit tests access to @hide APIs in framework-wifi. Bug: 146513037 Test: atest FrameworksWifiApiTests Change-Id: I6755d75e3556bf940c79a2105af5cbc5f3def147 --- wifi/tests/Android.bp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/tests/Android.bp b/wifi/tests/Android.bp index f54d40eb0887..9e3acc9107ce 100644 --- a/wifi/tests/Android.bp +++ b/wifi/tests/Android.bp @@ -37,6 +37,8 @@ jacoco_include = ["android.net.wifi.*"] android_test { name: "FrameworksWifiApiTests", + defaults: ["framework-wifi-test-defaults"], + srcs: ["**/*.java"], jacoco: { @@ -59,7 +61,6 @@ android_test { "android.test.base", ], - platform_apis: true, test_suites: [ "device-tests", "mts", -- cgit v1.2.3 From 3c21193fa1b498bac6855c30d2c6164b772c4f42 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Mon, 16 Sep 2019 15:31:05 +0800 Subject: Wifi: add WAPI constants and fields This changes adds below WAPI codes: * WAPI feature, proto, key management, cipher * WAPI suite field to WifiConfiguration * New builder method for WAPI network in WifiNetworkSuggestion. Bug: 139257562 Test: atest FrameworksWifiApiTests Change-Id: I5d6edec45a535f483be3319183671c90eef8539a --- wifi/java/android/net/wifi/ScanResult.java | 23 ++++++ wifi/java/android/net/wifi/WifiConfiguration.java | 69 ++++++++++++++++-- .../android/net/wifi/WifiEnterpriseConfig.java | 67 +++++++++++++++++- wifi/java/android/net/wifi/WifiManager.java | 9 +++ .../android/net/wifi/WifiNetworkSuggestion.java | 59 +++++++++++++++- .../android/net/wifi/WifiConfigurationTest.java | 10 +++ .../src/android/net/wifi/WifiManagerTest.java | 14 ++++ .../net/wifi/WifiNetworkSuggestionTest.java | 82 ++++++++++++++++++++++ 8 files changed, 324 insertions(+), 9 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java index 729ef61f0e4d..83a18008919d 100644 --- a/wifi/java/android/net/wifi/ScanResult.java +++ b/wifi/java/android/net/wifi/ScanResult.java @@ -101,6 +101,12 @@ public class ScanResult implements Parcelable { */ public static final int PROTOCOL_OSEN = 3; + /** + * @hide + * Security protocol type: WAPI. + */ + public static final int PROTOCOL_WAPI = 4; + /** * @hide * No security key management scheme. @@ -167,6 +173,18 @@ public class ScanResult implements Parcelable { * Security key management scheme: OWE in transition mode. */ public static final int KEY_MGMT_OWE_TRANSITION = 12; + /** + * @hide + * Security key management scheme: WAPI_PSK. + */ + @SystemApi + public static final int KEY_MGMT_WAPI_PSK = 13; + /** + * @hide + * Security key management scheme: WAPI_CERT. + */ + @SystemApi + public static final int KEY_MGMT_WAPI_CERT = 14; /** * @hide * No cipher suite. @@ -192,6 +210,11 @@ public class ScanResult implements Parcelable { * Cipher suite: GCMP */ public static final int CIPHER_GCMP_256 = 4; + /** + * @hide + * Cipher suite: SMS4 + */ + public static final int CIPHER_SMS4 = 5; /** * The detected signal level in dBm, also known as the RSSI. diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index d068fc681ae7..31eb77332d7e 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -123,7 +123,9 @@ public class WifiConfiguration implements Parcelable { OWE, SUITE_B_192, WPA_PSK_SHA256, - WPA_EAP_SHA256}) + WPA_EAP_SHA256, + WAPI_PSK, + WAPI_CERT}) public @interface KeyMgmtScheme {} /** WPA is not used; plaintext or static WEP could be used. */ @@ -190,11 +192,26 @@ public class WifiConfiguration implements Parcelable { */ public static final int WPA_EAP_SHA256 = 12; + /** + * WAPI pre-shared key (requires {@code preSharedKey} to be specified). + * @hide + */ + @SystemApi + public static final int WAPI_PSK = 13; + + /** + * WAPI certificate to be specified. + * @hide + */ + @SystemApi + public static final int WAPI_CERT = 14; + public static final String varName = "key_mgmt"; public static final String[] strings = { "NONE", "WPA_PSK", "WPA_EAP", "IEEE8021X", "WPA2_PSK", "OSEN", "FT_PSK", "FT_EAP", - "SAE", "OWE", "SUITE_B_192", "WPA_PSK_SHA256", "WPA_EAP_SHA256" }; + "SAE", "OWE", "SUITE_B_192", "WPA_PSK_SHA256", "WPA_EAP_SHA256", + "WAPI_PSK", "WAPI_CERT" }; } /** @@ -215,9 +232,14 @@ public class WifiConfiguration implements Parcelable { */ public static final int OSEN = 2; + /** + * WAPI Protocol + */ + public static final int WAPI = 3; + public static final String varName = "proto"; - public static final String[] strings = { "WPA", "RSN", "OSEN" }; + public static final String[] strings = { "WPA", "RSN", "OSEN", "WAPI" }; } /** @@ -260,10 +282,14 @@ public class WifiConfiguration implements Parcelable { * AES in Galois/Counter Mode */ public static final int GCMP_256 = 3; + /** + * SMS4 cipher for WAPI + */ + public static final int SMS4 = 4; public static final String varName = "pairwise"; - public static final String[] strings = { "NONE", "TKIP", "CCMP", "GCMP_256" }; + public static final String[] strings = { "NONE", "TKIP", "CCMP", "GCMP_256", "SMS4" }; } /** @@ -301,12 +327,17 @@ public class WifiConfiguration implements Parcelable { * AES in Galois/Counter Mode */ public static final int GCMP_256 = 5; + /** + * SMS4 cipher for WAPI + */ + public static final int SMS4 = 6; public static final String varName = "group"; public static final String[] strings = { /* deprecated */ "WEP40", /* deprecated */ "WEP104", - "TKIP", "CCMP", "GTK_NOT_USED", "GCMP_256" }; + "TKIP", "CCMP", "GTK_NOT_USED", "GCMP_256", + "SMS4" }; } /** @@ -388,6 +419,10 @@ public class WifiConfiguration implements Parcelable { public static final int SECURITY_TYPE_EAP_SUITE_B = 5; /** @hide */ public static final int SECURITY_TYPE_OWE = 6; + /** @hide */ + public static final int SECURITY_TYPE_WAPI_PSK = 7; + /** @hide */ + public static final int SECURITY_TYPE_WAPI_CERT = 8; /** @hide */ @Retention(RetentionPolicy.SOURCE) @@ -398,7 +433,9 @@ public class WifiConfiguration implements Parcelable { SECURITY_TYPE_EAP, SECURITY_TYPE_SAE, SECURITY_TYPE_EAP_SUITE_B, - SECURITY_TYPE_OWE + SECURITY_TYPE_OWE, + SECURITY_TYPE_WAPI_PSK, + SECURITY_TYPE_WAPI_CERT }) public @interface SecurityType {} @@ -450,6 +487,18 @@ public class WifiConfiguration implements Parcelable { allowedKeyManagement.set(WifiConfiguration.KeyMgmt.OWE); requirePMF = true; break; + case SECURITY_TYPE_WAPI_PSK: + allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WAPI_PSK); + allowedProtocols.set(WifiConfiguration.Protocol.WAPI); + allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.SMS4); + allowedGroupCiphers.set(WifiConfiguration.GroupCipher.SMS4); + break; + case SECURITY_TYPE_WAPI_CERT: + allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WAPI_CERT); + allowedProtocols.set(WifiConfiguration.Protocol.WAPI); + allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.SMS4); + allowedGroupCiphers.set(WifiConfiguration.GroupCipher.SMS4); + break; default: throw new IllegalArgumentException("unknown security type " + securityType); } @@ -2350,6 +2399,10 @@ public class WifiConfiguration implements Parcelable { return KeyMgmt.OWE; } else if (allowedKeyManagement.get(KeyMgmt.SUITE_B_192)) { return KeyMgmt.SUITE_B_192; + } else if (allowedKeyManagement.get(KeyMgmt.WAPI_PSK)) { + return KeyMgmt.WAPI_PSK; + } else if (allowedKeyManagement.get(KeyMgmt.WAPI_CERT)) { + return KeyMgmt.WAPI_CERT; } return KeyMgmt.NONE; } @@ -2388,6 +2441,10 @@ public class WifiConfiguration implements Parcelable { key = SSID + KeyMgmt.strings[KeyMgmt.SAE]; } else if (allowedKeyManagement.get(KeyMgmt.SUITE_B_192)) { key = SSID + KeyMgmt.strings[KeyMgmt.SUITE_B_192]; + } else if (allowedKeyManagement.get(KeyMgmt.WAPI_PSK)) { + key = SSID + KeyMgmt.strings[KeyMgmt.WAPI_PSK]; + } else if (allowedKeyManagement.get(KeyMgmt.WAPI_CERT)) { + key = SSID + KeyMgmt.strings[KeyMgmt.WAPI_CERT]; } else { key = SSID + KeyMgmt.strings[KeyMgmt.NONE]; } diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java index 66b0590511fc..7a59a4f9be30 100644 --- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java +++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java @@ -41,6 +41,36 @@ import java.util.Map; */ public class WifiEnterpriseConfig implements Parcelable { + /** Key prefix for WAPI AS certificates. */ + public static final String WAPI_AS_CERTIFICATE = "WAPIAS_"; + + /** Key prefix for WAPI user certificates. */ + public static final String WAPI_USER_CERTIFICATE = "WAPIUSR_"; + + /** + * Intent extra: name for WAPI AS certificates + */ + public static final String EXTRA_WAPI_AS_CERTIFICATE_NAME = + "android.net.wifi.extra.WAPI_AS_CERTIFICATE_NAME"; + + /** + * Intent extra: data for WAPI AS certificates + */ + public static final String EXTRA_WAPI_AS_CERTIFICATE_DATA = + "android.net.wifi.extra.WAPI_AS_CERTIFICATE_DATA"; + + /** + * Intent extra: name for WAPI AS certificates + */ + public static final String EXTRA_WAPI_USER_CERTIFICATE_NAME = + "android.net.wifi.extra.WAPI_USER_CERTIFICATE_NAME"; + + /** + * Intent extra: data for WAPI AS certificates + */ + public static final String EXTRA_WAPI_USER_CERTIFICATE_DATA = + "android.net.wifi.extra.WAPI_USER_CERTIFICATE_DATA"; + /** @hide */ public static final String EMPTY_VALUE = "NULL"; /** @hide */ @@ -61,6 +91,7 @@ public class WifiEnterpriseConfig implements Parcelable { public static final String DOM_SUFFIX_MATCH_KEY = "domain_suffix_match"; /** @hide */ public static final String OPP_KEY_CACHING = "proactive_key_caching"; + /** * String representing the keystore OpenSSL ENGINE's ID. * @hide @@ -130,6 +161,8 @@ public class WifiEnterpriseConfig implements Parcelable { public static final String PLMN_KEY = "plmn"; /** @hide */ public static final String CA_CERT_ALIAS_DELIMITER = " "; + /** @hide */ + public static final String WAPI_CERT_SUITE_KEY = "wapi_cert_suite"; /** * Do not use OCSP stapling (TLS certificate status extension) @@ -348,9 +381,12 @@ public class WifiEnterpriseConfig implements Parcelable { public static final int AKA_PRIME = 6; /** Hotspot 2.0 r2 OSEN */ public static final int UNAUTH_TLS = 7; + /** WAPI Certificate */ + public static final int WAPI_CERT = 8; /** @hide */ public static final String[] strings = - { "PEAP", "TLS", "TTLS", "PWD", "SIM", "AKA", "AKA'", "WFA-UNAUTH-TLS" }; + { "PEAP", "TLS", "TTLS", "PWD", "SIM", "AKA", "AKA'", "WFA-UNAUTH-TLS", + "WAPI_CERT" }; /** Prevent initialization */ private Eap() {} @@ -494,6 +530,10 @@ public class WifiEnterpriseConfig implements Parcelable { public void setEapMethod(int eapMethod) { switch (eapMethod) { /** Valid methods */ + case Eap.WAPI_CERT: + mEapMethod = eapMethod; + setPhase2Method(Phase2.NONE); + break; case Eap.TLS: case Eap.UNAUTH_TLS: setPhase2Method(Phase2.NONE); @@ -1313,4 +1353,29 @@ public class WifiEnterpriseConfig implements Parcelable { } return false; } + + /** + * Set the WAPI certificate suite name on wpa_supplicant. + * + * If this field is not specified, WAPI-CERT uses ASU ID from WAI packet + * as the certificate suite name automatically. + * + * @param wapiCertSuite The name for WAPI certificate suite, or null/empty string to clear. + * @hide + */ + @SystemApi + public void setWapiCertSuite(@Nullable String wapiCertSuite) { + setFieldValue(WAPI_CERT_SUITE_KEY, wapiCertSuite); + } + + /** + * Get the WAPI certificate suite name + * @return the certificate suite name + * @hide + */ + @Nullable + @SystemApi + public String getWapiCertSuite() { + return getFieldValue(WAPI_CERT_SUITE_KEY); + } } diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 9691bda2cf73..ed77fe525987 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -2225,6 +2225,8 @@ public class WifiManager { public static final long WIFI_FEATURE_MBO = 0x800000000L; // MBO Support /** @hide */ public static final long WIFI_FEATURE_OCE = 0x1000000000L; // OCE Support + /** @hide */ + public static final long WIFI_FEATURE_WAPI = 0x2000000000L; // WAPI private long getSupportedFeatures() { try { @@ -4960,6 +4962,13 @@ public class WifiManager { return isFeatureSupported(WIFI_FEATURE_DPP); } + /** + * @return true if this device supports WAPI. + */ + public boolean isWapiSupported() { + return isFeatureSupported(WIFI_FEATURE_WAPI); + } + /** * Gets the factory Wi-Fi MAC addresses. * @return Array of String representing Wi-Fi MAC addresses sorted lexically or an empty Array diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java index 9fd29ae8d14a..9c1475ffc8cd 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java +++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java @@ -122,6 +122,16 @@ public final class WifiNetworkSuggestion implements Parcelable { * Whether the setIsUserAllowedToManuallyConnect have been called. */ private boolean mIsUserAllowedBeenSet; + /** + * Pre-shared key for use with WAPI-PSK networks. + */ + private @Nullable String mWapiPskPassphrase; + + /** + * The enterprise configuration details specifying the EAP method, + * certificates and other settings associated with the WAPI networks. + */ + private @Nullable WifiEnterpriseConfig mWapiEnterpriseConfig; public Builder() { mSsid = null; @@ -140,6 +150,8 @@ public final class WifiNetworkSuggestion implements Parcelable { mIsUserAllowedBeenSet = false; mPriority = UNASSIGNED_PRIORITY; mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID; + mWapiPskPassphrase = null; + mWapiEnterpriseConfig = null; } /** @@ -293,6 +305,39 @@ public final class WifiNetworkSuggestion implements Parcelable { return this; } + /** + * Set the ASCII WAPI passphrase for this network. Needed for authenticating to + * WAPI-PSK networks. + * + * @param passphrase passphrase of the network. + * @return Instance of {@link Builder} to enable chaining of the builder method. + * @throws IllegalArgumentException if the passphrase is not ASCII encodable. + * + */ + public @NonNull Builder setWapiPassphrase(@NonNull String passphrase) { + checkNotNull(passphrase); + final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder(); + if (!asciiEncoder.canEncode(passphrase)) { + throw new IllegalArgumentException("passphrase not ASCII encodable"); + } + mWapiPskPassphrase = passphrase; + return this; + } + + /** + * Set the associated enterprise configuration for this network. Needed for authenticating + * to WAPI-CERT networks. See {@link WifiEnterpriseConfig} for description. + * + * @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}. + * @return Instance of {@link Builder} to enable chaining of the builder method. + */ + public @NonNull Builder setWapiEnterpriseConfig( + @NonNull WifiEnterpriseConfig enterpriseConfig) { + checkNotNull(enterpriseConfig); + mWapiEnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig); + return this; + } + /** * Specifies whether this represents a hidden network. *

    @@ -413,6 +458,13 @@ public final class WifiNetworkSuggestion implements Parcelable { configuration.enterpriseConfig = mWpa3EnterpriseConfig; } else if (mIsEnhancedOpen) { // OWE network configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OWE); + } else if (!TextUtils.isEmpty(mWapiPskPassphrase)) { // WAPI-PSK network. + configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_WAPI_PSK); + // WifiConfiguration.preSharedKey needs quotes around ASCII password. + configuration.preSharedKey = "\"" + mWapiPskPassphrase + "\""; + } else if (mWapiEnterpriseConfig != null) { // WAPI-CERT network + configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_WAPI_CERT); + configuration.enterpriseConfig = mWapiEnterpriseConfig; } else { // Open network configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OPEN); } @@ -446,13 +498,16 @@ public final class WifiNetworkSuggestion implements Parcelable { numSecurityTypes += mIsEnhancedOpen ? 1 : 0; numSecurityTypes += !TextUtils.isEmpty(mWpa2PskPassphrase) ? 1 : 0; numSecurityTypes += !TextUtils.isEmpty(mWpa3SaePassphrase) ? 1 : 0; + numSecurityTypes += !TextUtils.isEmpty(mWapiPskPassphrase) ? 1 : 0; numSecurityTypes += mWpa2EnterpriseConfig != null ? 1 : 0; numSecurityTypes += mWpa3EnterpriseConfig != null ? 1 : 0; + numSecurityTypes += mWapiEnterpriseConfig != null ? 1 : 0; numSecurityTypes += mPasspointConfiguration != null ? 1 : 0; if (numSecurityTypes > 1) { throw new IllegalStateException("only one of setIsEnhancedOpen, setWpa2Passphrase," - + "setWpa3Passphrase, setWpa2EnterpriseConfig, setWpa3EnterpriseConfig" - + "or setPasspointConfig can be invoked for network suggestion"); + + " setWpa3Passphrase, setWpa2EnterpriseConfig, setWpa3EnterpriseConfig" + + " setWapiPassphrase, setWapiCertSuite, setIsWapiCertSuiteAuto" + + " or setPasspointConfig can be invoked for network suggestion"); } } diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java index 7e38e147427f..8089e23bb4c0 100644 --- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java @@ -317,6 +317,16 @@ public class WifiConfigurationTest { config.allowedKeyManagement.clear(); config.allowedKeyManagement.set(KeyMgmt.NONE); assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.NONE], config.getSsidAndSecurityTypeString()); + + config.allowedKeyManagement.clear(); + config.allowedKeyManagement.set(KeyMgmt.WAPI_PSK); + assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.WAPI_PSK], + config.getSsidAndSecurityTypeString()); + + config.allowedKeyManagement.clear(); + config.allowedKeyManagement.set(KeyMgmt.WAPI_CERT); + assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.WAPI_CERT], + config.getSsidAndSecurityTypeString()); } /** diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 62ff9f65a1a7..4a46744a2d32 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -2075,4 +2075,18 @@ public class WifiManagerTest { verify(mWifiService).calculateSignalLevel(Integer.MAX_VALUE); assertEquals(4, actual); } + + /* + * Test behavior of isWapiSupported + * @throws Exception + */ + @Test + public void testIsWapiSupported() throws Exception { + when(mWifiService.getSupportedFeatures()) + .thenReturn(new Long(WifiManager.WIFI_FEATURE_WAPI)); + assertTrue(mWifiManager.isWapiSupported()); + when(mWifiService.getSupportedFeatures()) + .thenReturn(new Long(~WifiManager.WIFI_FEATURE_WAPI)); + assertFalse(mWifiManager.isWapiSupported()); + } } diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java index 04aaa0bbcad0..4cdc4bc2ad48 100644 --- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java +++ b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java @@ -39,6 +39,7 @@ public class WifiNetworkSuggestionTest { private static final String TEST_SSID_1 = "\"Test1234\""; private static final String TEST_PRESHARED_KEY = "Test123"; private static final String TEST_FQDN = "fqdn"; + private static final String TEST_WAPI_CERT_SUITE = "suite"; /** * Validate correctness of WifiNetworkSuggestion object created by @@ -192,6 +193,87 @@ public class WifiNetworkSuggestionTest { assertTrue(suggestion.isUserAllowedToManuallyConnect); } + /** + * Validate correctness of WifiNetworkSuggestion object created by + * {@link WifiNetworkSuggestion.Builder#build()} for WAPI-PSK network. + */ + @Test + public void testWifiNetworkSuggestionBuilderForWapiPskNetwork() { + WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() + .setSsid(TEST_SSID) + .setWapiPassphrase(TEST_PRESHARED_KEY) + .build(); + + assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID); + assertTrue(suggestion.wifiConfiguration.allowedKeyManagement + .get(WifiConfiguration.KeyMgmt.WAPI_PSK)); + assertTrue(suggestion.wifiConfiguration.allowedPairwiseCiphers + .get(WifiConfiguration.PairwiseCipher.SMS4)); + assertTrue(suggestion.wifiConfiguration.allowedGroupCiphers + .get(WifiConfiguration.GroupCipher.SMS4)); + assertEquals("\"" + TEST_PRESHARED_KEY + "\"", + suggestion.wifiConfiguration.preSharedKey); + } + + + /** + * Validate correctness of WifiNetworkSuggestion object created by + * {@link WifiNetworkSuggestion.Builder#build()} for WAPI-CERT network. + */ + @Test + public void testWifiNetworkSuggestionBuilderForWapiCertNetwork() { + WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); + enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.WAPI_CERT); + enterpriseConfig.setWapiCertSuite(TEST_WAPI_CERT_SUITE); + WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() + .setSsid(TEST_SSID) + .setWapiEnterpriseConfig(enterpriseConfig) + .build(); + + assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID); + assertTrue(suggestion.wifiConfiguration.allowedKeyManagement + .get(WifiConfiguration.KeyMgmt.WAPI_CERT)); + assertTrue(suggestion.wifiConfiguration.allowedPairwiseCiphers + .get(WifiConfiguration.PairwiseCipher.SMS4)); + assertTrue(suggestion.wifiConfiguration.allowedGroupCiphers + .get(WifiConfiguration.GroupCipher.SMS4)); + assertNull(suggestion.wifiConfiguration.preSharedKey); + assertNotNull(suggestion.wifiConfiguration.enterpriseConfig); + assertEquals(WifiEnterpriseConfig.Eap.WAPI_CERT, + suggestion.wifiConfiguration.enterpriseConfig.getEapMethod()); + assertEquals(TEST_WAPI_CERT_SUITE, + suggestion.wifiConfiguration.enterpriseConfig.getWapiCertSuite()); + } + + /** + * Validate correctness of WifiNetworkSuggestion object created by + * {@link WifiNetworkSuggestion.Builder#build()} for WAPI-CERT network + * which selects the certificate suite automatically. + */ + @Test + public void testWifiNetworkSuggestionBuilderForWapiCertAutoNetwork() { + WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); + enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.WAPI_CERT); + WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() + .setSsid(TEST_SSID) + .setWapiEnterpriseConfig(enterpriseConfig) + .build(); + + assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID); + assertTrue(suggestion.wifiConfiguration.allowedKeyManagement + .get(WifiConfiguration.KeyMgmt.WAPI_CERT)); + assertTrue(suggestion.wifiConfiguration.allowedPairwiseCiphers + .get(WifiConfiguration.PairwiseCipher.SMS4)); + assertTrue(suggestion.wifiConfiguration.allowedGroupCiphers + .get(WifiConfiguration.GroupCipher.SMS4)); + assertNull(suggestion.wifiConfiguration.preSharedKey); + assertNotNull(suggestion.wifiConfiguration.enterpriseConfig); + assertEquals(WifiEnterpriseConfig.Eap.WAPI_CERT, + suggestion.wifiConfiguration.enterpriseConfig.getEapMethod()); + assertEquals("", + suggestion.wifiConfiguration.enterpriseConfig.getWapiCertSuite()); + } + /** * Validate correctness of WifiNetworkSuggestion object created by * {@link WifiNetworkSuggestion.Builder#build()} for Passpoint network which requires -- cgit v1.2.3 From 434fe602b8c06c609a2be79f855f20dbe5200c40 Mon Sep 17 00:00:00 2001 From: David Su Date: Wed, 18 Dec 2019 21:22:21 -0800 Subject: ConnectivityManagerTest: grant access to Wifi @hide APIs Bug: 146513037 Test: atest ConnectivityManagerTest Change-Id: If2a65abede0ab76b0435c252a893df9791645607 --- wifi/Android.bp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index d7a85c5f75cc..80703b8bf841 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -47,6 +47,8 @@ filegroup { test_access_hidden_api_whitelist = [ "//frameworks/base/wifi/tests", "//frameworks/opt/net/wifi/tests/wifitests:__subpackages__", + + "//frameworks/base/core/tests/ConnectivityManagerTest", ] java_library { -- cgit v1.2.3 From fd0886a81896739447da5ef0d34581815c502bd0 Mon Sep 17 00:00:00 2001 From: David Su Date: Wed, 18 Dec 2019 21:56:46 -0800 Subject: WifiTrackerLibTests: grant access to Wifi @hide APIs Bug: 146513037 Test: atest WifiTrackerLibTests Change-Id: I27662aafa325db333a0547fe371009842c0711ad --- wifi/Android.bp | 1 + 1 file changed, 1 insertion(+) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 80703b8bf841..866dead89ea3 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -49,6 +49,7 @@ test_access_hidden_api_whitelist = [ "//frameworks/opt/net/wifi/tests/wifitests:__subpackages__", "//frameworks/base/core/tests/ConnectivityManagerTest", + "//frameworks/opt/net/wifi/libs/WifiTrackerLib/tests", ] java_library { -- cgit v1.2.3 From 5abc6d980dfb815b962a0568f7715fee1b1268de Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Wed, 18 Dec 2019 10:54:28 -0800 Subject: [WIFICOND] Formalize the wificond AIDL interface The wificond daemon provides an interface for the framework to interact with the operating system when managing Wi-Fi. Since wificond is outside the mainline module, the AIDL interface has to be formalized as an API surface. Bug: 140062898 Test: atest android.net.wifi Test: atest com.android.server.wifi.aware Test: (CTS) atest android.net.wifi.cts Test: scan, association, SoftAP operations manually tested, kill wificond Change-Id: Iee0fef6a454fdd84b1d0c59516d4746ddc2a4ce5 --- wifi/Android.bp | 1 - wifi/java/android/net/wifi/SoftApInfo.java | 25 +- wifi/java/android/net/wifi/WifiAnnotations.java | 12 + wifi/java/android/net/wifi/WifiCondManager.java | 983 --------------- .../net/wifi/wificond/NativeScanResult.java | 158 ++- .../net/wifi/wificond/NativeWifiClient.java | 33 +- .../java/android/net/wifi/wificond/PnoNetwork.java | 116 +- .../android/net/wifi/wificond/PnoSettings.java | 159 ++- .../android/net/wifi/wificond/RadioChainInfo.java | 43 +- .../android/net/wifi/wificond/WifiCondManager.java | 1165 ++++++++++++++++++ .../src/android/net/wifi/WifiCondManagerTest.java | 1281 -------------------- .../android/net/wifi/wificond/PnoSettingsTest.java | 38 +- .../net/wifi/wificond/WifiCondManagerTest.java | 1247 +++++++++++++++++++ 13 files changed, 2872 insertions(+), 2389 deletions(-) delete mode 100644 wifi/java/android/net/wifi/WifiCondManager.java create mode 100644 wifi/java/android/net/wifi/wificond/WifiCondManager.java delete mode 100644 wifi/tests/src/android/net/wifi/WifiCondManagerTest.java create mode 100644 wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 08115ecb6b2b..fb1f8661370b 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -32,7 +32,6 @@ filegroup { // framework-wifi.jar. This is not a good idea, should move WifiNetworkScoreCache // to a separate package. "java/android/net/wifi/WifiNetworkScoreCache.java", - "java/android/net/wifi/WifiCondManager.java", "java/android/net/wifi/wificond/*.java", ":libwificond_ipc_aidl", ], diff --git a/wifi/java/android/net/wifi/SoftApInfo.java b/wifi/java/android/net/wifi/SoftApInfo.java index 375a9774f570..24ed8effe471 100644 --- a/wifi/java/android/net/wifi/SoftApInfo.java +++ b/wifi/java/android/net/wifi/SoftApInfo.java @@ -16,15 +16,12 @@ package android.net.wifi; -import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; import java.util.Objects; /** @@ -85,26 +82,12 @@ public final class SoftApInfo implements Parcelable { */ public static final int CHANNEL_WIDTH_160MHZ = 6; - /** - * @hide - */ - @IntDef(prefix = { "CHANNEL_WIDTH_" }, value = { - CHANNEL_WIDTH_INVALID, - CHANNEL_WIDTH_20MHZ_NOHT, - CHANNEL_WIDTH_20MHZ, - CHANNEL_WIDTH_40MHZ, - CHANNEL_WIDTH_80MHZ, - CHANNEL_WIDTH_80MHZ_PLUS_MHZ, - CHANNEL_WIDTH_160MHZ, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface Bandwidth {} /** The frequency which AP resides on. */ private int mFrequency = 0; - @Bandwidth + @WifiAnnotations.Bandwidth private int mBandwidth = CHANNEL_WIDTH_INVALID; /** @@ -127,9 +110,9 @@ public final class SoftApInfo implements Parcelable { * * @return One of {@link #CHANNEL_WIDTH_20MHZ}, {@link #CHANNEL_WIDTH_40MHZ}, * {@link #CHANNEL_WIDTH_80MHZ}, {@link #CHANNEL_WIDTH_160MHZ}, - * {@link #CHANNEL_WIDTH_80MHZ_PLUS_MHZ} or {@link #CHANNEL_WIDTH_UNKNOWN}. + * {@link #CHANNEL_WIDTH_80MHZ_PLUS_MHZ} or {@link #CHANNEL_WIDTH_INVALID}. */ - @Bandwidth + @WifiAnnotations.Bandwidth public int getBandwidth() { return mBandwidth; } @@ -138,7 +121,7 @@ public final class SoftApInfo implements Parcelable { * Set AP Channel bandwidth. * @hide */ - public void setBandwidth(@Bandwidth int bandwidth) { + public void setBandwidth(@WifiAnnotations.Bandwidth int bandwidth) { mBandwidth = bandwidth; } diff --git a/wifi/java/android/net/wifi/WifiAnnotations.java b/wifi/java/android/net/wifi/WifiAnnotations.java index 4a7dee138971..9223d28836b6 100644 --- a/wifi/java/android/net/wifi/WifiAnnotations.java +++ b/wifi/java/android/net/wifi/WifiAnnotations.java @@ -48,4 +48,16 @@ public final class WifiAnnotations { WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY, WifiScanner.WIFI_BAND_6_GHZ}) public @interface WifiBandBasic {} + + @IntDef(prefix = { "CHANNEL_WIDTH_" }, value = { + SoftApInfo.CHANNEL_WIDTH_INVALID, + SoftApInfo.CHANNEL_WIDTH_20MHZ_NOHT, + SoftApInfo.CHANNEL_WIDTH_20MHZ, + SoftApInfo.CHANNEL_WIDTH_40MHZ, + SoftApInfo.CHANNEL_WIDTH_80MHZ, + SoftApInfo.CHANNEL_WIDTH_80MHZ_PLUS_MHZ, + SoftApInfo.CHANNEL_WIDTH_160MHZ, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface Bandwidth {} } diff --git a/wifi/java/android/net/wifi/WifiCondManager.java b/wifi/java/android/net/wifi/WifiCondManager.java deleted file mode 100644 index c05ba347ab5c..000000000000 --- a/wifi/java/android/net/wifi/WifiCondManager.java +++ /dev/null @@ -1,983 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.wifi; - -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.app.AlarmManager; -import android.content.Context; -import android.net.wifi.wificond.ChannelSettings; -import android.net.wifi.wificond.HiddenNetwork; -import android.net.wifi.wificond.NativeScanResult; -import android.net.wifi.wificond.NativeWifiClient; -import android.net.wifi.wificond.PnoSettings; -import android.net.wifi.wificond.SingleScanSettings; -import android.os.Binder; -import android.os.Handler; -import android.os.IBinder; -import android.os.RemoteException; -import android.os.ServiceManager; -import android.os.SystemClock; -import android.util.Log; - -import com.android.internal.annotations.VisibleForTesting; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * This class provides methods for WifiNative to send control commands to wificond. - * NOTE: This class should only be used from WifiNative. - * @hide - */ -public class WifiCondManager implements IBinder.DeathRecipient { - private static final String TAG = "WifiCondManager"; - private boolean mVerboseLoggingEnabled = false; - - /** - * The {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int) sendMgmtFrame()} - * timeout, in milliseconds, after which - * {@link SendMgmtFrameCallback#onFailure(int)} will be called with reason - * {@link #SEND_MGMT_FRAME_ERROR_TIMEOUT}. - */ - public static final int SEND_MGMT_FRAME_TIMEOUT_MS = 1000; - - private static final String TIMEOUT_ALARM_TAG = TAG + " Send Management Frame Timeout"; - - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = {"SCAN_TYPE_"}, - value = {SCAN_TYPE_SINGLE_SCAN, - SCAN_TYPE_PNO_SCAN}) - public @interface ScanResultType {} - - /** Get scan results for a single scan */ - public static final int SCAN_TYPE_SINGLE_SCAN = 0; - - /** Get scan results for Pno Scan */ - public static final int SCAN_TYPE_PNO_SCAN = 1; - - private AlarmManager mAlarmManager; - private Handler mEventHandler; - - // Cached wificond binder handlers. - private IWificond mWificond; - private HashMap mClientInterfaces = new HashMap<>(); - private HashMap mApInterfaces = new HashMap<>(); - private HashMap mWificondScanners = new HashMap<>(); - private HashMap mScanEventHandlers = new HashMap<>(); - private HashMap mPnoScanEventHandlers = new HashMap<>(); - private HashMap mApInterfaceListeners = new HashMap<>(); - private Runnable mDeathEventHandler; - /** - * Ensures that no more than one sendMgmtFrame operation runs concurrently. - */ - private AtomicBoolean mSendMgmtFrameInProgress = new AtomicBoolean(false); - - /** - * Interface for a callback to be used to handle scan results. - */ - public interface ScanEventCallback { - /** - * Called when scan results are available. - */ - void onScanResultReady(); - - /** - * Called when a scan has failed. - */ - void onScanFailed(); - } - - /** - * Interface for a callback to provide information about PNO scan request. - */ - public interface PnoScanRequestCallback { - /** - * Called when the PNO scan is requested. - */ - void onPnoRequestSucceeded(); - - /** - * Called when a PNO scan request fails. - */ - void onPnoRequestFailed(); - } - - private class ScanEventHandler extends IScanEvent.Stub { - private ScanEventCallback mCallback; - - ScanEventHandler(@NonNull ScanEventCallback callback) { - mCallback = callback; - } - - @Override - public void OnScanResultReady() { - Log.d(TAG, "Scan result ready event"); - mCallback.onScanResultReady(); - } - - @Override - public void OnScanFailed() { - Log.d(TAG, "Scan failed event"); - mCallback.onScanFailed(); - } - } - - /** - * Result of a signal poll. - */ - public static class SignalPollResult { - // RSSI value in dBM. - public int currentRssi; - //Transmission bit rate in Mbps. - public int txBitrate; - // Association frequency in MHz. - public int associationFrequency; - //Last received packet bit rate in Mbps. - public int rxBitrate; - } - - /** - * WiFi interface transimission counters. - */ - public static class TxPacketCounters { - // Number of successfully transmitted packets. - public int txSucceeded; - // Number of tramsmission failures. - public int txFailed; - } - - /** - * Callbacks for SoftAp interface. - */ - public interface SoftApListener { - /** - * Invoked when there is some fatal failure in the lower layers. - */ - void onFailure(); - - /** - * Invoked when the associated stations changes. - */ - void onConnectedClientsChanged(NativeWifiClient client, boolean isConnected); - - /** - * Invoked when the channel switch event happens. - */ - void onSoftApChannelSwitched(int frequency, int bandwidth); - } - - /** - * Callback to notify the results of a - * {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int) sendMgmtFrame()} call. - * Note: no callbacks will be triggered if the iface dies while sending a frame. - */ - public interface SendMgmtFrameCallback { - /** - * Called when the management frame was successfully sent and ACKed by the recipient. - * @param elapsedTimeMs The elapsed time between when the management frame was sent and when - * the ACK was processed, in milliseconds, as measured by wificond. - * This includes the time that the send frame spent queuing before it - * was sent, any firmware retries, and the time the received ACK spent - * queuing before it was processed. - */ - void onAck(int elapsedTimeMs); - - /** - * Called when the send failed. - * @param reason The error code for the failure. - */ - void onFailure(@SendMgmtFrameError int reason); - } - - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = {"SEND_MGMT_FRAME_ERROR_"}, - value = {SEND_MGMT_FRAME_ERROR_UNKNOWN, - SEND_MGMT_FRAME_ERROR_MCS_UNSUPPORTED, - SEND_MGMT_FRAME_ERROR_NO_ACK, - SEND_MGMT_FRAME_ERROR_TIMEOUT, - SEND_MGMT_FRAME_ERROR_ALREADY_STARTED}) - public @interface SendMgmtFrameError {} - - // Send management frame error codes - - /** - * Unknown error occurred during call to - * {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int) sendMgmtFrame()}. - */ - public static final int SEND_MGMT_FRAME_ERROR_UNKNOWN = 1; - - /** - * Specifying the MCS rate in - * {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int) sendMgmtFrame()} is not - * supported by this device. - */ - public static final int SEND_MGMT_FRAME_ERROR_MCS_UNSUPPORTED = 2; - - /** - * Driver reported that no ACK was received for the frame transmitted using - * {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int) sendMgmtFrame()}. - */ - public static final int SEND_MGMT_FRAME_ERROR_NO_ACK = 3; - - /** - * Error code for when the driver fails to report on the status of the frame sent by - * {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int) sendMgmtFrame()} - * after {@link #SEND_MGMT_FRAME_TIMEOUT_MS} milliseconds. - */ - public static final int SEND_MGMT_FRAME_ERROR_TIMEOUT = 4; - - /** - * An existing call to - * {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int) sendMgmtFrame()} - * is in progress. Another frame cannot be sent until the first call completes. - */ - public static final int SEND_MGMT_FRAME_ERROR_ALREADY_STARTED = 5; - - - public WifiCondManager(Context context) { - mAlarmManager = (AlarmManager) context.getSystemService(AlarmManager.class); - mEventHandler = new Handler(context.getMainLooper()); - } - - @VisibleForTesting - public WifiCondManager(Context context, IWificond wificond) { - this(context); - mWificond = wificond; - } - - private class PnoScanEventHandler extends IPnoScanEvent.Stub { - private ScanEventCallback mCallback; - - PnoScanEventHandler(@NonNull ScanEventCallback callback) { - mCallback = callback; - } - - @Override - public void OnPnoNetworkFound() { - Log.d(TAG, "Pno scan result event"); - mCallback.onScanResultReady(); - } - - @Override - public void OnPnoScanFailed() { - Log.d(TAG, "Pno Scan failed event"); - mCallback.onScanFailed(); - } - } - - /** - * Listener for AP Interface events. - */ - private class ApInterfaceEventCallback extends IApInterfaceEventCallback.Stub { - private SoftApListener mSoftApListener; - - ApInterfaceEventCallback(SoftApListener listener) { - mSoftApListener = listener; - } - - @Override - public void onConnectedClientsChanged(NativeWifiClient client, boolean isConnected) { - if (mVerboseLoggingEnabled) { - Log.d(TAG, "onConnectedClientsChanged called with " - + client.macAddress + " isConnected: " + isConnected); - } - - mSoftApListener.onConnectedClientsChanged(client, isConnected); - } - - @Override - public void onSoftApChannelSwitched(int frequency, int bandwidth) { - mSoftApListener.onSoftApChannelSwitched(frequency, bandwidth); - } - } - - /** - * Callback triggered by wificond. - */ - private class SendMgmtFrameEvent extends ISendMgmtFrameEvent.Stub { - private SendMgmtFrameCallback mCallback; - private AlarmManager.OnAlarmListener mTimeoutCallback; - /** - * ensures that mCallback is only called once - */ - private boolean mWasCalled; - - private void runIfFirstCall(Runnable r) { - if (mWasCalled) return; - mWasCalled = true; - - mSendMgmtFrameInProgress.set(false); - r.run(); - } - - SendMgmtFrameEvent(@NonNull SendMgmtFrameCallback callback) { - mCallback = callback; - // called in main thread - mTimeoutCallback = () -> runIfFirstCall(() -> { - if (mVerboseLoggingEnabled) { - Log.e(TAG, "Timed out waiting for ACK"); - } - mCallback.onFailure(SEND_MGMT_FRAME_ERROR_TIMEOUT); - }); - mWasCalled = false; - - mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, - SystemClock.elapsedRealtime() + SEND_MGMT_FRAME_TIMEOUT_MS, - TIMEOUT_ALARM_TAG, mTimeoutCallback, mEventHandler); - } - - // called in binder thread - @Override - public void OnAck(int elapsedTimeMs) { - // post to main thread - mEventHandler.post(() -> runIfFirstCall(() -> { - mAlarmManager.cancel(mTimeoutCallback); - mCallback.onAck(elapsedTimeMs); - })); - } - - // called in binder thread - @Override - public void OnFailure(int reason) { - // post to main thread - mEventHandler.post(() -> runIfFirstCall(() -> { - mAlarmManager.cancel(mTimeoutCallback); - mCallback.onFailure(reason); - })); - } - } - - /** - * Called by the binder subsystem upon remote object death. - * Invoke all the register death handlers and clear state. - */ - @Override - public void binderDied() { - mEventHandler.post(() -> { - Log.e(TAG, "Wificond died!"); - clearState(); - // Invalidate the global wificond handle on death. Will be refreshed - // on the next setup call. - mWificond = null; - if (mDeathEventHandler != null) { - mDeathEventHandler.run(); - } - }); - } - - /** Enable or disable verbose logging of WificondControl. - * @param enable True to enable verbose logging. False to disable verbose logging. - */ - public void enableVerboseLogging(boolean enable) { - mVerboseLoggingEnabled = enable; - } - - /** - * Initializes wificond & registers a death notification for wificond. - * This method clears any existing state in wificond daemon. - * - * @return Returns true on success. - */ - public boolean initialize(@NonNull Runnable deathEventHandler) { - if (mDeathEventHandler != null) { - Log.e(TAG, "Death handler already present"); - } - mDeathEventHandler = deathEventHandler; - tearDownInterfaces(); - return true; - } - - /** - * Helper method to retrieve the global wificond handle and register for - * death notifications. - */ - private boolean retrieveWificondAndRegisterForDeath() { - if (mWificond != null) { - if (mVerboseLoggingEnabled) { - Log.d(TAG, "Wificond handle already retrieved"); - } - // We already have a wificond handle. - return true; - } - IBinder binder = ServiceManager.getService(Context.WIFI_COND_SERVICE); - mWificond = IWificond.Stub.asInterface(binder); - if (mWificond == null) { - Log.e(TAG, "Failed to get reference to wificond"); - return false; - } - try { - mWificond.asBinder().linkToDeath(this, 0); - } catch (RemoteException e) { - Log.e(TAG, "Failed to register death notification for wificond"); - // The remote has already died. - return false; - } - return true; - } - - /** - * Setup interface for client mode via wificond. - * @return true on success. - */ - public boolean setupInterfaceForClientMode(@NonNull String ifaceName, - @NonNull ScanEventCallback scanCallback, @NonNull ScanEventCallback pnoScanCallback) { - Log.d(TAG, "Setting up interface for client mode"); - if (!retrieveWificondAndRegisterForDeath()) { - return false; - } - - IClientInterface clientInterface = null; - try { - clientInterface = mWificond.createClientInterface(ifaceName); - } catch (RemoteException e1) { - Log.e(TAG, "Failed to get IClientInterface due to remote exception"); - return false; - } - - if (clientInterface == null) { - Log.e(TAG, "Could not get IClientInterface instance from wificond"); - return false; - } - Binder.allowBlocking(clientInterface.asBinder()); - - // Refresh Handlers - mClientInterfaces.put(ifaceName, clientInterface); - try { - IWifiScannerImpl wificondScanner = clientInterface.getWifiScannerImpl(); - if (wificondScanner == null) { - Log.e(TAG, "Failed to get WificondScannerImpl"); - return false; - } - mWificondScanners.put(ifaceName, wificondScanner); - Binder.allowBlocking(wificondScanner.asBinder()); - ScanEventHandler scanEventHandler = new ScanEventHandler(scanCallback); - mScanEventHandlers.put(ifaceName, scanEventHandler); - wificondScanner.subscribeScanEvents(scanEventHandler); - PnoScanEventHandler pnoScanEventHandler = new PnoScanEventHandler(pnoScanCallback); - mPnoScanEventHandlers.put(ifaceName, pnoScanEventHandler); - wificondScanner.subscribePnoScanEvents(pnoScanEventHandler); - } catch (RemoteException e) { - Log.e(TAG, "Failed to refresh wificond scanner due to remote exception"); - } - - return true; - } - - /** - * Teardown a specific STA interface configured in wificond. - * - * @return Returns true on success. - */ - public boolean tearDownClientInterface(@NonNull String ifaceName) { - if (getClientInterface(ifaceName) == null) { - Log.e(TAG, "No valid wificond client interface handler"); - return false; - } - try { - IWifiScannerImpl scannerImpl = mWificondScanners.get(ifaceName); - if (scannerImpl != null) { - scannerImpl.unsubscribeScanEvents(); - scannerImpl.unsubscribePnoScanEvents(); - } - } catch (RemoteException e) { - Log.e(TAG, "Failed to unsubscribe wificond scanner due to remote exception"); - return false; - } - - if (mWificond == null) { - Log.e(TAG, "Reference to wifiCond is null"); - return false; - } - - boolean success; - try { - success = mWificond.tearDownClientInterface(ifaceName); - } catch (RemoteException e1) { - Log.e(TAG, "Failed to teardown client interface due to remote exception"); - return false; - } - if (!success) { - Log.e(TAG, "Failed to teardown client interface"); - return false; - } - - mClientInterfaces.remove(ifaceName); - mWificondScanners.remove(ifaceName); - mScanEventHandlers.remove(ifaceName); - mPnoScanEventHandlers.remove(ifaceName); - return true; - } - - /** - * Setup interface for softAp mode via wificond. - * @return true on success. - */ - public boolean setupInterfaceForSoftApMode(@NonNull String ifaceName) { - Log.d(TAG, "Setting up interface for soft ap mode"); - if (!retrieveWificondAndRegisterForDeath()) { - return false; - } - - IApInterface apInterface = null; - try { - apInterface = mWificond.createApInterface(ifaceName); - } catch (RemoteException e1) { - Log.e(TAG, "Failed to get IApInterface due to remote exception"); - return false; - } - - if (apInterface == null) { - Log.e(TAG, "Could not get IApInterface instance from wificond"); - return false; - } - Binder.allowBlocking(apInterface.asBinder()); - - // Refresh Handlers - mApInterfaces.put(ifaceName, apInterface); - return true; - } - - /** - * Teardown a specific AP interface configured in wificond. - * - * @return Returns true on success. - */ - public boolean tearDownSoftApInterface(@NonNull String ifaceName) { - if (getApInterface(ifaceName) == null) { - Log.e(TAG, "No valid wificond ap interface handler"); - return false; - } - - if (mWificond == null) { - Log.e(TAG, "Reference to wifiCond is null"); - return false; - } - - boolean success; - try { - success = mWificond.tearDownApInterface(ifaceName); - } catch (RemoteException e1) { - Log.e(TAG, "Failed to teardown AP interface due to remote exception"); - return false; - } - if (!success) { - Log.e(TAG, "Failed to teardown AP interface"); - return false; - } - mApInterfaces.remove(ifaceName); - mApInterfaceListeners.remove(ifaceName); - return true; - } - - /** - * Teardown all interfaces configured in wificond. - * @return Returns true on success. - */ - public boolean tearDownInterfaces() { - Log.d(TAG, "tearing down interfaces in wificond"); - // Explicitly refresh the wificodn handler because |tearDownInterfaces()| - // could be used to cleanup before we setup any interfaces. - if (!retrieveWificondAndRegisterForDeath()) { - return false; - } - - try { - for (Map.Entry entry : mWificondScanners.entrySet()) { - entry.getValue().unsubscribeScanEvents(); - entry.getValue().unsubscribePnoScanEvents(); - } - mWificond.tearDownInterfaces(); - clearState(); - return true; - } catch (RemoteException e) { - Log.e(TAG, "Failed to tear down interfaces due to remote exception"); - } - - return false; - } - - /** Helper function to look up the interface handle using name */ - private IClientInterface getClientInterface(@NonNull String ifaceName) { - return mClientInterfaces.get(ifaceName); - } - - /** - * Request signal polling to wificond. - * @param ifaceName Name of the interface. - * Returns an SignalPollResult object. - * Returns null on failure. - */ - public SignalPollResult signalPoll(@NonNull String ifaceName) { - IClientInterface iface = getClientInterface(ifaceName); - if (iface == null) { - Log.e(TAG, "No valid wificond client interface handler"); - return null; - } - - int[] resultArray; - try { - resultArray = iface.signalPoll(); - if (resultArray == null || resultArray.length != 4) { - Log.e(TAG, "Invalid signal poll result from wificond"); - return null; - } - } catch (RemoteException e) { - Log.e(TAG, "Failed to do signal polling due to remote exception"); - return null; - } - SignalPollResult pollResult = new SignalPollResult(); - pollResult.currentRssi = resultArray[0]; - pollResult.txBitrate = resultArray[1]; - pollResult.associationFrequency = resultArray[2]; - pollResult.rxBitrate = resultArray[3]; - return pollResult; - } - - /** - * Fetch TX packet counters on current connection from wificond. - * @param ifaceName Name of the interface. - * Returns an TxPacketCounters object. - * Returns null on failure. - */ - public TxPacketCounters getTxPacketCounters(@NonNull String ifaceName) { - IClientInterface iface = getClientInterface(ifaceName); - if (iface == null) { - Log.e(TAG, "No valid wificond client interface handler"); - return null; - } - - int[] resultArray; - try { - resultArray = iface.getPacketCounters(); - if (resultArray == null || resultArray.length != 2) { - Log.e(TAG, "Invalid signal poll result from wificond"); - return null; - } - } catch (RemoteException e) { - Log.e(TAG, "Failed to do signal polling due to remote exception"); - return null; - } - TxPacketCounters counters = new TxPacketCounters(); - counters.txSucceeded = resultArray[0]; - counters.txFailed = resultArray[1]; - return counters; - } - - /** Helper function to look up the scanner impl handle using name */ - private IWifiScannerImpl getScannerImpl(@NonNull String ifaceName) { - return mWificondScanners.get(ifaceName); - } - - /** - * Fetch the latest scan result from kernel via wificond. - * @param ifaceName Name of the interface. - * @return Returns an array of native scan results or an empty array on failure. - */ - @NonNull public List getScanResults(@NonNull String ifaceName, - @ScanResultType int scanType) { - IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); - if (scannerImpl == null) { - Log.e(TAG, "No valid wificond scanner interface handler"); - return new ArrayList<>(); - } - List results = null; - try { - if (scanType == SCAN_TYPE_SINGLE_SCAN) { - results = Arrays.asList(scannerImpl.getScanResults()); - } else { - results = Arrays.asList(scannerImpl.getPnoScanResults()); - } - } catch (RemoteException e1) { - Log.e(TAG, "Failed to create ScanDetail ArrayList"); - } - if (results == null) { - results = new ArrayList<>(); - } - if (mVerboseLoggingEnabled) { - Log.d(TAG, "get " + results.size() + " scan results from wificond"); - } - - return results; - } - - /** - * Return scan type for the parcelable {@link SingleScanSettings} - */ - private static int getScanType(@WifiAnnotations.ScanType int scanType) { - switch (scanType) { - case WifiScanner.SCAN_TYPE_LOW_LATENCY: - return IWifiScannerImpl.SCAN_TYPE_LOW_SPAN; - case WifiScanner.SCAN_TYPE_LOW_POWER: - return IWifiScannerImpl.SCAN_TYPE_LOW_POWER; - case WifiScanner.SCAN_TYPE_HIGH_ACCURACY: - return IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY; - default: - throw new IllegalArgumentException("Invalid scan type " + scanType); - } - } - - /** - * Start a scan using wificond for the given parameters. - * @param ifaceName Name of the interface. - * @param scanType Type of scan to perform. - * @param freqs list of frequencies to scan for, if null scan all supported channels. - * @param hiddenNetworkSSIDs List of hidden networks to be scanned for. - * @return Returns true on success. - */ - public boolean scan(@NonNull String ifaceName, @WifiAnnotations.ScanType int scanType, - Set freqs, List hiddenNetworkSSIDs) { - IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); - if (scannerImpl == null) { - Log.e(TAG, "No valid wificond scanner interface handler"); - return false; - } - SingleScanSettings settings = new SingleScanSettings(); - try { - settings.scanType = getScanType(scanType); - } catch (IllegalArgumentException e) { - Log.e(TAG, "Invalid scan type ", e); - return false; - } - settings.channelSettings = new ArrayList<>(); - settings.hiddenNetworks = new ArrayList<>(); - - if (freqs != null) { - for (Integer freq : freqs) { - ChannelSettings channel = new ChannelSettings(); - channel.frequency = freq; - settings.channelSettings.add(channel); - } - } - if (hiddenNetworkSSIDs != null) { - for (byte[] ssid : hiddenNetworkSSIDs) { - HiddenNetwork network = new HiddenNetwork(); - network.ssid = ssid; - - // settings.hiddenNetworks is expected to be very small, so this shouldn't cause - // any performance issues. - if (!settings.hiddenNetworks.contains(network)) { - settings.hiddenNetworks.add(network); - } - } - } - - try { - return scannerImpl.scan(settings); - } catch (RemoteException e1) { - Log.e(TAG, "Failed to request scan due to remote exception"); - } - return false; - } - - /** - * Start PNO scan. - * @param ifaceName Name of the interface. - * @param pnoSettings Pno scan configuration. - * @return true on success. - */ - public boolean startPnoScan(@NonNull String ifaceName, PnoSettings pnoSettings, - PnoScanRequestCallback callback) { - IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); - if (scannerImpl == null) { - Log.e(TAG, "No valid wificond scanner interface handler"); - return false; - } - - try { - boolean success = scannerImpl.startPnoScan(pnoSettings); - if (success) { - callback.onPnoRequestSucceeded(); - } else { - callback.onPnoRequestFailed(); - } - return success; - } catch (RemoteException e1) { - Log.e(TAG, "Failed to start pno scan due to remote exception"); - } - return false; - } - - /** - * Stop PNO scan. - * @param ifaceName Name of the interface. - * @return true on success. - */ - public boolean stopPnoScan(@NonNull String ifaceName) { - IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); - if (scannerImpl == null) { - Log.e(TAG, "No valid wificond scanner interface handler"); - return false; - } - try { - return scannerImpl.stopPnoScan(); - } catch (RemoteException e1) { - Log.e(TAG, "Failed to stop pno scan due to remote exception"); - } - return false; - } - - /** - * Abort ongoing single scan. - * @param ifaceName Name of the interface. - */ - public void abortScan(@NonNull String ifaceName) { - IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); - if (scannerImpl == null) { - Log.e(TAG, "No valid wificond scanner interface handler"); - return; - } - try { - scannerImpl.abortScan(); - } catch (RemoteException e1) { - Log.e(TAG, "Failed to request abortScan due to remote exception"); - } - } - - /** - * Query the list of valid frequencies for the provided band. - * The result depends on the on the country code that has been set. - * - * @param band as specified by one of the WifiScanner.WIFI_BAND_* constants. - * The following bands are supported {@link @WifiScanner.WifiBandBasic}: - * WifiScanner.WIFI_BAND_24_GHZ - * WifiScanner.WIFI_BAND_5_GHZ - * WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY - * WifiScanner.WIFI_BAND_6_GHZ - * @return frequencies vector of valid frequencies (MHz), or null for error. - * @throws IllegalArgumentException if band is not recognized. - */ - public int [] getChannelsForBand(@WifiAnnotations.WifiBandBasic int band) { - if (mWificond == null) { - Log.e(TAG, "No valid wificond scanner interface handler"); - return null; - } - try { - switch (band) { - case WifiScanner.WIFI_BAND_24_GHZ: - return mWificond.getAvailable2gChannels(); - case WifiScanner.WIFI_BAND_5_GHZ: - return mWificond.getAvailable5gNonDFSChannels(); - case WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY: - return mWificond.getAvailableDFSChannels(); - case WifiScanner.WIFI_BAND_6_GHZ: - return mWificond.getAvailable6gChannels(); - default: - throw new IllegalArgumentException("unsupported band " + band); - } - } catch (RemoteException e1) { - Log.e(TAG, "Failed to request getChannelsForBand due to remote exception"); - } - return null; - } - - /** Helper function to look up the interface handle using name */ - private IApInterface getApInterface(@NonNull String ifaceName) { - return mApInterfaces.get(ifaceName); - } - - /** - * Register the provided listener for SoftAp events. - * - * @param ifaceName Name of the interface. - * @param listener Callback for AP events. - * @return true on success, false otherwise. - */ - public boolean registerApListener(@NonNull String ifaceName, SoftApListener listener) { - IApInterface iface = getApInterface(ifaceName); - if (iface == null) { - Log.e(TAG, "No valid ap interface handler"); - return false; - } - try { - IApInterfaceEventCallback callback = new ApInterfaceEventCallback(listener); - mApInterfaceListeners.put(ifaceName, callback); - boolean success = iface.registerCallback(callback); - if (!success) { - Log.e(TAG, "Failed to register ap callback."); - return false; - } - } catch (RemoteException e) { - Log.e(TAG, "Exception in registering AP callback: " + e); - return false; - } - return true; - } - - /** - * See {@link #sendMgmtFrame(String, byte[], SendMgmtFrameCallback, int)} - */ - public void sendMgmtFrame(@NonNull String ifaceName, @NonNull byte[] frame, - @NonNull SendMgmtFrameCallback callback, int mcs) { - - if (callback == null) { - Log.e(TAG, "callback cannot be null!"); - return; - } - - if (frame == null) { - Log.e(TAG, "frame cannot be null!"); - callback.onFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN); - return; - } - - // TODO (b/112029045) validate mcs - IClientInterface clientInterface = getClientInterface(ifaceName); - if (clientInterface == null) { - Log.e(TAG, "No valid wificond client interface handler"); - callback.onFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN); - return; - } - - if (!mSendMgmtFrameInProgress.compareAndSet(false, true)) { - Log.e(TAG, "An existing management frame transmission is in progress!"); - callback.onFailure(SEND_MGMT_FRAME_ERROR_ALREADY_STARTED); - return; - } - - SendMgmtFrameEvent sendMgmtFrameEvent = new SendMgmtFrameEvent(callback); - try { - clientInterface.SendMgmtFrame(frame, sendMgmtFrameEvent, mcs); - } catch (RemoteException e) { - Log.e(TAG, "Exception while starting link probe: " + e); - // Call sendMgmtFrameEvent.OnFailure() instead of callback.onFailure() so that - // sendMgmtFrameEvent can clean up internal state, such as cancelling the timer. - sendMgmtFrameEvent.OnFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN); - } - } - - /** - * Clear all internal handles. - */ - private void clearState() { - // Refresh handlers - mClientInterfaces.clear(); - mWificondScanners.clear(); - mPnoScanEventHandlers.clear(); - mScanEventHandlers.clear(); - mApInterfaces.clear(); - mApInterfaceListeners.clear(); - mSendMgmtFrameInProgress.set(false); - } -} diff --git a/wifi/java/android/net/wifi/wificond/NativeScanResult.java b/wifi/java/android/net/wifi/wificond/NativeScanResult.java index ff8e935da8c0..6ed17081bdb5 100644 --- a/wifi/java/android/net/wifi/wificond/NativeScanResult.java +++ b/wifi/java/android/net/wifi/wificond/NativeScanResult.java @@ -16,46 +16,163 @@ package android.net.wifi.wificond; +import android.annotation.NonNull; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; +import com.android.internal.annotations.VisibleForTesting; + import java.util.ArrayList; import java.util.BitSet; import java.util.List; /** - * ScanResult from wificond + * Raw scan result data from the wificond daemon. * * @hide */ -public class NativeScanResult implements Parcelable { +@SystemApi +public final class NativeScanResult implements Parcelable { private static final int CAPABILITY_SIZE = 16; + /** @hide */ + @VisibleForTesting public byte[] ssid; + /** @hide */ + @VisibleForTesting public byte[] bssid; + /** @hide */ + @VisibleForTesting public byte[] infoElement; + /** @hide */ + @VisibleForTesting public int frequency; + /** @hide */ + @VisibleForTesting public int signalMbm; + /** @hide */ + @VisibleForTesting public long tsf; + /** @hide */ + @VisibleForTesting public BitSet capability; + /** @hide */ + @VisibleForTesting public boolean associated; + /** @hide */ + @VisibleForTesting public List radioChainInfos; - /** public constructor */ - public NativeScanResult() { } + /** + * Returns the SSID raw byte array of the AP represented by this scan result. + * + * @return A byte array. + */ + @NonNull public byte[] getSsid() { + return ssid; + } + + /** + * Returns raw bytes representing the MAC address (BSSID) of the AP represented by this scan + * result. + * + * @return a byte array, possibly null or containing the incorrect number of bytes for a MAC + * address. + */ + @NonNull public byte[] getBssid() { + return bssid; + } + + /** + * Returns the raw bytes of the information element advertised by the AP represented by this + * scan result. + * + * @return A byte array, possibly null or containing an invalid TLV configuration. + */ + @NonNull public byte[] getInformationElements() { + return infoElement; + } + + /** + * Returns the frequency (in MHz) on which the AP represented by this scan result was observed. + * + * @return The frequency in MHz. + */ + public int getFrequencyMhz() { + return frequency; + } + + /** + * Return the signal strength of probe response/beacon in (100 * dBm). + * + * @return Signal strenght in (100 * dBm). + */ + public int getSignalMbm() { + return signalMbm; + } - /** copy constructor */ - public NativeScanResult(NativeScanResult source) { - ssid = source.ssid.clone(); - bssid = source.bssid.clone(); - infoElement = source.infoElement.clone(); - frequency = source.frequency; - signalMbm = source.signalMbm; - tsf = source.tsf; - capability = (BitSet) source.capability.clone(); - associated = source.associated; + /** + * Return the TSF (Timing Synchronization Function) of the received probe response/beacon. + * @return + */ + public long getTsf() { + return tsf; } + /** + * Return a boolean indicating whether or not we're associated to the AP represented by this + * scan result. + * + * @return A boolean indicating association. + */ + public boolean isAssociated() { + return associated; + } + + /** + * Returns the capabilities of the AP repseresented by this scan result as advertised in the + * received probe response or beacon. + * + * This is a bit mask describing the capabilities of a BSS. See IEEE Std 802.11: 8.4.1.4: + * Bit 0 - ESS + * Bit 1 - IBSS + * Bit 2 - CF Pollable + * Bit 3 - CF-Poll Request + * Bit 4 - Privacy + * Bit 5 - Short Preamble + * Bit 6 - PBCC + * Bit 7 - Channel Agility + * Bit 8 - Spectrum Mgmt + * Bit 9 - QoS + * Bit 10 - Short Slot Time + * Bit 11 - APSD + * Bit 12 - Radio Measurement + * Bit 13 - DSSS-OFDM + * Bit 14 - Delayed Block Ack + * Bit 15 - Immediate Block Ack + * + * @return a bit mask of capabilities. + */ + @NonNull public BitSet getCapabilities() { + return capability; + } + + /** + * Returns details of the signal received on each radio chain for the AP represented by this + * scan result in a list of {@link RadioChainInfo} elements. + * + * @return A list of {@link RadioChainInfo} - possibly empty in case of error. + */ + @NonNull public List getRadioChainInfos() { + return radioChainInfos; + } + + /** + * @hide + */ + public NativeScanResult() { } + /** implement Parcelable interface */ @Override public int describeContents() { @@ -64,7 +181,7 @@ public class NativeScanResult implements Parcelable { /** implement Parcelable interface */ @Override - public void writeToParcel(Parcel out, int flags) { + public void writeToParcel(@NonNull Parcel out, int flags) { out.writeByteArray(ssid); out.writeByteArray(bssid); out.writeByteArray(infoElement); @@ -83,14 +200,23 @@ public class NativeScanResult implements Parcelable { } /** implement Parcelable interface */ - public static final Parcelable.Creator CREATOR = + @NonNull public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { @Override public NativeScanResult createFromParcel(Parcel in) { NativeScanResult result = new NativeScanResult(); result.ssid = in.createByteArray(); + if (result.ssid == null) { + result.ssid = new byte[0]; + } result.bssid = in.createByteArray(); + if (result.bssid == null) { + result.bssid = new byte[0]; + } result.infoElement = in.createByteArray(); + if (result.infoElement == null) { + result.infoElement = new byte[0]; + } result.frequency = in.readInt(); result.signalMbm = in.readInt(); result.tsf = in.readLong(); diff --git a/wifi/java/android/net/wifi/wificond/NativeWifiClient.java b/wifi/java/android/net/wifi/wificond/NativeWifiClient.java index 4994ebd33216..554f9295ef0d 100644 --- a/wifi/java/android/net/wifi/wificond/NativeWifiClient.java +++ b/wifi/java/android/net/wifi/wificond/NativeWifiClient.java @@ -16,21 +16,32 @@ package android.net.wifi.wificond; +import android.annotation.NonNull; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; import java.util.Arrays; /** - * NativeWifiClient for wificond + * Structure providing information about clients (STAs) associated with a SoftAp. * * @hide */ -public class NativeWifiClient implements Parcelable { - public byte[] macAddress; +@SystemApi +public final class NativeWifiClient implements Parcelable { + /** + * The raw bytes of the MAC address of the client (STA) represented by this object. + */ + @NonNull public final byte[] macAddress; - /** public constructor */ - public NativeWifiClient() { } + /** + * public constructor + * @hide + */ + public NativeWifiClient(@NonNull byte[] macAddress) { + this.macAddress = macAddress; + } /** override comparator */ @Override @@ -60,18 +71,20 @@ public class NativeWifiClient implements Parcelable { * |flag| is ignored. */ @Override - public void writeToParcel(Parcel out, int flags) { + public void writeToParcel(@NonNull Parcel out, int flags) { out.writeByteArray(macAddress); } /** implement Parcelable interface */ - public static final Parcelable.Creator CREATOR = + @NonNull public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { @Override public NativeWifiClient createFromParcel(Parcel in) { - NativeWifiClient result = new NativeWifiClient(); - result.macAddress = in.createByteArray(); - return result; + byte[] macAddress = in.createByteArray(); + if (macAddress == null) { + macAddress = new byte[0]; + } + return new NativeWifiClient(macAddress); } @Override diff --git a/wifi/java/android/net/wifi/wificond/PnoNetwork.java b/wifi/java/android/net/wifi/wificond/PnoNetwork.java index f923fd384a90..ca0b1cfb6223 100644 --- a/wifi/java/android/net/wifi/wificond/PnoNetwork.java +++ b/wifi/java/android/net/wifi/wificond/PnoNetwork.java @@ -16,6 +16,8 @@ package android.net.wifi.wificond; +import android.annotation.NonNull; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; @@ -23,17 +25,85 @@ import java.util.Arrays; import java.util.Objects; /** - * PnoNetwork for wificond + * Configuration for a PNO (preferred network offload) network used in {@link PnoSettings}. A PNO + * network allows configuration of a specific network to search for. * * @hide */ -public class PnoNetwork implements Parcelable { +@SystemApi +public final class PnoNetwork implements Parcelable { + private boolean mIsHidden; + private byte[] mSsid; + private int[] mFrequencies; - public boolean isHidden; - public byte[] ssid; - public int[] frequencies; + /** + * Indicates whether the PNO network configuration is for a hidden SSID - i.e. a network which + * does not broadcast its SSID and must be queried explicitly. + * + * @return True if the configuration is for a hidden network, false otherwise. + */ + public boolean isHidden() { + return mIsHidden; + } + + /** + * Configure whether the PNO network configuration is for a hidden SSID - i.e. a network which + * does not broadcast its SSID and must be queried explicitly. + * + * @param isHidden True if the configuration is for a hidden network, false otherwise. + */ + public void setHidden(boolean isHidden) { + mIsHidden = isHidden; + } + + /** + * Get the raw bytes for the SSID of the PNO network being scanned for. + * + * @return A byte array. + */ + @NonNull public byte[] getSsid() { + return mSsid; + } + + /** + * Set the raw bytes for the SSID of the PNO network being scanned for. + * + * @param ssid A byte array. + */ + public void setSsid(@NonNull byte[] ssid) { + if (ssid == null) { + throw new IllegalArgumentException("null argument"); + } + this.mSsid = ssid; + } + + /** + * Get the frequencies (in MHz) on which to PNO scan for the current network is being searched + * for. A null return (i.e. no frequencies configured) indicates that the network is search for + * on all supported frequencies. + * + * @return A array of frequencies (in MHz), a null indicates no configured frequencies. + */ + @NonNull public int[] getFrequenciesMhz() { + return mFrequencies; + } + + /** + * Set the frequencies (in MHz) on which to PNO scan for the current network is being searched + * for. A null configuration (i.e. no frequencies configured) indicates that the network is + * search for on all supported frequencies. + * + * @param frequenciesMhz an array of frequencies (in MHz), null indicating no configured + * frequencies. + */ + public void setFrequenciesMhz(@NonNull int[] frequenciesMhz) { + if (frequenciesMhz == null) { + throw new IllegalArgumentException("null argument"); + } + this.mFrequencies = frequenciesMhz; + } - /** public constructor */ + /** Construct an uninitialized PnoNetwork object */ public PnoNetwork() { } /** override comparator */ @@ -44,18 +114,18 @@ public class PnoNetwork implements Parcelable { return false; } PnoNetwork network = (PnoNetwork) rhs; - return Arrays.equals(ssid, network.ssid) - && Arrays.equals(frequencies, network.frequencies) - && isHidden == network.isHidden; + return Arrays.equals(mSsid, network.mSsid) + && Arrays.equals(mFrequencies, network.mFrequencies) + && mIsHidden == network.mIsHidden; } /** override hash code */ @Override public int hashCode() { return Objects.hash( - isHidden, - Arrays.hashCode(ssid), - Arrays.hashCode(frequencies)); + mIsHidden, + Arrays.hashCode(mSsid), + Arrays.hashCode(mFrequencies)); } /** implement Parcelable interface */ @@ -69,21 +139,27 @@ public class PnoNetwork implements Parcelable { * |flag| is ignored. */ @Override - public void writeToParcel(Parcel out, int flags) { - out.writeInt(isHidden ? 1 : 0); - out.writeByteArray(ssid); - out.writeIntArray(frequencies); + public void writeToParcel(@NonNull Parcel out, int flags) { + out.writeInt(mIsHidden ? 1 : 0); + out.writeByteArray(mSsid); + out.writeIntArray(mFrequencies); } /** implement Parcelable interface */ - public static final Parcelable.Creator CREATOR = + @NonNull public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { @Override public PnoNetwork createFromParcel(Parcel in) { PnoNetwork result = new PnoNetwork(); - result.isHidden = in.readInt() != 0 ? true : false; - result.ssid = in.createByteArray(); - result.frequencies = in.createIntArray(); + result.mIsHidden = in.readInt() != 0 ? true : false; + result.mSsid = in.createByteArray(); + if (result.mSsid == null) { + result.mSsid = new byte[0]; + } + result.mFrequencies = in.createIntArray(); + if (result.mFrequencies == null) { + result.mFrequencies = new int[0]; + } return result; } diff --git a/wifi/java/android/net/wifi/wificond/PnoSettings.java b/wifi/java/android/net/wifi/wificond/PnoSettings.java index 96cf24fdfb81..57c9ca5fd302 100644 --- a/wifi/java/android/net/wifi/wificond/PnoSettings.java +++ b/wifi/java/android/net/wifi/wificond/PnoSettings.java @@ -16,27 +16,130 @@ package android.net.wifi.wificond; +import android.annotation.NonNull; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; import java.util.ArrayList; +import java.util.List; import java.util.Objects; /** - * PnoSettings for wificond + * Configuration for a PNO (preferred network offload). A mechanism by which scans are offloaded + * from the host device to the Wi-Fi chip. * * @hide */ -public class PnoSettings implements Parcelable { - public int intervalMs; - public int min2gRssi; - public int min5gRssi; - public int min6gRssi; - public ArrayList pnoNetworks; - - /** public constructor */ +@SystemApi +public final class PnoSettings implements Parcelable { + private int mIntervalMs; + private int mMin2gRssi; + private int mMin5gRssi; + private int mMin6gRssi; + private List mPnoNetworks; + + /** Construct an uninitialized PnoSettings object */ public PnoSettings() { } + /** + * Get the requested PNO scan interval in milliseconds. + * + * @return An interval in milliseconds. + */ + public int getIntervalMillis() { + return mIntervalMs; + } + + /** + * Set the requested PNO scan interval in milliseconds. + * + * @param intervalMs An interval in milliseconds. + */ + public void setIntervalMillis(int intervalMs) { + this.mIntervalMs = intervalMs; + } + + /** + * Get the requested minimum RSSI threshold (in dBm) for APs to report in scan results in the + * 2.4GHz band. + * + * @return An RSSI value in dBm. + */ + public int getMin2gRssiDbm() { + return mMin2gRssi; + } + + /** + * Set the requested minimum RSSI threshold (in dBm) for APs to report in scan scan results in + * the 2.4GHz band. + * + * @param min2gRssiDbm An RSSI value in dBm. + */ + public void setMin2gRssiDbm(int min2gRssiDbm) { + this.mMin2gRssi = min2gRssiDbm; + } + + /** + * Get the requested minimum RSSI threshold (in dBm) for APs to report in scan results in the + * 5GHz band. + * + * @return An RSSI value in dBm. + */ + public int getMin5gRssiDbm() { + return mMin5gRssi; + } + + /** + * Set the requested minimum RSSI threshold (in dBm) for APs to report in scan scan results in + * the 5GHz band. + * + * @param min5gRssiDbm An RSSI value in dBm. + */ + public void setMin5gRssiDbm(int min5gRssiDbm) { + this.mMin5gRssi = min5gRssiDbm; + } + + /** + * Get the requested minimum RSSI threshold (in dBm) for APs to report in scan results in the + * 6GHz band. + * + * @return An RSSI value in dBm. + */ + public int getMin6gRssiDbm() { + return mMin6gRssi; + } + + /** + * Set the requested minimum RSSI threshold (in dBm) for APs to report in scan scan results in + * the 6GHz band. + * + * @param min6gRssiDbm An RSSI value in dBm. + */ + public void setMin6gRssiDbm(int min6gRssiDbm) { + this.mMin6gRssi = min6gRssiDbm; + } + + /** + * Return the configured list of specific networks to search for in a PNO scan. + * + * @return A list of {@link PnoNetwork} objects, possibly empty if non configured. + */ + @NonNull public List getPnoNetworks() { + return mPnoNetworks; + } + + /** + * Set the list of specified networks to scan for in a PNO scan. The networks (APs) are + * specified using {@link PnoNetwork}s. An empty list indicates that all networks are scanned + * for. + * + * @param pnoNetworks A (possibly empty) list of {@link PnoNetwork} objects. + */ + public void setPnoNetworks(@NonNull List pnoNetworks) { + this.mPnoNetworks = pnoNetworks; + } + /** override comparator */ @Override public boolean equals(Object rhs) { @@ -48,17 +151,17 @@ public class PnoSettings implements Parcelable { if (settings == null) { return false; } - return intervalMs == settings.intervalMs - && min2gRssi == settings.min2gRssi - && min5gRssi == settings.min5gRssi - && min6gRssi == settings.min6gRssi - && pnoNetworks.equals(settings.pnoNetworks); + return mIntervalMs == settings.mIntervalMs + && mMin2gRssi == settings.mMin2gRssi + && mMin5gRssi == settings.mMin5gRssi + && mMin6gRssi == settings.mMin6gRssi + && mPnoNetworks.equals(settings.mPnoNetworks); } /** override hash code */ @Override public int hashCode() { - return Objects.hash(intervalMs, min2gRssi, min5gRssi, min6gRssi, pnoNetworks); + return Objects.hash(mIntervalMs, mMin2gRssi, mMin5gRssi, mMin6gRssi, mPnoNetworks); } /** implement Parcelable interface */ @@ -72,27 +175,27 @@ public class PnoSettings implements Parcelable { * |flag| is ignored. **/ @Override - public void writeToParcel(Parcel out, int flags) { - out.writeInt(intervalMs); - out.writeInt(min2gRssi); - out.writeInt(min5gRssi); - out.writeInt(min6gRssi); - out.writeTypedList(pnoNetworks); + public void writeToParcel(@NonNull Parcel out, int flags) { + out.writeInt(mIntervalMs); + out.writeInt(mMin2gRssi); + out.writeInt(mMin5gRssi); + out.writeInt(mMin6gRssi); + out.writeTypedList(mPnoNetworks); } /** implement Parcelable interface */ - public static final Parcelable.Creator CREATOR = + @NonNull public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { @Override public PnoSettings createFromParcel(Parcel in) { PnoSettings result = new PnoSettings(); - result.intervalMs = in.readInt(); - result.min2gRssi = in.readInt(); - result.min5gRssi = in.readInt(); - result.min6gRssi = in.readInt(); + result.mIntervalMs = in.readInt(); + result.mMin2gRssi = in.readInt(); + result.mMin5gRssi = in.readInt(); + result.mMin6gRssi = in.readInt(); - result.pnoNetworks = new ArrayList(); - in.readTypedList(result.pnoNetworks, PnoNetwork.CREATOR); + result.mPnoNetworks = new ArrayList<>(); + in.readTypedList(result.mPnoNetworks, PnoNetwork.CREATOR); return result; } diff --git a/wifi/java/android/net/wifi/wificond/RadioChainInfo.java b/wifi/java/android/net/wifi/wificond/RadioChainInfo.java index 2b03450b1357..64102dde94c0 100644 --- a/wifi/java/android/net/wifi/wificond/RadioChainInfo.java +++ b/wifi/java/android/net/wifi/wificond/RadioChainInfo.java @@ -16,26 +16,52 @@ package android.net.wifi.wificond; +import android.annotation.NonNull; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; +import com.android.internal.annotations.VisibleForTesting; + import java.util.Objects; /** - * RadioChainInfo for wificond + * A class representing the radio chains of the Wi-Fi modems. Use to provide raw information about + * signals received on different radio chains. * * @hide */ -public class RadioChainInfo implements Parcelable { +@SystemApi +public final class RadioChainInfo implements Parcelable { private static final String TAG = "RadioChainInfo"; + /** @hide */ + @VisibleForTesting public int chainId; + /** @hide */ + @VisibleForTesting public int level; + /** + * Return an identifier for this radio chain. This is an arbitrary ID which is consistent for + * the same device. + * + * @return The radio chain ID. + */ + public int getChainId() { + return chainId; + } - /** public constructor */ - public RadioChainInfo() { } + /** + * Returns the detected signal level on this radio chain in dBm (aka RSSI). + * + * @return A signal level in dBm. + */ + public int getLevelDbm() { + return level; + } + /** @hide */ public RadioChainInfo(int chainId, int level) { this.chainId = chainId; this.level = level; @@ -73,23 +99,20 @@ public class RadioChainInfo implements Parcelable { * |flags| is ignored. */ @Override - public void writeToParcel(Parcel out, int flags) { + public void writeToParcel(@NonNull Parcel out, int flags) { out.writeInt(chainId); out.writeInt(level); } /** implement Parcelable interface */ - public static final Parcelable.Creator CREATOR = + @NonNull public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { /** * Caller is responsible for providing a valid parcel. */ @Override public RadioChainInfo createFromParcel(Parcel in) { - RadioChainInfo result = new RadioChainInfo(); - result.chainId = in.readInt(); - result.level = in.readInt(); - return result; + return new RadioChainInfo(in.readInt(), in.readInt()); } @Override diff --git a/wifi/java/android/net/wifi/wificond/WifiCondManager.java b/wifi/java/android/net/wifi/wificond/WifiCondManager.java new file mode 100644 index 000000000000..94f1212da0a0 --- /dev/null +++ b/wifi/java/android/net/wifi/wificond/WifiCondManager.java @@ -0,0 +1,1165 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.wificond; + +import android.annotation.CallbackExecutor; +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.annotation.SystemService; +import android.app.AlarmManager; +import android.content.Context; +import android.net.wifi.IApInterface; +import android.net.wifi.IApInterfaceEventCallback; +import android.net.wifi.IClientInterface; +import android.net.wifi.IPnoScanEvent; +import android.net.wifi.IScanEvent; +import android.net.wifi.ISendMgmtFrameEvent; +import android.net.wifi.IWifiScannerImpl; +import android.net.wifi.IWificond; +import android.net.wifi.SoftApInfo; +import android.net.wifi.WifiAnnotations; +import android.net.wifi.WifiScanner; +import android.os.Binder; +import android.os.Handler; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.os.SystemClock; +import android.util.Log; + +import com.android.internal.annotations.VisibleForTesting; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * This class encapsulates the interface the wificond daemon presents to the Wi-Fi framework. The + * interface is only for use by the Wi-Fi framework and access is protected by SELinux permissions. + * + * @hide + */ +@SystemApi +@SystemService(Context.WIFI_COND_SERVICE) +public class WifiCondManager { + private static final String TAG = "WifiCondManager"; + private boolean mVerboseLoggingEnabled = false; + + /** + * The {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} + * timeout, in milliseconds, after which + * {@link SendMgmtFrameCallback#onFailure(int)} will be called with reason + * {@link #SEND_MGMT_FRAME_ERROR_TIMEOUT}. + */ + private static final int SEND_MGMT_FRAME_TIMEOUT_MS = 1000; + + private static final String TIMEOUT_ALARM_TAG = TAG + " Send Management Frame Timeout"; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"SCAN_TYPE_"}, + value = {SCAN_TYPE_SINGLE_SCAN, + SCAN_TYPE_PNO_SCAN}) + public @interface ScanResultType {} + + /** + * Specifies a scan type: single scan initiated by the framework. Can be used in + * {@link #getScanResults(String, int)} to specify the type of scan result to fetch. + */ + public static final int SCAN_TYPE_SINGLE_SCAN = 0; + + /** + * Specifies a scan type: PNO scan. Can be used in {@link #getScanResults(String, int)} to + * specify the type of scan result to fetch. + */ + public static final int SCAN_TYPE_PNO_SCAN = 1; + + private AlarmManager mAlarmManager; + private Handler mEventHandler; + + // Cached wificond binder handlers. + private IWificond mWificond; + private HashMap mClientInterfaces = new HashMap<>(); + private HashMap mApInterfaces = new HashMap<>(); + private HashMap mWificondScanners = new HashMap<>(); + private HashMap mScanEventHandlers = new HashMap<>(); + private HashMap mPnoScanEventHandlers = new HashMap<>(); + private HashMap mApInterfaceListeners = new HashMap<>(); + private Runnable mDeathEventHandler; + /** + * Ensures that no more than one sendMgmtFrame operation runs concurrently. + */ + private AtomicBoolean mSendMgmtFrameInProgress = new AtomicBoolean(false); + + /** + * Interface used when waiting for scans to be completed (with results). + */ + public interface ScanEventCallback { + /** + * Called when scan results are available. Scans results should then be obtained from + * {@link #getScanResults(String, int)}. + */ + void onScanResultReady(); + + /** + * Called when a scan has failed. + */ + void onScanFailed(); + } + + /** + * Interface for a callback to provide information about PNO scan request requested with + * {@link #startPnoScan(String, PnoSettings, Executor, PnoScanRequestCallback)}. Note that the + * callback are for the status of the request - not the scan itself. The results of the scan + * are returned with {@link ScanEventCallback}. + */ + public interface PnoScanRequestCallback { + /** + * Called when a PNO scan request has been successfully submitted. + */ + void onPnoRequestSucceeded(); + + /** + * Called when a PNO scan request fails. + */ + void onPnoRequestFailed(); + } + + private class ScanEventHandler extends IScanEvent.Stub { + private Executor mExecutor; + private ScanEventCallback mCallback; + + ScanEventHandler(@NonNull Executor executor, @NonNull ScanEventCallback callback) { + mExecutor = executor; + mCallback = callback; + } + + @Override + public void OnScanResultReady() { + Log.d(TAG, "Scan result ready event"); + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mCallback.onScanResultReady()); + } + + @Override + public void OnScanFailed() { + Log.d(TAG, "Scan failed event"); + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mCallback.onScanFailed()); + } + } + + /** + * Result of a signal poll requested using {@link #signalPoll(String)}. + */ + public static class SignalPollResult { + /** @hide */ + public SignalPollResult(int currentRssiDbm, int txBitrateMbps, int rxBitrateMbps, + int associationFrequencyMHz) { + this.currentRssiDbm = currentRssiDbm; + this.txBitrateMbps = txBitrateMbps; + this.rxBitrateMbps = rxBitrateMbps; + this.associationFrequencyMHz = associationFrequencyMHz; + } + + /** + * RSSI value in dBM. + */ + public final int currentRssiDbm; + + /** + * Transmission bit rate in Mbps. + */ + public final int txBitrateMbps; + + /** + * Last received packet bit rate in Mbps. + */ + public final int rxBitrateMbps; + + /** + * Association frequency in MHz. + */ + public final int associationFrequencyMHz; + } + + /** + * Transmission counters obtained using {@link #getTxPacketCounters(String)}. + */ + public static class TxPacketCounters { + /** @hide */ + public TxPacketCounters(int txPacketSucceeded, int txPacketFailed) { + this.txPacketSucceeded = txPacketSucceeded; + this.txPacketFailed = txPacketFailed; + } + + /** + * Number of successfully transmitted packets. + */ + public final int txPacketSucceeded; + + /** + * Number of packet transmission failures. + */ + public final int txPacketFailed; + } + + /** + * Callbacks for SoftAp interface registered using + * {@link #registerApCallback(String, Executor, SoftApCallback)}. + */ + public interface SoftApCallback { + /** + * Invoked when there is a fatal failure and the SoftAp is shutdown. + */ + void onFailure(); + + /** + * Invoked when there is a change in the associated station (STA). + * @param client Information about the client whose status has changed. + * @param isConnected Indication as to whether the client is connected (true), or + * disconnected (false). + */ + void onConnectedClientsChanged(@NonNull NativeWifiClient client, boolean isConnected); + + /** + * Invoked when a channel switch event happens - i.e. the SoftAp is moved to a different + * channel. Also called on initial registration. + * @param frequencyMhz The new frequency of the SoftAp. A value of 0 is invalid and is an + * indication that the SoftAp is not enabled. + * @param bandwidth The new bandwidth of the SoftAp. + */ + void onSoftApChannelSwitched(int frequencyMhz, @WifiAnnotations.Bandwidth int bandwidth); + } + + /** + * Callback to notify the results of a + * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} call. + * Note: no callbacks will be triggered if the interface dies while sending a frame. + */ + public interface SendMgmtFrameCallback { + /** + * Called when the management frame was successfully sent and ACKed by the recipient. + * @param elapsedTimeMs The elapsed time between when the management frame was sent and when + * the ACK was processed, in milliseconds, as measured by wificond. + * This includes the time that the send frame spent queuing before it + * was sent, any firmware retries, and the time the received ACK spent + * queuing before it was processed. + */ + void onAck(int elapsedTimeMs); + + /** + * Called when the send failed. + * @param reason The error code for the failure. + */ + void onFailure(@SendMgmtFrameError int reason); + } + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"SEND_MGMT_FRAME_ERROR_"}, + value = {SEND_MGMT_FRAME_ERROR_UNKNOWN, + SEND_MGMT_FRAME_ERROR_MCS_UNSUPPORTED, + SEND_MGMT_FRAME_ERROR_NO_ACK, + SEND_MGMT_FRAME_ERROR_TIMEOUT, + SEND_MGMT_FRAME_ERROR_ALREADY_STARTED}) + public @interface SendMgmtFrameError {} + + // Send management frame error codes + + /** + * Unknown error occurred during call to + * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)}. + */ + public static final int SEND_MGMT_FRAME_ERROR_UNKNOWN = 1; + + /** + * Specifying the MCS rate in + * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} is not + * supported by this device. + */ + public static final int SEND_MGMT_FRAME_ERROR_MCS_UNSUPPORTED = 2; + + /** + * Driver reported that no ACK was received for the frame transmitted using + * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)}. + */ + public static final int SEND_MGMT_FRAME_ERROR_NO_ACK = 3; + + /** + * Error code for when the driver fails to report on the status of the frame sent by + * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} + * after {@link #SEND_MGMT_FRAME_TIMEOUT_MS} milliseconds. + */ + public static final int SEND_MGMT_FRAME_ERROR_TIMEOUT = 4; + + /** + * An existing call to + * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} + * is in progress. Another frame cannot be sent until the first call completes. + */ + public static final int SEND_MGMT_FRAME_ERROR_ALREADY_STARTED = 5; + + /** @hide */ + public WifiCondManager(Context context) { + mAlarmManager = context.getSystemService(AlarmManager.class); + mEventHandler = new Handler(context.getMainLooper()); + } + + /** @hide */ + @VisibleForTesting + public WifiCondManager(Context context, IWificond wificond) { + this(context); + mWificond = wificond; + } + + private class PnoScanEventHandler extends IPnoScanEvent.Stub { + private Executor mExecutor; + private ScanEventCallback mCallback; + + PnoScanEventHandler(@NonNull Executor executor, @NonNull ScanEventCallback callback) { + mExecutor = executor; + mCallback = callback; + } + + @Override + public void OnPnoNetworkFound() { + Log.d(TAG, "Pno scan result event"); + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mCallback.onScanResultReady()); + } + + @Override + public void OnPnoScanFailed() { + Log.d(TAG, "Pno Scan failed event"); + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mCallback.onScanFailed()); + } + } + + /** + * Listener for AP Interface events. + */ + private class ApInterfaceEventCallback extends IApInterfaceEventCallback.Stub { + private Executor mExecutor; + private SoftApCallback mSoftApListener; + + ApInterfaceEventCallback(Executor executor, SoftApCallback listener) { + mExecutor = executor; + mSoftApListener = listener; + } + + @Override + public void onConnectedClientsChanged(NativeWifiClient client, boolean isConnected) { + if (mVerboseLoggingEnabled) { + Log.d(TAG, "onConnectedClientsChanged called with " + + client.macAddress + " isConnected: " + isConnected); + } + + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mSoftApListener.onConnectedClientsChanged(client, isConnected)); + } + + @Override + public void onSoftApChannelSwitched(int frequency, int bandwidth) { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mSoftApListener.onSoftApChannelSwitched(frequency, + toFrameworkBandwidth(bandwidth))); + } + + private @WifiAnnotations.Bandwidth int toFrameworkBandwidth(int bandwidth) { + switch(bandwidth) { + case IApInterfaceEventCallback.BANDWIDTH_INVALID: + return SoftApInfo.CHANNEL_WIDTH_INVALID; + case IApInterfaceEventCallback.BANDWIDTH_20_NOHT: + return SoftApInfo.CHANNEL_WIDTH_20MHZ_NOHT; + case IApInterfaceEventCallback.BANDWIDTH_20: + return SoftApInfo.CHANNEL_WIDTH_20MHZ; + case IApInterfaceEventCallback.BANDWIDTH_40: + return SoftApInfo.CHANNEL_WIDTH_40MHZ; + case IApInterfaceEventCallback.BANDWIDTH_80: + return SoftApInfo.CHANNEL_WIDTH_80MHZ; + case IApInterfaceEventCallback.BANDWIDTH_80P80: + return SoftApInfo.CHANNEL_WIDTH_80MHZ_PLUS_MHZ; + case IApInterfaceEventCallback.BANDWIDTH_160: + return SoftApInfo.CHANNEL_WIDTH_160MHZ; + default: + return SoftApInfo.CHANNEL_WIDTH_INVALID; + } + } + } + + /** + * Callback triggered by wificond. + */ + private class SendMgmtFrameEvent extends ISendMgmtFrameEvent.Stub { + private Executor mExecutor; + private SendMgmtFrameCallback mCallback; + private AlarmManager.OnAlarmListener mTimeoutCallback; + /** + * ensures that mCallback is only called once + */ + private boolean mWasCalled; + + private void runIfFirstCall(Runnable r) { + if (mWasCalled) return; + mWasCalled = true; + + mSendMgmtFrameInProgress.set(false); + r.run(); + } + + SendMgmtFrameEvent(@NonNull Executor executor, @NonNull SendMgmtFrameCallback callback) { + mExecutor = executor; + mCallback = callback; + // called in main thread + mTimeoutCallback = () -> runIfFirstCall(() -> { + if (mVerboseLoggingEnabled) { + Log.e(TAG, "Timed out waiting for ACK"); + } + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mCallback.onFailure(SEND_MGMT_FRAME_ERROR_TIMEOUT)); + }); + mWasCalled = false; + + mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, + SystemClock.elapsedRealtime() + SEND_MGMT_FRAME_TIMEOUT_MS, + TIMEOUT_ALARM_TAG, mTimeoutCallback, mEventHandler); + } + + // called in binder thread + @Override + public void OnAck(int elapsedTimeMs) { + // post to main thread + mEventHandler.post(() -> runIfFirstCall(() -> { + mAlarmManager.cancel(mTimeoutCallback); + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mCallback.onAck(elapsedTimeMs)); + })); + } + + // called in binder thread + @Override + public void OnFailure(int reason) { + // post to main thread + mEventHandler.post(() -> runIfFirstCall(() -> { + mAlarmManager.cancel(mTimeoutCallback); + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mCallback.onFailure(reason)); + })); + } + } + + /** + * Called by the binder subsystem upon remote object death. + * Invoke all the register death handlers and clear state. + * @hide + */ + @VisibleForTesting + public void binderDied() { + mEventHandler.post(() -> { + Log.e(TAG, "Wificond died!"); + clearState(); + // Invalidate the global wificond handle on death. Will be refreshed + // on the next setup call. + mWificond = null; + if (mDeathEventHandler != null) { + mDeathEventHandler.run(); + } + }); + } + + /** + * Enable or disable verbose logging of the WifiCondManager module. + * @param enable True to enable verbose logging. False to disable verbose logging. + */ + public void enableVerboseLogging(boolean enable) { + mVerboseLoggingEnabled = enable; + } + + /** + * Initializes WifiCondManager & registers a death notification for the WifiCondManager which + * acts as a proxy for the wificond daemon (i.e. the death listener will be called when and if + * the wificond daemon dies). + * + * Note: This method clears any existing state in wificond daemon. + * + * @param deathEventHandler A {@link Runnable} to be called whenever the wificond daemon dies. + * @return Returns true on success. + */ + public boolean initialize(@NonNull Runnable deathEventHandler) { + if (mDeathEventHandler != null) { + Log.e(TAG, "Death handler already present"); + } + mDeathEventHandler = deathEventHandler; + tearDownInterfaces(); + return true; + } + + /** + * Helper method to retrieve the global wificond handle and register for + * death notifications. + */ + private boolean retrieveWificondAndRegisterForDeath() { + if (mWificond != null) { + if (mVerboseLoggingEnabled) { + Log.d(TAG, "Wificond handle already retrieved"); + } + // We already have a wificond handle. + return true; + } + IBinder binder = ServiceManager.getService(Context.WIFI_COND_SERVICE); + mWificond = IWificond.Stub.asInterface(binder); + if (mWificond == null) { + Log.e(TAG, "Failed to get reference to wificond"); + return false; + } + try { + mWificond.asBinder().linkToDeath(() -> binderDied(), 0); + } catch (RemoteException e) { + Log.e(TAG, "Failed to register death notification for wificond"); + // The remote has already died. + return false; + } + return true; + } + + /** + * Set up an interface for client (STA) mode. + * + * @param ifaceName Name of the interface to configure. + * @param executor The Executor on which to execute the callbacks. + * @param scanCallback A callback for framework initiated scans. + * @param pnoScanCallback A callback for PNO (offloaded) scans. + * @return true on success. + */ + public boolean setupInterfaceForClientMode(@NonNull String ifaceName, + @NonNull @CallbackExecutor Executor executor, + @NonNull ScanEventCallback scanCallback, @NonNull ScanEventCallback pnoScanCallback) { + Log.d(TAG, "Setting up interface for client mode"); + if (!retrieveWificondAndRegisterForDeath()) { + return false; + } + + if (scanCallback == null || pnoScanCallback == null || executor == null) { + Log.e(TAG, "setupInterfaceForClientMode invoked with null callbacks"); + return false; + } + + IClientInterface clientInterface = null; + try { + clientInterface = mWificond.createClientInterface(ifaceName); + } catch (RemoteException e1) { + Log.e(TAG, "Failed to get IClientInterface due to remote exception"); + return false; + } + + if (clientInterface == null) { + Log.e(TAG, "Could not get IClientInterface instance from wificond"); + return false; + } + Binder.allowBlocking(clientInterface.asBinder()); + + // Refresh Handlers + mClientInterfaces.put(ifaceName, clientInterface); + try { + IWifiScannerImpl wificondScanner = clientInterface.getWifiScannerImpl(); + if (wificondScanner == null) { + Log.e(TAG, "Failed to get WificondScannerImpl"); + return false; + } + mWificondScanners.put(ifaceName, wificondScanner); + Binder.allowBlocking(wificondScanner.asBinder()); + ScanEventHandler scanEventHandler = new ScanEventHandler(executor, scanCallback); + mScanEventHandlers.put(ifaceName, scanEventHandler); + wificondScanner.subscribeScanEvents(scanEventHandler); + PnoScanEventHandler pnoScanEventHandler = new PnoScanEventHandler(executor, + pnoScanCallback); + mPnoScanEventHandlers.put(ifaceName, pnoScanEventHandler); + wificondScanner.subscribePnoScanEvents(pnoScanEventHandler); + } catch (RemoteException e) { + Log.e(TAG, "Failed to refresh wificond scanner due to remote exception"); + } + + return true; + } + + /** + * Tear down a specific client (STA) interface, initially configured using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}. + * + * @param ifaceName Name of the interface to tear down. + * @return Returns true on success. + */ + public boolean tearDownClientInterface(@NonNull String ifaceName) { + if (getClientInterface(ifaceName) == null) { + Log.e(TAG, "No valid wificond client interface handler"); + return false; + } + try { + IWifiScannerImpl scannerImpl = mWificondScanners.get(ifaceName); + if (scannerImpl != null) { + scannerImpl.unsubscribeScanEvents(); + scannerImpl.unsubscribePnoScanEvents(); + } + } catch (RemoteException e) { + Log.e(TAG, "Failed to unsubscribe wificond scanner due to remote exception"); + return false; + } + + if (mWificond == null) { + Log.e(TAG, "Reference to wifiCond is null"); + return false; + } + + boolean success; + try { + success = mWificond.tearDownClientInterface(ifaceName); + } catch (RemoteException e1) { + Log.e(TAG, "Failed to teardown client interface due to remote exception"); + return false; + } + if (!success) { + Log.e(TAG, "Failed to teardown client interface"); + return false; + } + + mClientInterfaces.remove(ifaceName); + mWificondScanners.remove(ifaceName); + mScanEventHandlers.remove(ifaceName); + mPnoScanEventHandlers.remove(ifaceName); + return true; + } + + /** + * Set up interface as a Soft AP. + * + * @param ifaceName Name of the interface to configure. + * @return true on success. + */ + public boolean setupInterfaceForSoftApMode(@NonNull String ifaceName) { + Log.d(TAG, "Setting up interface for soft ap mode"); + if (!retrieveWificondAndRegisterForDeath()) { + return false; + } + + IApInterface apInterface = null; + try { + apInterface = mWificond.createApInterface(ifaceName); + } catch (RemoteException e1) { + Log.e(TAG, "Failed to get IApInterface due to remote exception"); + return false; + } + + if (apInterface == null) { + Log.e(TAG, "Could not get IApInterface instance from wificond"); + return false; + } + Binder.allowBlocking(apInterface.asBinder()); + + // Refresh Handlers + mApInterfaces.put(ifaceName, apInterface); + return true; + } + + /** + * Tear down a Soft AP interface initially configured using + * {@link #setupInterfaceForSoftApMode(String)}. + * + * @param ifaceName Name of the interface to tear down. + * @return Returns true on success. + */ + public boolean tearDownSoftApInterface(@NonNull String ifaceName) { + if (getApInterface(ifaceName) == null) { + Log.e(TAG, "No valid wificond ap interface handler"); + return false; + } + + if (mWificond == null) { + Log.e(TAG, "Reference to wifiCond is null"); + return false; + } + + boolean success; + try { + success = mWificond.tearDownApInterface(ifaceName); + } catch (RemoteException e1) { + Log.e(TAG, "Failed to teardown AP interface due to remote exception"); + return false; + } + if (!success) { + Log.e(TAG, "Failed to teardown AP interface"); + return false; + } + mApInterfaces.remove(ifaceName); + mApInterfaceListeners.remove(ifaceName); + return true; + } + + /** + * Tear down all interfaces, whether clients (STA) or Soft AP. + * + * @return Returns true on success. + */ + public boolean tearDownInterfaces() { + Log.d(TAG, "tearing down interfaces in wificond"); + // Explicitly refresh the wificodn handler because |tearDownInterfaces()| + // could be used to cleanup before we setup any interfaces. + if (!retrieveWificondAndRegisterForDeath()) { + return false; + } + + try { + for (Map.Entry entry : mWificondScanners.entrySet()) { + entry.getValue().unsubscribeScanEvents(); + entry.getValue().unsubscribePnoScanEvents(); + } + mWificond.tearDownInterfaces(); + clearState(); + return true; + } catch (RemoteException e) { + Log.e(TAG, "Failed to tear down interfaces due to remote exception"); + } + + return false; + } + + /** Helper function to look up the interface handle using name */ + private IClientInterface getClientInterface(@NonNull String ifaceName) { + return mClientInterfaces.get(ifaceName); + } + + /** + * Request signal polling. + * + * @param ifaceName Name of the interface on which to poll. + * @return A {@link SignalPollResult} object containing interface statistics, or a null on + * error. + */ + @Nullable public SignalPollResult signalPoll(@NonNull String ifaceName) { + IClientInterface iface = getClientInterface(ifaceName); + if (iface == null) { + Log.e(TAG, "No valid wificond client interface handler"); + return null; + } + + int[] resultArray; + try { + resultArray = iface.signalPoll(); + if (resultArray == null || resultArray.length != 4) { + Log.e(TAG, "Invalid signal poll result from wificond"); + return null; + } + } catch (RemoteException e) { + Log.e(TAG, "Failed to do signal polling due to remote exception"); + return null; + } + return new SignalPollResult(resultArray[0], resultArray[1], resultArray[3], resultArray[2]); + } + + /** + * Get current transmit (Tx) packet counters of the specified interface. + * + * @param ifaceName Name of the interface. + * @return {@link TxPacketCounters} of the current interface or null on error. + */ + @Nullable public TxPacketCounters getTxPacketCounters(@NonNull String ifaceName) { + IClientInterface iface = getClientInterface(ifaceName); + if (iface == null) { + Log.e(TAG, "No valid wificond client interface handler"); + return null; + } + + int[] resultArray; + try { + resultArray = iface.getPacketCounters(); + if (resultArray == null || resultArray.length != 2) { + Log.e(TAG, "Invalid signal poll result from wificond"); + return null; + } + } catch (RemoteException e) { + Log.e(TAG, "Failed to do signal polling due to remote exception"); + return null; + } + return new TxPacketCounters(resultArray[0], resultArray[1]); + } + + /** Helper function to look up the scanner impl handle using name */ + private IWifiScannerImpl getScannerImpl(@NonNull String ifaceName) { + return mWificondScanners.get(ifaceName); + } + + /** + * Fetch the latest scan results of the indicated type for the specified interface. Note that + * this method fetches the latest results - it does not initiate a scan. Initiating a scan can + * be done using {@link #startScan(String, int, Set, List)} or + * {@link #startPnoScan(String, PnoSettings, Executor, PnoScanRequestCallback)}. + * + * @param ifaceName Name of the interface. + * @param scanType The type of scan result to be returned, can be + * {@link #SCAN_TYPE_SINGLE_SCAN} or {@link #SCAN_TYPE_PNO_SCAN}. + * @return Returns an array of {@link NativeScanResult} or an empty array on failure. + */ + @NonNull public List getScanResults(@NonNull String ifaceName, + @ScanResultType int scanType) { + IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); + if (scannerImpl == null) { + Log.e(TAG, "No valid wificond scanner interface handler"); + return new ArrayList<>(); + } + List results = null; + try { + if (scanType == SCAN_TYPE_SINGLE_SCAN) { + results = Arrays.asList(scannerImpl.getScanResults()); + } else { + results = Arrays.asList(scannerImpl.getPnoScanResults()); + } + } catch (RemoteException e1) { + Log.e(TAG, "Failed to create ScanDetail ArrayList"); + } + if (results == null) { + results = new ArrayList<>(); + } + if (mVerboseLoggingEnabled) { + Log.d(TAG, "get " + results.size() + " scan results from wificond"); + } + + return results; + } + + /** + * Return scan type for the parcelable {@link SingleScanSettings} + */ + private static int getScanType(@WifiAnnotations.ScanType int scanType) { + switch (scanType) { + case WifiScanner.SCAN_TYPE_LOW_LATENCY: + return IWifiScannerImpl.SCAN_TYPE_LOW_SPAN; + case WifiScanner.SCAN_TYPE_LOW_POWER: + return IWifiScannerImpl.SCAN_TYPE_LOW_POWER; + case WifiScanner.SCAN_TYPE_HIGH_ACCURACY: + return IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY; + default: + throw new IllegalArgumentException("Invalid scan type " + scanType); + } + } + + /** + * Start a scan using the specified parameters. A scan is an asynchronous operation. The + * result of the operation is returned in the {@link ScanEventCallback} registered when + * setting up an interface using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}. + * The latest scans can be obtained using {@link #getScanResults(String, int)} and using a + * {@link #SCAN_TYPE_SINGLE_SCAN} for the {@code scanType}. + * + * @param ifaceName Name of the interface on which to initiate the scan. + * @param scanType Type of scan to perform, can be any of + * {@link WifiScanner#SCAN_TYPE_HIGH_ACCURACY}, {@link WifiScanner#SCAN_TYPE_LOW_POWER}, or + * {@link WifiScanner#SCAN_TYPE_LOW_LATENCY}. + * @param freqs list of frequencies to scan for, if null scan all supported channels. + * @param hiddenNetworkSSIDs List of hidden networks to be scanned for. + * @return Returns true on success. + */ + public boolean startScan(@NonNull String ifaceName, @WifiAnnotations.ScanType int scanType, + @Nullable Set freqs, @Nullable List hiddenNetworkSSIDs) { + IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); + if (scannerImpl == null) { + Log.e(TAG, "No valid wificond scanner interface handler"); + return false; + } + SingleScanSettings settings = new SingleScanSettings(); + try { + settings.scanType = getScanType(scanType); + } catch (IllegalArgumentException e) { + Log.e(TAG, "Invalid scan type ", e); + return false; + } + settings.channelSettings = new ArrayList<>(); + settings.hiddenNetworks = new ArrayList<>(); + + if (freqs != null) { + for (Integer freq : freqs) { + ChannelSettings channel = new ChannelSettings(); + channel.frequency = freq; + settings.channelSettings.add(channel); + } + } + if (hiddenNetworkSSIDs != null) { + for (byte[] ssid : hiddenNetworkSSIDs) { + HiddenNetwork network = new HiddenNetwork(); + network.ssid = ssid; + + // settings.hiddenNetworks is expected to be very small, so this shouldn't cause + // any performance issues. + if (!settings.hiddenNetworks.contains(network)) { + settings.hiddenNetworks.add(network); + } + } + } + + try { + return scannerImpl.scan(settings); + } catch (RemoteException e1) { + Log.e(TAG, "Failed to request scan due to remote exception"); + } + return false; + } + + /** + * Request a PNO (Preferred Network Offload). The offload request and the scans are asynchronous + * operations. The result of the request are returned in the {@code callback} parameter which + * is an {@link PnoScanRequestCallback}. The scan results are are return in the + * {@link ScanEventCallback} which is registered when setting up an interface using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}. + * The latest PNO scans can be obtained using {@link #getScanResults(String, int)} with the + * {@code scanType} set to {@link #SCAN_TYPE_PNO_SCAN}. + * + * @param ifaceName Name of the interface on which to request a PNO. + * @param pnoSettings PNO scan configuration. + * @param executor The Executor on which to execute the callback. + * @param callback Callback for the results of the offload request. + * @return true on success. + */ + public boolean startPnoScan(@NonNull String ifaceName, @NonNull PnoSettings pnoSettings, + @NonNull @CallbackExecutor Executor executor, + @NonNull PnoScanRequestCallback callback) { + IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); + if (scannerImpl == null) { + Log.e(TAG, "No valid wificond scanner interface handler"); + return false; + } + + if (callback == null || executor == null) { + Log.e(TAG, "startPnoScan called with a null callback"); + return false; + } + + try { + boolean success = scannerImpl.startPnoScan(pnoSettings); + if (success) { + executor.execute(callback::onPnoRequestSucceeded); + } else { + executor.execute(callback::onPnoRequestFailed); + } + return success; + } catch (RemoteException e1) { + Log.e(TAG, "Failed to start pno scan due to remote exception"); + } + return false; + } + + /** + * Stop PNO scan configured with + * {@link #startPnoScan(String, PnoSettings, Executor, PnoScanRequestCallback)}. + * + * @param ifaceName Name of the interface on which the PNO scan was configured. + * @return true on success. + */ + public boolean stopPnoScan(@NonNull String ifaceName) { + IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); + if (scannerImpl == null) { + Log.e(TAG, "No valid wificond scanner interface handler"); + return false; + } + try { + return scannerImpl.stopPnoScan(); + } catch (RemoteException e1) { + Log.e(TAG, "Failed to stop pno scan due to remote exception"); + } + return false; + } + + /** + * Abort ongoing single scan started with {@link #startScan(String, int, Set, List)}. + * + * @param ifaceName Name of the interface on which the scan was started. + */ + public void abortScan(@NonNull String ifaceName) { + IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); + if (scannerImpl == null) { + Log.e(TAG, "No valid wificond scanner interface handler"); + return; + } + try { + scannerImpl.abortScan(); + } catch (RemoteException e1) { + Log.e(TAG, "Failed to request abortScan due to remote exception"); + } + } + + /** + * Query the list of valid frequencies (in MHz) for the provided band. + * The result depends on the on the country code that has been set. + * + * @param band as specified by one of the WifiScanner.WIFI_BAND_* constants. + * The following bands are supported {@link @WifiScanner.WifiBandBasic}: + * WifiScanner.WIFI_BAND_24_GHZ + * WifiScanner.WIFI_BAND_5_GHZ + * WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY + * WifiScanner.WIFI_BAND_6_GHZ + * @return frequencies vector of valid frequencies (MHz), or an empty array for error. + * @throws IllegalArgumentException if band is not recognized. + */ + public @NonNull int[] getChannelsMhzForBand(@WifiAnnotations.WifiBandBasic int band) { + if (mWificond == null) { + Log.e(TAG, "No valid wificond scanner interface handler"); + return new int[0]; + } + int[] result = null; + try { + switch (band) { + case WifiScanner.WIFI_BAND_24_GHZ: + result = mWificond.getAvailable2gChannels(); + break; + case WifiScanner.WIFI_BAND_5_GHZ: + result = mWificond.getAvailable5gNonDFSChannels(); + break; + case WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY: + result = mWificond.getAvailableDFSChannels(); + break; + case WifiScanner.WIFI_BAND_6_GHZ: + result = mWificond.getAvailable6gChannels(); + break; + default: + throw new IllegalArgumentException("unsupported band " + band); + } + } catch (RemoteException e1) { + Log.e(TAG, "Failed to request getChannelsForBand due to remote exception"); + } + if (result == null) { + result = new int[0]; + } + return result; + } + + /** Helper function to look up the interface handle using name */ + private IApInterface getApInterface(@NonNull String ifaceName) { + return mApInterfaces.get(ifaceName); + } + + /** + * Register the provided callback handler for SoftAp events. Note that the Soft AP itself is + * configured using {@link #setupInterfaceForSoftApMode(String)}. + * + * @param ifaceName Name of the interface on which to register the callback. + * @param executor The Executor on which to execute the callbacks. + * @param callback Callback for AP events. + * @return true on success, false otherwise. + */ + public boolean registerApCallback(@NonNull String ifaceName, + @NonNull @CallbackExecutor Executor executor, + @NonNull SoftApCallback callback) { + IApInterface iface = getApInterface(ifaceName); + if (iface == null) { + Log.e(TAG, "No valid ap interface handler"); + return false; + } + + if (callback == null || executor == null) { + Log.e(TAG, "registerApCallback called with a null callback"); + return false; + } + + try { + IApInterfaceEventCallback wificondCallback = new ApInterfaceEventCallback(executor, + callback); + mApInterfaceListeners.put(ifaceName, wificondCallback); + boolean success = iface.registerCallback(wificondCallback); + if (!success) { + Log.e(TAG, "Failed to register ap callback."); + return false; + } + } catch (RemoteException e) { + Log.e(TAG, "Exception in registering AP callback: " + e); + return false; + } + return true; + } + + /** + * Send a management frame on the specified interface at the specified rate. Useful for probing + * the link with arbitrary frames. + * + * @param ifaceName The interface on which to send the frame. + * @param frame The raw byte array of the management frame to tramit. + * @param mcs The MCS (modulation and coding scheme), i.e. rate, at which to transmit the + * frame. Specified per IEEE 802.11. + * @param executor The Executor on which to execute the callbacks. + * @param callback A {@link SendMgmtFrameCallback} callback for results of the operation. + */ + public void sendMgmtFrame(@NonNull String ifaceName, @NonNull byte[] frame, int mcs, + @NonNull @CallbackExecutor Executor executor, + @NonNull SendMgmtFrameCallback callback) { + + if (callback == null || executor == null) { + Log.e(TAG, "callback cannot be null!"); + return; + } + + if (frame == null) { + Log.e(TAG, "frame cannot be null!"); + executor.execute(() -> callback.onFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN)); + return; + } + + // TODO (b/112029045) validate mcs + IClientInterface clientInterface = getClientInterface(ifaceName); + if (clientInterface == null) { + Log.e(TAG, "No valid wificond client interface handler"); + executor.execute(() -> callback.onFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN)); + return; + } + + if (!mSendMgmtFrameInProgress.compareAndSet(false, true)) { + Log.e(TAG, "An existing management frame transmission is in progress!"); + executor.execute(() -> callback.onFailure(SEND_MGMT_FRAME_ERROR_ALREADY_STARTED)); + return; + } + + SendMgmtFrameEvent sendMgmtFrameEvent = new SendMgmtFrameEvent(executor, callback); + try { + clientInterface.SendMgmtFrame(frame, sendMgmtFrameEvent, mcs); + } catch (RemoteException e) { + Log.e(TAG, "Exception while starting link probe: " + e); + // Call sendMgmtFrameEvent.OnFailure() instead of callback.onFailure() so that + // sendMgmtFrameEvent can clean up internal state, such as cancelling the timer. + sendMgmtFrameEvent.OnFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN); + } + } + + /** + * Clear all internal handles. + */ + private void clearState() { + // Refresh handlers + mClientInterfaces.clear(); + mWificondScanners.clear(); + mPnoScanEventHandlers.clear(); + mScanEventHandlers.clear(); + mApInterfaces.clear(); + mApInterfaceListeners.clear(); + mSendMgmtFrameInProgress.set(false); + } +} diff --git a/wifi/tests/src/android/net/wifi/WifiCondManagerTest.java b/wifi/tests/src/android/net/wifi/WifiCondManagerTest.java deleted file mode 100644 index 48a9afa1d961..000000000000 --- a/wifi/tests/src/android/net/wifi/WifiCondManagerTest.java +++ /dev/null @@ -1,1281 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.wifi; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Matchers.argThat; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyLong; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import android.app.AlarmManager; -import android.app.test.TestAlarmManager; -import android.content.Context; -import android.net.wifi.util.HexEncoding; -import android.net.wifi.wificond.ChannelSettings; -import android.net.wifi.wificond.HiddenNetwork; -import android.net.wifi.wificond.NativeWifiClient; -import android.net.wifi.wificond.PnoNetwork; -import android.net.wifi.wificond.PnoSettings; -import android.net.wifi.wificond.SingleScanSettings; -import android.os.Handler; -import android.os.IBinder; -import android.os.RemoteException; -import android.os.test.TestLooper; - -import androidx.test.filters.SmallTest; - -import org.junit.Before; -import org.junit.Test; -import org.mockito.AdditionalMatchers; -import org.mockito.ArgumentCaptor; -import org.mockito.ArgumentMatcher; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.charset.CharacterCodingException; -import java.nio.charset.CharsetDecoder; -import java.nio.charset.CharsetEncoder; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -/** - * Unit tests for {@link android.net.wifi.WifiCondManager}. - */ -@SmallTest -public class WifiCondManagerTest { - @Mock - private IWificond mWificond; - @Mock - private IBinder mWifiCondBinder; - @Mock - private IClientInterface mClientInterface; - @Mock - private IWifiScannerImpl mWifiScannerImpl; - @Mock - private IApInterface mApInterface; - @Mock - private WifiCondManager.SoftApListener mSoftApListener; - @Mock - private WifiCondManager.SendMgmtFrameCallback mSendMgmtFrameCallback; - @Mock - private WifiCondManager.ScanEventCallback mNormalScanCallback; - @Mock - private WifiCondManager.ScanEventCallback mPnoScanCallback; - @Mock - private WifiCondManager.PnoScanRequestCallback mPnoScanRequestCallback; - @Mock - private Context mContext; - private TestLooper mLooper; - private TestAlarmManager mTestAlarmManager; - private AlarmManager mAlarmManager; - private WifiCondManager mWificondControl; - private static final String TEST_INTERFACE_NAME = "test_wlan_if"; - private static final String TEST_INTERFACE_NAME1 = "test_wlan_if1"; - private static final String TEST_INVALID_INTERFACE_NAME = "asdf"; - private static final byte[] TEST_SSID = - new byte[]{'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'}; - private static final byte[] TEST_PSK = - new byte[]{'T', 'e', 's', 't'}; - - private static final Set SCAN_FREQ_SET = - new HashSet() {{ - add(2410); - add(2450); - add(5050); - add(5200); - }}; - private static final String TEST_QUOTED_SSID_1 = "\"testSsid1\""; - private static final String TEST_QUOTED_SSID_2 = "\"testSsid2\""; - private static final int[] TEST_FREQUENCIES_1 = {}; - private static final int[] TEST_FREQUENCIES_2 = {2500, 5124}; - - private static final List SCAN_HIDDEN_NETWORK_SSID_LIST = - new ArrayList() {{ - add(LocalNativeUtil.byteArrayFromArrayList( - LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_1))); - add(LocalNativeUtil.byteArrayFromArrayList( - LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_2))); - }}; - - private static final PnoSettings TEST_PNO_SETTINGS = - new PnoSettings() {{ - intervalMs = 6000; - pnoNetworks = new ArrayList<>(); - PnoNetwork network = new PnoNetwork(); - network.ssid = LocalNativeUtil.byteArrayFromArrayList( - LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_1)); - network.isHidden = true; - network.frequencies = TEST_FREQUENCIES_1; - pnoNetworks.add(network); - network.ssid = LocalNativeUtil.byteArrayFromArrayList( - LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_2)); - network.isHidden = false; - network.frequencies = TEST_FREQUENCIES_2; - pnoNetworks.add(network); - }}; - - private static final int TEST_MCS_RATE = 5; - private static final int TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS = 100; - private static final byte[] TEST_PROBE_FRAME = { - 0x40, 0x00, 0x3c, 0x00, (byte) 0xa8, (byte) 0xbd, 0x27, 0x5b, - 0x33, 0x72, (byte) 0xf4, (byte) 0xf5, (byte) 0xe8, 0x51, (byte) 0x9e, 0x09, - (byte) 0xa8, (byte) 0xbd, 0x27, 0x5b, 0x33, 0x72, (byte) 0xb0, 0x66, - 0x00, 0x00 - }; - - @Before - public void setUp() throws Exception { - // Setup mocks for successful WificondControl operation. Failure case mocks should be - // created in specific tests - MockitoAnnotations.initMocks(this); - - mTestAlarmManager = new TestAlarmManager(); - mAlarmManager = mTestAlarmManager.getAlarmManager(); - when(mContext.getSystemServiceName(AlarmManager.class)).thenReturn(Context.ALARM_SERVICE); - when(mContext.getSystemService(AlarmManager.class)).thenReturn(mAlarmManager); - - mLooper = new TestLooper(); - when(mContext.getMainLooper()).thenReturn(mLooper.getLooper()); - - when(mWificond.asBinder()).thenReturn(mWifiCondBinder); - when(mClientInterface.getWifiScannerImpl()).thenReturn(mWifiScannerImpl); - when(mWificond.createClientInterface(any())).thenReturn(mClientInterface); - when(mWificond.createApInterface(any())).thenReturn(mApInterface); - when(mWificond.tearDownClientInterface(any())).thenReturn(true); - when(mWificond.tearDownApInterface(any())).thenReturn(true); - when(mClientInterface.getWifiScannerImpl()).thenReturn(mWifiScannerImpl); - when(mClientInterface.getInterfaceName()).thenReturn(TEST_INTERFACE_NAME); - mWificondControl = new WifiCondManager(mContext, mWificond); - assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, - mNormalScanCallback, mPnoScanCallback)); - } - - /** - * Verifies that setupInterfaceForClientMode(TEST_INTERFACE_NAME) calls Wificond. - */ - @Test - public void testSetupInterfaceForClientMode() throws Exception { - when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); - verify(mWificond).createClientInterface(TEST_INTERFACE_NAME); - } - - /** - * Verifies that setupInterfaceForClientMode(TEST_INTERFACE_NAME) calls subscribeScanEvents(). - */ - @Test - public void testSetupInterfaceForClientModeCallsScanEventSubscripiton() throws Exception { - verify(mWifiScannerImpl).subscribeScanEvents(any(IScanEvent.class)); - } - - /** - * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. - */ - @Test - public void testTeardownClientInterface() throws Exception { - when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(true); - - assertTrue(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); - verify(mWifiScannerImpl).unsubscribeScanEvents(); - verify(mWifiScannerImpl).unsubscribePnoScanEvents(); - verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME); - } - - /** - * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. - */ - @Test - public void testTeardownClientInterfaceOnInvalidIface() throws Exception { - when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME1)).thenReturn(true); - - assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME1)); - verify(mWifiScannerImpl, never()).unsubscribeScanEvents(); - verify(mWifiScannerImpl, never()).unsubscribePnoScanEvents(); - verify(mWificond, never()).tearDownClientInterface(any()); - } - - /** - * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. - */ - @Test - public void testTeardownClientInterfaceFailDueToExceptionScannerUnsubscribe() throws Exception { - when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(true); - doThrow(new RemoteException()).when(mWifiScannerImpl).unsubscribeScanEvents(); - - assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); - verify(mWifiScannerImpl).unsubscribeScanEvents(); - verify(mWifiScannerImpl, never()).unsubscribePnoScanEvents(); - verify(mWificond, never()).tearDownClientInterface(TEST_INTERFACE_NAME); - } - - /** - * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. - */ - @Test - public void testTeardownClientInterfaceErrorWhenWificondFailed() throws Exception { - when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(false); - - assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); - verify(mWifiScannerImpl).unsubscribeScanEvents(); - verify(mWifiScannerImpl).unsubscribePnoScanEvents(); - verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME); - } - - /** - * Verifies that the client handles are cleared after teardown. - */ - @Test - public void testTeardownClientInterfaceClearsHandles() throws Exception { - testTeardownClientInterface(); - - assertNull(mWificondControl.signalPoll(TEST_INTERFACE_NAME)); - verify(mClientInterface, never()).signalPoll(); - - assertFalse(mWificondControl.scan( - TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_LATENCY, - SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); - verify(mWifiScannerImpl, never()).scan(any()); - } - - /** - * Verifies that setupInterfaceForSoftApMode(TEST_INTERFACE_NAME) calls wificond. - */ - @Test - public void testSetupInterfaceForSoftApMode() throws Exception { - when(mWificond.createApInterface(TEST_INTERFACE_NAME)).thenReturn(mApInterface); - - assertEquals(true, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME)); - verify(mWificond).createApInterface(TEST_INTERFACE_NAME); - } - - /** - * Verifies that setupInterfaceForSoftAp() returns null when wificond is not started. - */ - @Test - public void testSetupInterfaceForSoftApModeErrorWhenWificondIsNotStarted() throws Exception { - // Invoke wificond death handler to clear the handle. - mWificondControl.binderDied(); - mLooper.dispatchAll(); - - assertEquals(false, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME)); - } - - /** - * Verifies that setupInterfaceForSoftApMode(TEST_INTERFACE_NAME) returns null when wificond - * failed to setup AP interface. - */ - @Test - public void testSetupInterfaceForSoftApModeErrorWhenWificondFailedToSetupInterface() - throws Exception { - when(mWificond.createApInterface(TEST_INTERFACE_NAME)).thenReturn(null); - - assertEquals(false, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME)); - } - - /** - * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. - */ - @Test - public void testTeardownSoftApInterface() throws Exception { - testSetupInterfaceForSoftApMode(); - when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME)).thenReturn(true); - - assertTrue(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME)); - verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME); - } - - /** - * Verifies that tearDownSoftapInterface(TEST_INTERFACE_NAME) calls Wificond. - */ - @Test - public void testTeardownSoftApInterfaceOnInvalidIface() throws Exception { - testSetupInterfaceForSoftApMode(); - when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME1)).thenReturn(true); - - assertFalse(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME1)); - verify(mWificond, never()).tearDownApInterface(any()); - } - - /** - * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. - */ - @Test - public void testTeardownSoftApInterfaceErrorWhenWificondFailed() throws Exception { - testSetupInterfaceForSoftApMode(); - when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME)).thenReturn(false); - - assertFalse(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME)); - verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME); - } - - /** - * Verifies that the SoftAp handles are cleared after teardown. - */ - @Test - public void testTeardownSoftApInterfaceClearsHandles() throws Exception { - testTeardownSoftApInterface(); - - assertFalse(mWificondControl.registerApListener( - TEST_INTERFACE_NAME, mSoftApListener)); - verify(mApInterface, never()).registerCallback(any()); - } - - /** - * Verifies that we can setup concurrent interfaces. - */ - @Test - public void testSetupMultipleInterfaces() throws Exception { - when(mWificond.createApInterface(TEST_INTERFACE_NAME1)).thenReturn(mApInterface); - - assertEquals(true, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME1)); - - verify(mWificond).createClientInterface(TEST_INTERFACE_NAME); - verify(mWificond).createApInterface(TEST_INTERFACE_NAME1); - } - - /** - * Verifies that we can setup concurrent interfaces. - */ - @Test - public void testTeardownMultipleInterfaces() throws Exception { - testSetupMultipleInterfaces(); - assertTrue(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); - assertTrue(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME1)); - - verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME); - verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME1); - } - - /** - * Verifies that tearDownInterfaces() calls wificond. - */ - @Test - public void testTearDownInterfaces() throws Exception { - assertTrue(mWificondControl.tearDownInterfaces()); - verify(mWificond).tearDownInterfaces(); - } - - /** - * Verifies that tearDownInterfaces() calls unsubscribeScanEvents() when there was - * a configured client interface. - */ - @Test - public void testTearDownInterfacesRemovesScanEventSubscription() throws Exception { - assertTrue(mWificondControl.tearDownInterfaces()); - verify(mWifiScannerImpl).unsubscribeScanEvents(); - } - - - /** - * Verifies that tearDownInterfaces() returns false when wificond is not started. - */ - @Test - public void testTearDownInterfacesErrorWhenWificondIsNotStarterd() throws Exception { - // Invoke wificond death handler to clear the handle. - mWificondControl.binderDied(); - mLooper.dispatchAll(); - assertFalse(mWificondControl.tearDownInterfaces()); - } - - /** - * Verifies that signalPoll() calls wificond. - */ - @Test - public void testSignalPoll() throws Exception { - when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); - - mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, mNormalScanCallback, - mPnoScanCallback); - mWificondControl.signalPoll(TEST_INTERFACE_NAME); - verify(mClientInterface).signalPoll(); - } - - /** - * Verifies that signalPoll() returns null when there is no configured client interface. - */ - @Test - public void testSignalPollErrorWhenNoClientInterfaceConfigured() throws Exception { - when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); - - // Configure client interface. - assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, - mNormalScanCallback, mPnoScanCallback)); - - // Tear down interfaces. - assertTrue(mWificondControl.tearDownInterfaces()); - - // Signal poll should fail. - assertEquals(null, mWificondControl.signalPoll(TEST_INTERFACE_NAME)); - } - - /** - * Verifies that getTxPacketCounters() calls wificond. - */ - @Test - public void testGetTxPacketCounters() throws Exception { - when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); - - mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, mNormalScanCallback, - mPnoScanCallback); - mWificondControl.getTxPacketCounters(TEST_INTERFACE_NAME); - verify(mClientInterface).getPacketCounters(); - } - - /** - * Verifies that getTxPacketCounters() returns null when there is no configured client - * interface. - */ - @Test - public void testGetTxPacketCountersErrorWhenNoClientInterfaceConfigured() throws Exception { - when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); - - // Configure client interface. - assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, - mNormalScanCallback, mPnoScanCallback)); - - // Tear down interfaces. - assertTrue(mWificondControl.tearDownInterfaces()); - - // Signal poll should fail. - assertEquals(null, mWificondControl.getTxPacketCounters(TEST_INTERFACE_NAME)); - } - - /** - * Verifies that getScanResults() returns null when there is no configured client - * interface. - */ - @Test - public void testGetScanResultsErrorWhenNoClientInterfaceConfigured() throws Exception { - when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); - - // Configure client interface. - assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, - mNormalScanCallback, mPnoScanCallback)); - - // Tear down interfaces. - assertTrue(mWificondControl.tearDownInterfaces()); - - // getScanResults should fail. - assertEquals(0, - mWificondControl.getScanResults(TEST_INTERFACE_NAME, - WifiCondManager.SCAN_TYPE_SINGLE_SCAN).size()); - } - - /** - * Verifies that Scan() can convert input parameters to SingleScanSettings correctly. - */ - @Test - public void testScan() throws Exception { - when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true); - assertTrue(mWificondControl.scan( - TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_POWER, - SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); - verify(mWifiScannerImpl).scan(argThat(new ScanMatcher( - IWifiScannerImpl.SCAN_TYPE_LOW_POWER, - SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST))); - } - - /** - * Verifies that Scan() removes duplicates hiddenSsids passed in from input. - */ - @Test - public void testScanWithDuplicateHiddenSsids() throws Exception { - when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true); - // Create a list of hiddenSsid that has a duplicate element - List hiddenSsidWithDup = new ArrayList<>(SCAN_HIDDEN_NETWORK_SSID_LIST); - hiddenSsidWithDup.add(SCAN_HIDDEN_NETWORK_SSID_LIST.get(0)); - assertEquals(hiddenSsidWithDup.get(0), - hiddenSsidWithDup.get(hiddenSsidWithDup.size() - 1)); - // Pass the List with duplicate elements into scan() - assertTrue(mWificondControl.scan( - TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_POWER, - SCAN_FREQ_SET, hiddenSsidWithDup)); - // But the argument passed down should have the duplicate removed. - verify(mWifiScannerImpl).scan(argThat(new ScanMatcher( - IWifiScannerImpl.SCAN_TYPE_LOW_POWER, - SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST))); - } - - /** - * Verifies that Scan() can handle null input parameters correctly. - */ - @Test - public void testScanNullParameters() throws Exception { - when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true); - assertTrue(mWificondControl.scan( - TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_HIGH_ACCURACY, null, null)); - verify(mWifiScannerImpl).scan(argThat(new ScanMatcher( - IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY, null, null))); - } - - /** - * Verifies that Scan() can handle wificond scan failure. - */ - @Test - public void testScanFailure() throws Exception { - when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(false); - assertFalse(mWificondControl.scan( - TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_LATENCY, - SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); - verify(mWifiScannerImpl).scan(any(SingleScanSettings.class)); - } - - /** - * Verifies that Scan() can handle invalid type. - */ - @Test - public void testScanFailureDueToInvalidType() throws Exception { - assertFalse(mWificondControl.scan( - TEST_INTERFACE_NAME, 100, - SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); - verify(mWifiScannerImpl, never()).scan(any(SingleScanSettings.class)); - } - - /** - * Verifies that startPnoScan() can convert input parameters to PnoSettings correctly. - */ - @Test - public void testStartPnoScan() throws Exception { - when(mWifiScannerImpl.startPnoScan(any(PnoSettings.class))).thenReturn(true); - assertTrue(mWificondControl.startPnoScan(TEST_INTERFACE_NAME, TEST_PNO_SETTINGS, - mPnoScanRequestCallback)); - verify(mWifiScannerImpl).startPnoScan(argThat(new PnoScanMatcher(TEST_PNO_SETTINGS))); - verify(mPnoScanRequestCallback).onPnoRequestSucceeded(); - } - - /** - * Verifies that stopPnoScan() calls underlying wificond. - */ - @Test - public void testStopPnoScan() throws Exception { - when(mWifiScannerImpl.stopPnoScan()).thenReturn(true); - assertTrue(mWificondControl.stopPnoScan(TEST_INTERFACE_NAME)); - verify(mWifiScannerImpl).stopPnoScan(); - } - - /** - * Verifies that stopPnoScan() can handle wificond failure. - */ - @Test - public void testStopPnoScanFailure() throws Exception { - - when(mWifiScannerImpl.stopPnoScan()).thenReturn(false); - assertFalse(mWificondControl.stopPnoScan(TEST_INTERFACE_NAME)); - verify(mWifiScannerImpl).stopPnoScan(); - } - - /** - * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon scan - * result event. - */ - @Test - public void testScanResultEvent() throws Exception { - ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(IScanEvent.class); - verify(mWifiScannerImpl).subscribeScanEvents(messageCaptor.capture()); - IScanEvent scanEvent = messageCaptor.getValue(); - assertNotNull(scanEvent); - scanEvent.OnScanResultReady(); - - verify(mNormalScanCallback).onScanResultReady(); - } - - /** - * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon scan - * failed event. - */ - @Test - public void testScanFailedEvent() throws Exception { - ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(IScanEvent.class); - verify(mWifiScannerImpl).subscribeScanEvents(messageCaptor.capture()); - IScanEvent scanEvent = messageCaptor.getValue(); - assertNotNull(scanEvent); - scanEvent.OnScanFailed(); - - verify(mNormalScanCallback).onScanFailed(); - } - - /** - * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon pno scan - * result event. - */ - @Test - public void testPnoScanResultEvent() throws Exception { - ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(IPnoScanEvent.class); - verify(mWifiScannerImpl).subscribePnoScanEvents(messageCaptor.capture()); - IPnoScanEvent pnoScanEvent = messageCaptor.getValue(); - assertNotNull(pnoScanEvent); - pnoScanEvent.OnPnoNetworkFound(); - verify(mPnoScanCallback).onScanResultReady(); - } - - /** - * Verifies that WificondControl can invoke WifiMetrics pno scan count methods upon pno event. - */ - @Test - public void testPnoScanEventsForMetrics() throws Exception { - ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(IPnoScanEvent.class); - verify(mWifiScannerImpl).subscribePnoScanEvents(messageCaptor.capture()); - IPnoScanEvent pnoScanEvent = messageCaptor.getValue(); - assertNotNull(pnoScanEvent); - - pnoScanEvent.OnPnoNetworkFound(); - verify(mPnoScanCallback).onScanResultReady(); - - pnoScanEvent.OnPnoScanFailed(); - verify(mPnoScanCallback).onScanFailed(); - } - - /** - * Verifies that startPnoScan() can invoke WifiMetrics pno scan count methods correctly. - */ - @Test - public void testStartPnoScanForMetrics() throws Exception { - when(mWifiScannerImpl.startPnoScan(any(PnoSettings.class))).thenReturn(false); - - assertFalse(mWificondControl.startPnoScan(TEST_INTERFACE_NAME, TEST_PNO_SETTINGS, - mPnoScanRequestCallback)); - verify(mPnoScanRequestCallback).onPnoRequestFailed(); - } - - /** - * Verifies that abortScan() calls underlying wificond. - */ - @Test - public void testAbortScan() throws Exception { - mWificondControl.abortScan(TEST_INTERFACE_NAME); - verify(mWifiScannerImpl).abortScan(); - } - - /** - * Ensures that the Ap interface callbacks are forwarded to the - * SoftApListener used for starting soft AP. - */ - @Test - public void testSoftApListenerInvocation() throws Exception { - testSetupInterfaceForSoftApMode(); - - WifiConfiguration config = new WifiConfiguration(); - config.SSID = new String(TEST_SSID, StandardCharsets.UTF_8); - - when(mApInterface.registerCallback(any())).thenReturn(true); - - final ArgumentCaptor apInterfaceCallbackCaptor = - ArgumentCaptor.forClass(IApInterfaceEventCallback.class); - - assertTrue(mWificondControl.registerApListener( - TEST_INTERFACE_NAME, mSoftApListener)); - verify(mApInterface).registerCallback(apInterfaceCallbackCaptor.capture()); - - final NativeWifiClient testClient = new NativeWifiClient(); - apInterfaceCallbackCaptor.getValue().onConnectedClientsChanged(testClient, true); - verify(mSoftApListener).onConnectedClientsChanged(eq(testClient), eq(true)); - - int channelFrequency = 2437; - int channelBandwidth = IApInterfaceEventCallback.BANDWIDTH_20; - apInterfaceCallbackCaptor.getValue().onSoftApChannelSwitched(channelFrequency, - channelBandwidth); - verify(mSoftApListener).onSoftApChannelSwitched(eq(channelFrequency), eq(channelBandwidth)); - } - - /** - * Verifies registration and invocation of wificond death handler. - */ - @Test - public void testRegisterDeathHandler() throws Exception { - Runnable deathHandler = mock(Runnable.class); - assertTrue(mWificondControl.initialize(deathHandler)); - verify(mWificond).tearDownInterfaces(); - mWificondControl.binderDied(); - mLooper.dispatchAll(); - verify(deathHandler).run(); - } - - /** - * Verifies handling of wificond death and ensures that all internal state is cleared and - * handlers are invoked. - */ - @Test - public void testDeathHandling() throws Exception { - Runnable deathHandler = mock(Runnable.class); - assertTrue(mWificondControl.initialize(deathHandler)); - - testSetupInterfaceForClientMode(); - - mWificondControl.binderDied(); - mLooper.dispatchAll(); - verify(deathHandler).run(); - - // The handles should be cleared after death. - assertNull(mWificondControl.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ)); - verify(mWificond, never()).getAvailable5gNonDFSChannels(); - } - - /** - * sendMgmtFrame() should fail if a null callback is passed in. - */ - @Test - public void testSendMgmtFrameNullCallback() throws Exception { - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, null, TEST_MCS_RATE); - - verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt()); - } - - /** - * sendMgmtFrame() should fail if a null frame is passed in. - */ - @Test - public void testSendMgmtFrameNullFrame() throws Exception { - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, null, - mSendMgmtFrameCallback, TEST_MCS_RATE); - - verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt()); - verify(mSendMgmtFrameCallback).onFailure(anyInt()); - } - - /** - * sendMgmtFrame() should fail if an interface name that does not exist is passed in. - */ - @Test - public void testSendMgmtFrameInvalidInterfaceName() throws Exception { - mWificondControl.sendMgmtFrame(TEST_INVALID_INTERFACE_NAME, TEST_PROBE_FRAME, - mSendMgmtFrameCallback, TEST_MCS_RATE); - - verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt()); - verify(mSendMgmtFrameCallback).onFailure(anyInt()); - } - - /** - * sendMgmtFrame() should fail if it is called a second time before the first call completed. - */ - @Test - public void testSendMgmtFrameCalledTwiceBeforeFinished() throws Exception { - WifiCondManager.SendMgmtFrameCallback cb1 = mock( - WifiCondManager.SendMgmtFrameCallback.class); - WifiCondManager.SendMgmtFrameCallback cb2 = mock( - WifiCondManager.SendMgmtFrameCallback.class); - - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, cb1, TEST_MCS_RATE); - verify(cb1, never()).onFailure(anyInt()); - verify(mClientInterface, times(1)) - .SendMgmtFrame(AdditionalMatchers.aryEq(TEST_PROBE_FRAME), - any(), eq(TEST_MCS_RATE)); - - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, cb2, TEST_MCS_RATE); - verify(cb2).onFailure(WifiCondManager.SEND_MGMT_FRAME_ERROR_ALREADY_STARTED); - // verify SendMgmtFrame() still was only called once i.e. not called again - verify(mClientInterface, times(1)) - .SendMgmtFrame(any(), any(), anyInt()); - } - - /** - * Tests that when a RemoteException is triggered on AIDL call, onFailure() is called only once. - */ - @Test - public void testSendMgmtFrameThrowsException() throws Exception { - WifiCondManager.SendMgmtFrameCallback cb = mock( - WifiCondManager.SendMgmtFrameCallback.class); - - final ArgumentCaptor sendMgmtFrameEventCaptor = - ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); - - doThrow(new RemoteException()).when(mClientInterface) - .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); - - final ArgumentCaptor alarmListenerCaptor = - ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); - final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); - doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), - alarmListenerCaptor.capture(), handlerCaptor.capture()); - - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, - cb, TEST_MCS_RATE); - mLooper.dispatchAll(); - - verify(cb).onFailure(anyInt()); - verify(mAlarmManager).cancel(eq(alarmListenerCaptor.getValue())); - - sendMgmtFrameEventCaptor.getValue().OnFailure( - WifiCondManager.SEND_MGMT_FRAME_ERROR_UNKNOWN); - mLooper.dispatchAll(); - - handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); - mLooper.dispatchAll(); - - verifyNoMoreInteractions(cb); - } - - /** - * Tests that the onAck() callback is triggered correctly. - */ - @Test - public void testSendMgmtFrameSuccess() throws Exception { - WifiCondManager.SendMgmtFrameCallback cb = mock( - WifiCondManager.SendMgmtFrameCallback.class); - - final ArgumentCaptor sendMgmtFrameEventCaptor = - ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); - doNothing().when(mClientInterface) - .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); - final ArgumentCaptor alarmListenerCaptor = - ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); - final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); - doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), - alarmListenerCaptor.capture(), handlerCaptor.capture()); - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, cb, TEST_MCS_RATE); - - sendMgmtFrameEventCaptor.getValue().OnAck(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS); - mLooper.dispatchAll(); - verify(cb).onAck(eq(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS)); - verify(cb, never()).onFailure(anyInt()); - verify(mAlarmManager).cancel(eq(alarmListenerCaptor.getValue())); - - // verify that even if timeout is triggered afterwards, SendMgmtFrameCallback is not - // triggered again - handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); - mLooper.dispatchAll(); - verify(cb, times(1)).onAck(anyInt()); - verify(cb, never()).onFailure(anyInt()); - } - - /** - * Tests that the onFailure() callback is triggered correctly. - */ - @Test - public void testSendMgmtFrameFailure() throws Exception { - WifiCondManager.SendMgmtFrameCallback cb = mock( - WifiCondManager.SendMgmtFrameCallback.class); - - final ArgumentCaptor sendMgmtFrameEventCaptor = - ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); - doNothing().when(mClientInterface) - .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); - final ArgumentCaptor alarmListenerCaptor = - ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); - final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); - doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), - alarmListenerCaptor.capture(), handlerCaptor.capture()); - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, cb, TEST_MCS_RATE); - - sendMgmtFrameEventCaptor.getValue().OnFailure( - WifiCondManager.SEND_MGMT_FRAME_ERROR_UNKNOWN); - mLooper.dispatchAll(); - verify(cb, never()).onAck(anyInt()); - verify(cb).onFailure(WifiCondManager.SEND_MGMT_FRAME_ERROR_UNKNOWN); - verify(mAlarmManager).cancel(eq(alarmListenerCaptor.getValue())); - - // verify that even if timeout is triggered afterwards, SendMgmtFrameCallback is not - // triggered again - handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); - mLooper.dispatchAll(); - verify(cb, never()).onAck(anyInt()); - verify(cb, times(1)).onFailure(anyInt()); - } - - /** - * Tests that the onTimeout() callback is triggered correctly. - */ - @Test - public void testSendMgmtFrameTimeout() throws Exception { - WifiCondManager.SendMgmtFrameCallback cb = mock( - WifiCondManager.SendMgmtFrameCallback.class); - - final ArgumentCaptor sendMgmtFrameEventCaptor = - ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); - doNothing().when(mClientInterface) - .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); - final ArgumentCaptor alarmListenerCaptor = - ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); - final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); - doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), - alarmListenerCaptor.capture(), handlerCaptor.capture()); - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, cb, TEST_MCS_RATE); - - handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); - mLooper.dispatchAll(); - verify(cb, never()).onAck(anyInt()); - verify(cb).onFailure(WifiCondManager.SEND_MGMT_FRAME_ERROR_TIMEOUT); - - // verify that even if onAck() callback is triggered after timeout, - // SendMgmtFrameCallback is not triggered again - sendMgmtFrameEventCaptor.getValue().OnAck(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS); - mLooper.dispatchAll(); - verify(cb, never()).onAck(anyInt()); - verify(cb, times(1)).onFailure(anyInt()); - } - - /** - * Tests every possible test outcome followed by every other test outcome to ensure that the - * internal state is reset correctly between calls. - * i.e. (success, success), (success, failure), (success, timeout), - * (failure, failure), (failure, success), (failure, timeout), - * (timeout, timeout), (timeout, success), (timeout, failure) - * - * Also tests that internal state is reset correctly after a transient AIDL RemoteException. - */ - @Test - public void testSendMgmtFrameMixed() throws Exception { - testSendMgmtFrameThrowsException(); - testSendMgmtFrameSuccess(); - testSendMgmtFrameSuccess(); - testSendMgmtFrameFailure(); - testSendMgmtFrameFailure(); - testSendMgmtFrameTimeout(); - testSendMgmtFrameTimeout(); - testSendMgmtFrameSuccess(); - testSendMgmtFrameTimeout(); - testSendMgmtFrameFailure(); - testSendMgmtFrameSuccess(); - } - - /** - * Tests that OnAck() does not perform any non-thread-safe operations on the binder thread. - * - * The sequence of instructions are: - * 1. post onAlarm() onto main thread - * 2. OnAck() - * 3. mLooper.dispatchAll() - * - * The actual order of execution is: - * 1. binder thread portion of OnAck() - * 2. onAlarm() (which purely executes on the main thread) - * 3. main thread portion of OnAck() - * - * If the binder thread portion of OnAck() is not thread-safe, it can possibly mess up - * onAlarm(). Tests that this does not occur. - */ - @Test - public void testSendMgmtFrameTimeoutAckThreadSafe() throws Exception { - final ArgumentCaptor sendMgmtFrameEventCaptor = - ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); - doNothing().when(mClientInterface) - .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); - final ArgumentCaptor alarmListenerCaptor = - ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); - final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); - doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), - alarmListenerCaptor.capture(), handlerCaptor.capture()); - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, - mSendMgmtFrameCallback, TEST_MCS_RATE); - - // AlarmManager should post the onAlarm() callback onto the handler, but since we are - // triggering onAlarm() ourselves during the test, manually post onto handler - handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); - // OnAck posts to the handler - sendMgmtFrameEventCaptor.getValue().OnAck(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS); - mLooper.dispatchAll(); - verify(mSendMgmtFrameCallback, never()).onAck(anyInt()); - verify(mSendMgmtFrameCallback).onFailure(WifiCondManager.SEND_MGMT_FRAME_ERROR_TIMEOUT); - } - - /** - * See {@link #testSendMgmtFrameTimeoutAckThreadSafe()}. This test replaces OnAck() with - * OnFailure(). - */ - @Test - public void testSendMgmtFrameTimeoutFailureThreadSafe() throws Exception { - final ArgumentCaptor sendMgmtFrameEventCaptor = - ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); - doNothing().when(mClientInterface) - .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); - final ArgumentCaptor alarmListenerCaptor = - ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); - final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); - doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), - alarmListenerCaptor.capture(), handlerCaptor.capture()); - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, - mSendMgmtFrameCallback, TEST_MCS_RATE); - - // AlarmManager should post the onAlarm() callback onto the handler, but since we are - // triggering onAlarm() ourselves during the test, manually post onto handler - handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); - // OnFailure posts to the handler - sendMgmtFrameEventCaptor.getValue().OnFailure( - WifiCondManager.SEND_MGMT_FRAME_ERROR_UNKNOWN); - mLooper.dispatchAll(); - verify(mSendMgmtFrameCallback).onFailure(WifiCondManager.SEND_MGMT_FRAME_ERROR_TIMEOUT); - } - - // Create a ArgumentMatcher which captures a SingleScanSettings parameter and checks if it - // matches the provided frequency set and ssid set. - private class ScanMatcher implements ArgumentMatcher { - int mExpectedScanType; - private final Set mExpectedFreqs; - private final List mExpectedSsids; - - ScanMatcher(int expectedScanType, Set expectedFreqs, List expectedSsids) { - this.mExpectedScanType = expectedScanType; - this.mExpectedFreqs = expectedFreqs; - this.mExpectedSsids = expectedSsids; - } - - @Override - public boolean matches(SingleScanSettings settings) { - if (settings.scanType != mExpectedScanType) { - return false; - } - ArrayList channelSettings = settings.channelSettings; - ArrayList hiddenNetworks = settings.hiddenNetworks; - if (mExpectedFreqs != null) { - Set freqSet = new HashSet(); - for (ChannelSettings channel : channelSettings) { - freqSet.add(channel.frequency); - } - if (!mExpectedFreqs.equals(freqSet)) { - return false; - } - } else { - if (channelSettings != null && channelSettings.size() > 0) { - return false; - } - } - - if (mExpectedSsids != null) { - List ssidSet = new ArrayList<>(); - for (HiddenNetwork network : hiddenNetworks) { - ssidSet.add(network.ssid); - } - if (!mExpectedSsids.equals(ssidSet)) { - return false; - } - - } else { - if (hiddenNetworks != null && hiddenNetworks.size() > 0) { - return false; - } - } - return true; - } - - @Override - public String toString() { - return "ScanMatcher{mExpectedFreqs=" + mExpectedFreqs - + ", mExpectedSsids=" + mExpectedSsids + '}'; - } - } - - // Create a ArgumentMatcher which captures a PnoSettings parameter and checks if it - // matches the WifiNative.PnoSettings; - private class PnoScanMatcher implements ArgumentMatcher { - private final PnoSettings mExpectedPnoSettings; - - PnoScanMatcher(PnoSettings expectedPnoSettings) { - this.mExpectedPnoSettings = expectedPnoSettings; - } - - @Override - public boolean matches(PnoSettings settings) { - if (mExpectedPnoSettings == null) { - return false; - } - if (settings.intervalMs != mExpectedPnoSettings.intervalMs - || settings.min2gRssi != mExpectedPnoSettings.min2gRssi - || settings.min5gRssi != mExpectedPnoSettings.min5gRssi - || settings.min6gRssi != mExpectedPnoSettings.min6gRssi) { - return false; - } - if (settings.pnoNetworks == null || mExpectedPnoSettings.pnoNetworks == null) { - return false; - } - if (settings.pnoNetworks.size() != mExpectedPnoSettings.pnoNetworks.size()) { - return false; - } - - for (int i = 0; i < settings.pnoNetworks.size(); i++) { - if (!Arrays.equals(settings.pnoNetworks.get(i).ssid, - mExpectedPnoSettings.pnoNetworks.get(i).ssid)) { - return false; - } - if (settings.pnoNetworks.get(i).isHidden != mExpectedPnoSettings.pnoNetworks.get( - i).isHidden) { - return false; - } - if (!Arrays.equals(settings.pnoNetworks.get(i).frequencies, - mExpectedPnoSettings.pnoNetworks.get(i).frequencies)) { - return false; - } - } - return true; - } - - @Override - public String toString() { - return "PnoScanMatcher{" + "mExpectedPnoSettings=" + mExpectedPnoSettings + '}'; - } - } - - private static class LocalNativeUtil { - private static final int SSID_BYTES_MAX_LEN = 32; - - /** - * Converts an ArrayList of UTF_8 byte values to string. - * The string will either be: - * a) UTF-8 String encapsulated in quotes (if all the bytes are UTF-8 encodeable and non - * null), - * or - * b) Hex string with no delimiters. - * - * @param bytes List of bytes for ssid. - * @throws IllegalArgumentException for null bytes. - */ - public static String bytesToHexOrQuotedString(ArrayList bytes) { - if (bytes == null) { - throw new IllegalArgumentException("null ssid bytes"); - } - byte[] byteArray = byteArrayFromArrayList(bytes); - // Check for 0's in the byte stream in which case we cannot convert this into a string. - if (!bytes.contains(Byte.valueOf((byte) 0))) { - CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder(); - try { - CharBuffer decoded = decoder.decode(ByteBuffer.wrap(byteArray)); - return "\"" + decoded.toString() + "\""; - } catch (CharacterCodingException cce) { - } - } - return hexStringFromByteArray(byteArray); - } - - /** - * Converts an ssid string to an arraylist of UTF_8 byte values. - * These forms are acceptable: - * a) UTF-8 String encapsulated in quotes, or - * b) Hex string with no delimiters. - * - * @param ssidStr String to be converted. - * @throws IllegalArgumentException for null string. - */ - public static ArrayList decodeSsid(String ssidStr) { - ArrayList ssidBytes = hexOrQuotedStringToBytes(ssidStr); - if (ssidBytes.size() > SSID_BYTES_MAX_LEN) { - throw new IllegalArgumentException( - "ssid bytes size out of range: " + ssidBytes.size()); - } - return ssidBytes; - } - - /** - * Convert from an array list of Byte to an array of primitive bytes. - */ - public static byte[] byteArrayFromArrayList(ArrayList bytes) { - byte[] byteArray = new byte[bytes.size()]; - int i = 0; - for (Byte b : bytes) { - byteArray[i++] = b; - } - return byteArray; - } - - /** - * Converts a byte array to hex string. - * - * @param bytes List of bytes for ssid. - * @throws IllegalArgumentException for null bytes. - */ - public static String hexStringFromByteArray(byte[] bytes) { - if (bytes == null) { - throw new IllegalArgumentException("null hex bytes"); - } - return new String(HexEncoding.encode(bytes)).toLowerCase(); - } - - /** - * Converts an string to an arraylist of UTF_8 byte values. - * These forms are acceptable: - * a) UTF-8 String encapsulated in quotes, or - * b) Hex string with no delimiters. - * - * @param str String to be converted. - * @throws IllegalArgumentException for null string. - */ - public static ArrayList hexOrQuotedStringToBytes(String str) { - if (str == null) { - throw new IllegalArgumentException("null string"); - } - int length = str.length(); - if ((length > 1) && (str.charAt(0) == '"') && (str.charAt(length - 1) == '"')) { - str = str.substring(1, str.length() - 1); - return stringToByteArrayList(str); - } else { - return byteArrayToArrayList(hexStringToByteArray(str)); - } - } - - /** - * Convert the string to byte array list. - * - * @return the UTF_8 char byte values of str, as an ArrayList. - * @throws IllegalArgumentException if a null or unencodable string is sent. - */ - public static ArrayList stringToByteArrayList(String str) { - if (str == null) { - throw new IllegalArgumentException("null string"); - } - // Ensure that the provided string is UTF_8 encoded. - CharsetEncoder encoder = StandardCharsets.UTF_8.newEncoder(); - try { - ByteBuffer encoded = encoder.encode(CharBuffer.wrap(str)); - byte[] byteArray = new byte[encoded.remaining()]; - encoded.get(byteArray); - return byteArrayToArrayList(byteArray); - } catch (CharacterCodingException cce) { - throw new IllegalArgumentException("cannot be utf-8 encoded", cce); - } - } - - /** - * Convert from an array of primitive bytes to an array list of Byte. - */ - public static ArrayList byteArrayToArrayList(byte[] bytes) { - ArrayList byteList = new ArrayList<>(); - for (Byte b : bytes) { - byteList.add(b); - } - return byteList; - } - - /** - * Converts a hex string to byte array. - * - * @param hexStr String to be converted. - * @throws IllegalArgumentException for null string. - */ - public static byte[] hexStringToByteArray(String hexStr) { - if (hexStr == null) { - throw new IllegalArgumentException("null hex string"); - } - return HexEncoding.decode(hexStr.toCharArray(), false); - } - } -} diff --git a/wifi/tests/src/android/net/wifi/wificond/PnoSettingsTest.java b/wifi/tests/src/android/net/wifi/wificond/PnoSettingsTest.java index 775acc70d134..9439c796e1a5 100644 --- a/wifi/tests/src/android/net/wifi/wificond/PnoSettingsTest.java +++ b/wifi/tests/src/android/net/wifi/wificond/PnoSettingsTest.java @@ -30,7 +30,7 @@ import java.util.Arrays; import java.util.HashMap; /** - * Unit tests for {@link android.net.wifi.wificond.PnoSettingsResult}. + * Unit tests for {@link android.net.wifi.wificond.PnoSettings}. */ @SmallTest public class PnoSettingsTest { @@ -52,14 +52,14 @@ public class PnoSettingsTest { @Before public void setUp() { mPnoNetwork1 = new PnoNetwork(); - mPnoNetwork1.ssid = TEST_SSID_1; - mPnoNetwork1.isHidden = true; - mPnoNetwork1.frequencies = TEST_FREQUENCIES_1; + mPnoNetwork1.setSsid(TEST_SSID_1); + mPnoNetwork1.setHidden(true); + mPnoNetwork1.setFrequenciesMhz(TEST_FREQUENCIES_1); mPnoNetwork2 = new PnoNetwork(); - mPnoNetwork2.ssid = TEST_SSID_2; - mPnoNetwork2.isHidden = false; - mPnoNetwork2.frequencies = TEST_FREQUENCIES_2; + mPnoNetwork2.setSsid(TEST_SSID_2); + mPnoNetwork2.setHidden(false); + mPnoNetwork2.setFrequenciesMhz(TEST_FREQUENCIES_2); } /** @@ -69,10 +69,10 @@ public class PnoSettingsTest { @Test public void canSerializeAndDeserialize() { PnoSettings pnoSettings = new PnoSettings(); - pnoSettings.intervalMs = TEST_INTERVAL_MS; - pnoSettings.min2gRssi = TEST_MIN_2G_RSSI; - pnoSettings.min5gRssi = TEST_MIN_5G_RSSI; - pnoSettings.pnoNetworks = new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2)); + pnoSettings.setIntervalMillis(TEST_INTERVAL_MS); + pnoSettings.setMin2gRssiDbm(TEST_MIN_2G_RSSI); + pnoSettings.setMin5gRssiDbm(TEST_MIN_5G_RSSI); + pnoSettings.setPnoNetworks(new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2))); Parcel parcel = Parcel.obtain(); pnoSettings.writeToParcel(parcel, 0); @@ -90,16 +90,16 @@ public class PnoSettingsTest { @Test public void testAsHashMapKey() { PnoSettings pnoSettings1 = new PnoSettings(); - pnoSettings1.intervalMs = TEST_INTERVAL_MS; - pnoSettings1.min2gRssi = TEST_MIN_2G_RSSI; - pnoSettings1.min5gRssi = TEST_MIN_5G_RSSI; - pnoSettings1.pnoNetworks = new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2)); + pnoSettings1.setIntervalMillis(TEST_INTERVAL_MS); + pnoSettings1.setMin2gRssiDbm(TEST_MIN_2G_RSSI); + pnoSettings1.setMin5gRssiDbm(TEST_MIN_5G_RSSI); + pnoSettings1.setPnoNetworks(new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2))); PnoSettings pnoSettings2 = new PnoSettings(); - pnoSettings2.intervalMs = TEST_INTERVAL_MS; - pnoSettings2.min2gRssi = TEST_MIN_2G_RSSI; - pnoSettings2.min5gRssi = TEST_MIN_5G_RSSI; - pnoSettings2.pnoNetworks = new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2)); + pnoSettings2.setIntervalMillis(TEST_INTERVAL_MS); + pnoSettings2.setMin2gRssiDbm(TEST_MIN_2G_RSSI); + pnoSettings2.setMin5gRssiDbm(TEST_MIN_5G_RSSI); + pnoSettings2.setPnoNetworks(new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2))); assertEquals(pnoSettings1, pnoSettings2); assertEquals(pnoSettings1.hashCode(), pnoSettings2.hashCode()); diff --git a/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java b/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java new file mode 100644 index 000000000000..68e53362100d --- /dev/null +++ b/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java @@ -0,0 +1,1247 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.wificond; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Matchers.argThat; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyLong; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +import android.app.AlarmManager; +import android.app.test.TestAlarmManager; +import android.content.Context; +import android.net.wifi.IApInterface; +import android.net.wifi.IApInterfaceEventCallback; +import android.net.wifi.IClientInterface; +import android.net.wifi.IPnoScanEvent; +import android.net.wifi.IScanEvent; +import android.net.wifi.ISendMgmtFrameEvent; +import android.net.wifi.IWifiScannerImpl; +import android.net.wifi.IWificond; +import android.net.wifi.SoftApInfo; +import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiScanner; +import android.net.wifi.util.HexEncoding; +import android.os.Handler; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.test.TestLooper; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.AdditionalMatchers; +import org.mockito.ArgumentCaptor; +import org.mockito.ArgumentMatcher; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.CharacterCodingException; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Unit tests for {@link android.net.wifi.WifiCondManager}. + */ +@SmallTest +public class WifiCondManagerTest { + @Mock + private IWificond mWificond; + @Mock + private IBinder mWifiCondBinder; + @Mock + private IClientInterface mClientInterface; + @Mock + private IWifiScannerImpl mWifiScannerImpl; + @Mock + private IApInterface mApInterface; + @Mock + private WifiCondManager.SoftApCallback mSoftApListener; + @Mock + private WifiCondManager.SendMgmtFrameCallback mSendMgmtFrameCallback; + @Mock + private WifiCondManager.ScanEventCallback mNormalScanCallback; + @Mock + private WifiCondManager.ScanEventCallback mPnoScanCallback; + @Mock + private WifiCondManager.PnoScanRequestCallback mPnoScanRequestCallback; + @Mock + private Context mContext; + private TestLooper mLooper; + private TestAlarmManager mTestAlarmManager; + private AlarmManager mAlarmManager; + private WifiCondManager mWificondControl; + private static final String TEST_INTERFACE_NAME = "test_wlan_if"; + private static final String TEST_INTERFACE_NAME1 = "test_wlan_if1"; + private static final String TEST_INVALID_INTERFACE_NAME = "asdf"; + private static final byte[] TEST_SSID = + new byte[]{'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'}; + private static final byte[] TEST_PSK = + new byte[]{'T', 'e', 's', 't'}; + + private static final Set SCAN_FREQ_SET = + new HashSet() {{ + add(2410); + add(2450); + add(5050); + add(5200); + }}; + private static final String TEST_QUOTED_SSID_1 = "\"testSsid1\""; + private static final String TEST_QUOTED_SSID_2 = "\"testSsid2\""; + private static final int[] TEST_FREQUENCIES_1 = {}; + private static final int[] TEST_FREQUENCIES_2 = {2500, 5124}; + private static final byte[] TEST_RAW_MAC_BYTES = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05}; + + private static final List SCAN_HIDDEN_NETWORK_SSID_LIST = + new ArrayList() {{ + add(LocalNativeUtil.byteArrayFromArrayList( + LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_1))); + add(LocalNativeUtil.byteArrayFromArrayList( + LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_2))); + }}; + + private static final PnoSettings TEST_PNO_SETTINGS = new PnoSettings(); + static { + TEST_PNO_SETTINGS.setIntervalMillis(6000); + List initPnoNetworks = new ArrayList<>(); + PnoNetwork network = new PnoNetwork(); + network.setSsid(LocalNativeUtil.byteArrayFromArrayList( + LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_1))); + network.setHidden(true); + network.setFrequenciesMhz(TEST_FREQUENCIES_1); + initPnoNetworks.add(network); + network.setSsid(LocalNativeUtil.byteArrayFromArrayList( + LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_2))); + network.setHidden(false); + network.setFrequenciesMhz(TEST_FREQUENCIES_2); + initPnoNetworks.add(network); + TEST_PNO_SETTINGS.setPnoNetworks(initPnoNetworks); + } + + private static final int TEST_MCS_RATE = 5; + private static final int TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS = 100; + private static final byte[] TEST_PROBE_FRAME = { + 0x40, 0x00, 0x3c, 0x00, (byte) 0xa8, (byte) 0xbd, 0x27, 0x5b, + 0x33, 0x72, (byte) 0xf4, (byte) 0xf5, (byte) 0xe8, 0x51, (byte) 0x9e, 0x09, + (byte) 0xa8, (byte) 0xbd, 0x27, 0x5b, 0x33, 0x72, (byte) 0xb0, 0x66, + 0x00, 0x00 + }; + + @Before + public void setUp() throws Exception { + // Setup mocks for successful WificondControl operation. Failure case mocks should be + // created in specific tests + MockitoAnnotations.initMocks(this); + + mTestAlarmManager = new TestAlarmManager(); + mAlarmManager = mTestAlarmManager.getAlarmManager(); + when(mContext.getSystemServiceName(AlarmManager.class)).thenReturn(Context.ALARM_SERVICE); + when(mContext.getSystemService(AlarmManager.class)).thenReturn(mAlarmManager); + + mLooper = new TestLooper(); + when(mContext.getMainLooper()).thenReturn(mLooper.getLooper()); + + when(mWificond.asBinder()).thenReturn(mWifiCondBinder); + when(mClientInterface.getWifiScannerImpl()).thenReturn(mWifiScannerImpl); + when(mWificond.createClientInterface(any())).thenReturn(mClientInterface); + when(mWificond.createApInterface(any())).thenReturn(mApInterface); + when(mWificond.tearDownClientInterface(any())).thenReturn(true); + when(mWificond.tearDownApInterface(any())).thenReturn(true); + when(mClientInterface.getWifiScannerImpl()).thenReturn(mWifiScannerImpl); + when(mClientInterface.getInterfaceName()).thenReturn(TEST_INTERFACE_NAME); + mWificondControl = new WifiCondManager(mContext, mWificond); + assertEquals(true, + mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, Runnable::run, + mNormalScanCallback, mPnoScanCallback)); + } + + /** + * Verifies that setupInterfaceForClientMode(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testSetupInterfaceForClientMode() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + verify(mWificond).createClientInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that setupInterfaceForClientMode(TEST_INTERFACE_NAME) calls subscribeScanEvents(). + */ + @Test + public void testSetupInterfaceForClientModeCallsScanEventSubscripiton() throws Exception { + verify(mWifiScannerImpl).subscribeScanEvents(any(IScanEvent.class)); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownClientInterface() throws Exception { + when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(true); + + assertTrue(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); + verify(mWifiScannerImpl).unsubscribeScanEvents(); + verify(mWifiScannerImpl).unsubscribePnoScanEvents(); + verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownClientInterfaceOnInvalidIface() throws Exception { + when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME1)).thenReturn(true); + + assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME1)); + verify(mWifiScannerImpl, never()).unsubscribeScanEvents(); + verify(mWifiScannerImpl, never()).unsubscribePnoScanEvents(); + verify(mWificond, never()).tearDownClientInterface(any()); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownClientInterfaceFailDueToExceptionScannerUnsubscribe() throws Exception { + when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(true); + doThrow(new RemoteException()).when(mWifiScannerImpl).unsubscribeScanEvents(); + + assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); + verify(mWifiScannerImpl).unsubscribeScanEvents(); + verify(mWifiScannerImpl, never()).unsubscribePnoScanEvents(); + verify(mWificond, never()).tearDownClientInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownClientInterfaceErrorWhenWificondFailed() throws Exception { + when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(false); + + assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); + verify(mWifiScannerImpl).unsubscribeScanEvents(); + verify(mWifiScannerImpl).unsubscribePnoScanEvents(); + verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that the client handles are cleared after teardown. + */ + @Test + public void testTeardownClientInterfaceClearsHandles() throws Exception { + testTeardownClientInterface(); + + assertNull(mWificondControl.signalPoll(TEST_INTERFACE_NAME)); + verify(mClientInterface, never()).signalPoll(); + + assertFalse(mWificondControl.startScan( + TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_LATENCY, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); + verify(mWifiScannerImpl, never()).scan(any()); + } + + /** + * Verifies that setupInterfaceForSoftApMode(TEST_INTERFACE_NAME) calls wificond. + */ + @Test + public void testSetupInterfaceForSoftApMode() throws Exception { + when(mWificond.createApInterface(TEST_INTERFACE_NAME)).thenReturn(mApInterface); + + assertEquals(true, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME)); + verify(mWificond).createApInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that setupInterfaceForSoftAp() returns null when wificond is not started. + */ + @Test + public void testSetupInterfaceForSoftApModeErrorWhenWificondIsNotStarted() throws Exception { + // Invoke wificond death handler to clear the handle. + mWificondControl.binderDied(); + mLooper.dispatchAll(); + + assertEquals(false, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME)); + } + + /** + * Verifies that setupInterfaceForSoftApMode(TEST_INTERFACE_NAME) returns null when wificond + * failed to setup AP interface. + */ + @Test + public void testSetupInterfaceForSoftApModeErrorWhenWificondFailedToSetupInterface() + throws Exception { + when(mWificond.createApInterface(TEST_INTERFACE_NAME)).thenReturn(null); + + assertEquals(false, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME)); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownSoftApInterface() throws Exception { + testSetupInterfaceForSoftApMode(); + when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME)).thenReturn(true); + + assertTrue(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME)); + verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that tearDownSoftapInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownSoftApInterfaceOnInvalidIface() throws Exception { + testSetupInterfaceForSoftApMode(); + when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME1)).thenReturn(true); + + assertFalse(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME1)); + verify(mWificond, never()).tearDownApInterface(any()); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownSoftApInterfaceErrorWhenWificondFailed() throws Exception { + testSetupInterfaceForSoftApMode(); + when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME)).thenReturn(false); + + assertFalse(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME)); + verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that the SoftAp handles are cleared after teardown. + */ + @Test + public void testTeardownSoftApInterfaceClearsHandles() throws Exception { + testTeardownSoftApInterface(); + + assertFalse(mWificondControl.registerApCallback( + TEST_INTERFACE_NAME, Runnable::run, mSoftApListener)); + verify(mApInterface, never()).registerCallback(any()); + } + + /** + * Verifies that we can setup concurrent interfaces. + */ + @Test + public void testSetupMultipleInterfaces() throws Exception { + when(mWificond.createApInterface(TEST_INTERFACE_NAME1)).thenReturn(mApInterface); + + assertEquals(true, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME1)); + + verify(mWificond).createClientInterface(TEST_INTERFACE_NAME); + verify(mWificond).createApInterface(TEST_INTERFACE_NAME1); + } + + /** + * Verifies that we can setup concurrent interfaces. + */ + @Test + public void testTeardownMultipleInterfaces() throws Exception { + testSetupMultipleInterfaces(); + assertTrue(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); + assertTrue(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME1)); + + verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME); + verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME1); + } + + /** + * Verifies that tearDownInterfaces() calls wificond. + */ + @Test + public void testTearDownInterfaces() throws Exception { + assertTrue(mWificondControl.tearDownInterfaces()); + verify(mWificond).tearDownInterfaces(); + } + + /** + * Verifies that tearDownInterfaces() calls unsubscribeScanEvents() when there was + * a configured client interface. + */ + @Test + public void testTearDownInterfacesRemovesScanEventSubscription() throws Exception { + assertTrue(mWificondControl.tearDownInterfaces()); + verify(mWifiScannerImpl).unsubscribeScanEvents(); + } + + + /** + * Verifies that tearDownInterfaces() returns false when wificond is not started. + */ + @Test + public void testTearDownInterfacesErrorWhenWificondIsNotStarterd() throws Exception { + // Invoke wificond death handler to clear the handle. + mWificondControl.binderDied(); + mLooper.dispatchAll(); + assertFalse(mWificondControl.tearDownInterfaces()); + } + + /** + * Verifies that signalPoll() calls wificond. + */ + @Test + public void testSignalPoll() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + + mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, Runnable::run, + mNormalScanCallback, mPnoScanCallback); + mWificondControl.signalPoll(TEST_INTERFACE_NAME); + verify(mClientInterface).signalPoll(); + } + + /** + * Verifies that signalPoll() returns null when there is no configured client interface. + */ + @Test + public void testSignalPollErrorWhenNoClientInterfaceConfigured() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + + // Configure client interface. + assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, + Runnable::run, mNormalScanCallback, mPnoScanCallback)); + + // Tear down interfaces. + assertTrue(mWificondControl.tearDownInterfaces()); + + // Signal poll should fail. + assertEquals(null, mWificondControl.signalPoll(TEST_INTERFACE_NAME)); + } + + /** + * Verifies that getTxPacketCounters() calls wificond. + */ + @Test + public void testGetTxPacketCounters() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + + mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, Runnable::run, + mNormalScanCallback, mPnoScanCallback); + mWificondControl.getTxPacketCounters(TEST_INTERFACE_NAME); + verify(mClientInterface).getPacketCounters(); + } + + /** + * Verifies that getTxPacketCounters() returns null when there is no configured client + * interface. + */ + @Test + public void testGetTxPacketCountersErrorWhenNoClientInterfaceConfigured() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + + // Configure client interface. + assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, + Runnable::run, mNormalScanCallback, mPnoScanCallback)); + + // Tear down interfaces. + assertTrue(mWificondControl.tearDownInterfaces()); + + // Signal poll should fail. + assertEquals(null, mWificondControl.getTxPacketCounters(TEST_INTERFACE_NAME)); + } + + /** + * Verifies that getScanResults() returns null when there is no configured client + * interface. + */ + @Test + public void testGetScanResultsErrorWhenNoClientInterfaceConfigured() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + + // Configure client interface. + assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, + Runnable::run, mNormalScanCallback, mPnoScanCallback)); + + // Tear down interfaces. + assertTrue(mWificondControl.tearDownInterfaces()); + + // getScanResults should fail. + assertEquals(0, + mWificondControl.getScanResults(TEST_INTERFACE_NAME, + WifiCondManager.SCAN_TYPE_SINGLE_SCAN).size()); + } + + /** + * Verifies that Scan() can convert input parameters to SingleScanSettings correctly. + */ + @Test + public void testScan() throws Exception { + when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true); + assertTrue(mWificondControl.startScan( + TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_POWER, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); + verify(mWifiScannerImpl).scan(argThat(new ScanMatcher( + IWifiScannerImpl.SCAN_TYPE_LOW_POWER, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST))); + } + + /** + * Verifies that Scan() removes duplicates hiddenSsids passed in from input. + */ + @Test + public void testScanWithDuplicateHiddenSsids() throws Exception { + when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true); + // Create a list of hiddenSsid that has a duplicate element + List hiddenSsidWithDup = new ArrayList<>(SCAN_HIDDEN_NETWORK_SSID_LIST); + hiddenSsidWithDup.add(SCAN_HIDDEN_NETWORK_SSID_LIST.get(0)); + assertEquals(hiddenSsidWithDup.get(0), + hiddenSsidWithDup.get(hiddenSsidWithDup.size() - 1)); + // Pass the List with duplicate elements into scan() + assertTrue(mWificondControl.startScan( + TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_POWER, + SCAN_FREQ_SET, hiddenSsidWithDup)); + // But the argument passed down should have the duplicate removed. + verify(mWifiScannerImpl).scan(argThat(new ScanMatcher( + IWifiScannerImpl.SCAN_TYPE_LOW_POWER, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST))); + } + + /** + * Verifies that Scan() can handle null input parameters correctly. + */ + @Test + public void testScanNullParameters() throws Exception { + when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true); + assertTrue(mWificondControl.startScan( + TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_HIGH_ACCURACY, null, null)); + verify(mWifiScannerImpl).scan(argThat(new ScanMatcher( + IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY, null, null))); + } + + /** + * Verifies that Scan() can handle wificond scan failure. + */ + @Test + public void testScanFailure() throws Exception { + when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(false); + assertFalse(mWificondControl.startScan( + TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_LATENCY, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); + verify(mWifiScannerImpl).scan(any(SingleScanSettings.class)); + } + + /** + * Verifies that Scan() can handle invalid type. + */ + @Test + public void testScanFailureDueToInvalidType() throws Exception { + assertFalse(mWificondControl.startScan( + TEST_INTERFACE_NAME, 100, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); + verify(mWifiScannerImpl, never()).scan(any(SingleScanSettings.class)); + } + + /** + * Verifies that startPnoScan() can convert input parameters to PnoSettings correctly. + */ + @Test + public void testStartPnoScan() throws Exception { + when(mWifiScannerImpl.startPnoScan(any(PnoSettings.class))).thenReturn(true); + assertTrue( + mWificondControl.startPnoScan(TEST_INTERFACE_NAME, TEST_PNO_SETTINGS, Runnable::run, + mPnoScanRequestCallback)); + verify(mWifiScannerImpl).startPnoScan(eq(TEST_PNO_SETTINGS)); + verify(mPnoScanRequestCallback).onPnoRequestSucceeded(); + } + + /** + * Verifies that stopPnoScan() calls underlying wificond. + */ + @Test + public void testStopPnoScan() throws Exception { + when(mWifiScannerImpl.stopPnoScan()).thenReturn(true); + assertTrue(mWificondControl.stopPnoScan(TEST_INTERFACE_NAME)); + verify(mWifiScannerImpl).stopPnoScan(); + } + + /** + * Verifies that stopPnoScan() can handle wificond failure. + */ + @Test + public void testStopPnoScanFailure() throws Exception { + + when(mWifiScannerImpl.stopPnoScan()).thenReturn(false); + assertFalse(mWificondControl.stopPnoScan(TEST_INTERFACE_NAME)); + verify(mWifiScannerImpl).stopPnoScan(); + } + + /** + * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon scan + * result event. + */ + @Test + public void testScanResultEvent() throws Exception { + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(IScanEvent.class); + verify(mWifiScannerImpl).subscribeScanEvents(messageCaptor.capture()); + IScanEvent scanEvent = messageCaptor.getValue(); + assertNotNull(scanEvent); + scanEvent.OnScanResultReady(); + + verify(mNormalScanCallback).onScanResultReady(); + } + + /** + * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon scan + * failed event. + */ + @Test + public void testScanFailedEvent() throws Exception { + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(IScanEvent.class); + verify(mWifiScannerImpl).subscribeScanEvents(messageCaptor.capture()); + IScanEvent scanEvent = messageCaptor.getValue(); + assertNotNull(scanEvent); + scanEvent.OnScanFailed(); + + verify(mNormalScanCallback).onScanFailed(); + } + + /** + * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon pno scan + * result event. + */ + @Test + public void testPnoScanResultEvent() throws Exception { + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(IPnoScanEvent.class); + verify(mWifiScannerImpl).subscribePnoScanEvents(messageCaptor.capture()); + IPnoScanEvent pnoScanEvent = messageCaptor.getValue(); + assertNotNull(pnoScanEvent); + pnoScanEvent.OnPnoNetworkFound(); + verify(mPnoScanCallback).onScanResultReady(); + } + + /** + * Verifies that WificondControl can invoke WifiMetrics pno scan count methods upon pno event. + */ + @Test + public void testPnoScanEventsForMetrics() throws Exception { + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(IPnoScanEvent.class); + verify(mWifiScannerImpl).subscribePnoScanEvents(messageCaptor.capture()); + IPnoScanEvent pnoScanEvent = messageCaptor.getValue(); + assertNotNull(pnoScanEvent); + + pnoScanEvent.OnPnoNetworkFound(); + verify(mPnoScanCallback).onScanResultReady(); + + pnoScanEvent.OnPnoScanFailed(); + verify(mPnoScanCallback).onScanFailed(); + } + + /** + * Verifies that startPnoScan() can invoke WifiMetrics pno scan count methods correctly. + */ + @Test + public void testStartPnoScanForMetrics() throws Exception { + when(mWifiScannerImpl.startPnoScan(any(PnoSettings.class))).thenReturn(false); + + assertFalse( + mWificondControl.startPnoScan(TEST_INTERFACE_NAME, TEST_PNO_SETTINGS, Runnable::run, + mPnoScanRequestCallback)); + verify(mPnoScanRequestCallback).onPnoRequestFailed(); + } + + /** + * Verifies that abortScan() calls underlying wificond. + */ + @Test + public void testAbortScan() throws Exception { + mWificondControl.abortScan(TEST_INTERFACE_NAME); + verify(mWifiScannerImpl).abortScan(); + } + + /** + * Ensures that the Ap interface callbacks are forwarded to the + * SoftApListener used for starting soft AP. + */ + @Test + public void testSoftApListenerInvocation() throws Exception { + testSetupInterfaceForSoftApMode(); + + WifiConfiguration config = new WifiConfiguration(); + config.SSID = new String(TEST_SSID, StandardCharsets.UTF_8); + + when(mApInterface.registerCallback(any())).thenReturn(true); + + final ArgumentCaptor apInterfaceCallbackCaptor = + ArgumentCaptor.forClass(IApInterfaceEventCallback.class); + + assertTrue(mWificondControl.registerApCallback( + TEST_INTERFACE_NAME, Runnable::run, mSoftApListener)); + verify(mApInterface).registerCallback(apInterfaceCallbackCaptor.capture()); + + final NativeWifiClient testClient = new NativeWifiClient(TEST_RAW_MAC_BYTES); + apInterfaceCallbackCaptor.getValue().onConnectedClientsChanged(testClient, true); + verify(mSoftApListener).onConnectedClientsChanged(eq(testClient), eq(true)); + + int channelFrequency = 2437; + int channelBandwidth = IApInterfaceEventCallback.BANDWIDTH_20; + apInterfaceCallbackCaptor.getValue().onSoftApChannelSwitched(channelFrequency, + channelBandwidth); + verify(mSoftApListener).onSoftApChannelSwitched(eq(channelFrequency), + eq(SoftApInfo.CHANNEL_WIDTH_20MHZ)); + } + + /** + * Verifies registration and invocation of wificond death handler. + */ + @Test + public void testRegisterDeathHandler() throws Exception { + Runnable deathHandler = mock(Runnable.class); + assertTrue(mWificondControl.initialize(deathHandler)); + verify(mWificond).tearDownInterfaces(); + mWificondControl.binderDied(); + mLooper.dispatchAll(); + verify(deathHandler).run(); + } + + /** + * Verifies handling of wificond death and ensures that all internal state is cleared and + * handlers are invoked. + */ + @Test + public void testDeathHandling() throws Exception { + Runnable deathHandler = mock(Runnable.class); + assertTrue(mWificondControl.initialize(deathHandler)); + + testSetupInterfaceForClientMode(); + + mWificondControl.binderDied(); + mLooper.dispatchAll(); + verify(deathHandler).run(); + + // The handles should be cleared after death. + assertEquals(0, mWificondControl.getChannelsMhzForBand(WifiScanner.WIFI_BAND_5_GHZ).length); + verify(mWificond, never()).getAvailable5gNonDFSChannels(); + } + + /** + * sendMgmtFrame() should fail if a null callback is passed in. + */ + @Test + public void testSendMgmtFrameNullCallback() throws Exception { + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, null); + + verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt()); + } + + /** + * sendMgmtFrame() should fail if a null frame is passed in. + */ + @Test + public void testSendMgmtFrameNullFrame() throws Exception { + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, null, TEST_MCS_RATE, Runnable::run, + mSendMgmtFrameCallback); + + verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt()); + verify(mSendMgmtFrameCallback).onFailure(anyInt()); + } + + /** + * sendMgmtFrame() should fail if an interface name that does not exist is passed in. + */ + @Test + public void testSendMgmtFrameInvalidInterfaceName() throws Exception { + mWificondControl.sendMgmtFrame(TEST_INVALID_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, mSendMgmtFrameCallback); + + verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt()); + verify(mSendMgmtFrameCallback).onFailure(anyInt()); + } + + /** + * sendMgmtFrame() should fail if it is called a second time before the first call completed. + */ + @Test + public void testSendMgmtFrameCalledTwiceBeforeFinished() throws Exception { + WifiCondManager.SendMgmtFrameCallback cb1 = mock( + WifiCondManager.SendMgmtFrameCallback.class); + WifiCondManager.SendMgmtFrameCallback cb2 = mock( + WifiCondManager.SendMgmtFrameCallback.class); + + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, cb1); + verify(cb1, never()).onFailure(anyInt()); + verify(mClientInterface, times(1)) + .SendMgmtFrame(AdditionalMatchers.aryEq(TEST_PROBE_FRAME), + any(), eq(TEST_MCS_RATE)); + + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, cb2); + verify(cb2).onFailure(WifiCondManager.SEND_MGMT_FRAME_ERROR_ALREADY_STARTED); + // verify SendMgmtFrame() still was only called once i.e. not called again + verify(mClientInterface, times(1)) + .SendMgmtFrame(any(), any(), anyInt()); + } + + /** + * Tests that when a RemoteException is triggered on AIDL call, onFailure() is called only once. + */ + @Test + public void testSendMgmtFrameThrowsException() throws Exception { + WifiCondManager.SendMgmtFrameCallback cb = mock( + WifiCondManager.SendMgmtFrameCallback.class); + + final ArgumentCaptor sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + + doThrow(new RemoteException()).when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + + final ArgumentCaptor alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, cb); + mLooper.dispatchAll(); + + verify(cb).onFailure(anyInt()); + verify(mAlarmManager).cancel(eq(alarmListenerCaptor.getValue())); + + sendMgmtFrameEventCaptor.getValue().OnFailure( + WifiCondManager.SEND_MGMT_FRAME_ERROR_UNKNOWN); + mLooper.dispatchAll(); + + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + mLooper.dispatchAll(); + + verifyNoMoreInteractions(cb); + } + + /** + * Tests that the onAck() callback is triggered correctly. + */ + @Test + public void testSendMgmtFrameSuccess() throws Exception { + WifiCondManager.SendMgmtFrameCallback cb = mock( + WifiCondManager.SendMgmtFrameCallback.class); + + final ArgumentCaptor sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + doNothing().when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + final ArgumentCaptor alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, cb); + + sendMgmtFrameEventCaptor.getValue().OnAck(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS); + mLooper.dispatchAll(); + verify(cb).onAck(eq(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS)); + verify(cb, never()).onFailure(anyInt()); + verify(mAlarmManager).cancel(eq(alarmListenerCaptor.getValue())); + + // verify that even if timeout is triggered afterwards, SendMgmtFrameCallback is not + // triggered again + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + mLooper.dispatchAll(); + verify(cb, times(1)).onAck(anyInt()); + verify(cb, never()).onFailure(anyInt()); + } + + /** + * Tests that the onFailure() callback is triggered correctly. + */ + @Test + public void testSendMgmtFrameFailure() throws Exception { + WifiCondManager.SendMgmtFrameCallback cb = mock( + WifiCondManager.SendMgmtFrameCallback.class); + + final ArgumentCaptor sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + doNothing().when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + final ArgumentCaptor alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, cb); + + sendMgmtFrameEventCaptor.getValue().OnFailure( + WifiCondManager.SEND_MGMT_FRAME_ERROR_UNKNOWN); + mLooper.dispatchAll(); + verify(cb, never()).onAck(anyInt()); + verify(cb).onFailure(WifiCondManager.SEND_MGMT_FRAME_ERROR_UNKNOWN); + verify(mAlarmManager).cancel(eq(alarmListenerCaptor.getValue())); + + // verify that even if timeout is triggered afterwards, SendMgmtFrameCallback is not + // triggered again + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + mLooper.dispatchAll(); + verify(cb, never()).onAck(anyInt()); + verify(cb, times(1)).onFailure(anyInt()); + } + + /** + * Tests that the onTimeout() callback is triggered correctly. + */ + @Test + public void testSendMgmtFrameTimeout() throws Exception { + WifiCondManager.SendMgmtFrameCallback cb = mock( + WifiCondManager.SendMgmtFrameCallback.class); + + final ArgumentCaptor sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + doNothing().when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + final ArgumentCaptor alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, cb); + + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + mLooper.dispatchAll(); + verify(cb, never()).onAck(anyInt()); + verify(cb).onFailure(WifiCondManager.SEND_MGMT_FRAME_ERROR_TIMEOUT); + + // verify that even if onAck() callback is triggered after timeout, + // SendMgmtFrameCallback is not triggered again + sendMgmtFrameEventCaptor.getValue().OnAck(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS); + mLooper.dispatchAll(); + verify(cb, never()).onAck(anyInt()); + verify(cb, times(1)).onFailure(anyInt()); + } + + /** + * Tests every possible test outcome followed by every other test outcome to ensure that the + * internal state is reset correctly between calls. + * i.e. (success, success), (success, failure), (success, timeout), + * (failure, failure), (failure, success), (failure, timeout), + * (timeout, timeout), (timeout, success), (timeout, failure) + * + * Also tests that internal state is reset correctly after a transient AIDL RemoteException. + */ + @Test + public void testSendMgmtFrameMixed() throws Exception { + testSendMgmtFrameThrowsException(); + testSendMgmtFrameSuccess(); + testSendMgmtFrameSuccess(); + testSendMgmtFrameFailure(); + testSendMgmtFrameFailure(); + testSendMgmtFrameTimeout(); + testSendMgmtFrameTimeout(); + testSendMgmtFrameSuccess(); + testSendMgmtFrameTimeout(); + testSendMgmtFrameFailure(); + testSendMgmtFrameSuccess(); + } + + /** + * Tests that OnAck() does not perform any non-thread-safe operations on the binder thread. + * + * The sequence of instructions are: + * 1. post onAlarm() onto main thread + * 2. OnAck() + * 3. mLooper.dispatchAll() + * + * The actual order of execution is: + * 1. binder thread portion of OnAck() + * 2. onAlarm() (which purely executes on the main thread) + * 3. main thread portion of OnAck() + * + * If the binder thread portion of OnAck() is not thread-safe, it can possibly mess up + * onAlarm(). Tests that this does not occur. + */ + @Test + public void testSendMgmtFrameTimeoutAckThreadSafe() throws Exception { + final ArgumentCaptor sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + doNothing().when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + final ArgumentCaptor alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, mSendMgmtFrameCallback); + + // AlarmManager should post the onAlarm() callback onto the handler, but since we are + // triggering onAlarm() ourselves during the test, manually post onto handler + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + // OnAck posts to the handler + sendMgmtFrameEventCaptor.getValue().OnAck(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS); + mLooper.dispatchAll(); + verify(mSendMgmtFrameCallback, never()).onAck(anyInt()); + verify(mSendMgmtFrameCallback).onFailure(WifiCondManager.SEND_MGMT_FRAME_ERROR_TIMEOUT); + } + + /** + * See {@link #testSendMgmtFrameTimeoutAckThreadSafe()}. This test replaces OnAck() with + * OnFailure(). + */ + @Test + public void testSendMgmtFrameTimeoutFailureThreadSafe() throws Exception { + final ArgumentCaptor sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + doNothing().when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + final ArgumentCaptor alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, mSendMgmtFrameCallback); + + // AlarmManager should post the onAlarm() callback onto the handler, but since we are + // triggering onAlarm() ourselves during the test, manually post onto handler + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + // OnFailure posts to the handler + sendMgmtFrameEventCaptor.getValue().OnFailure( + WifiCondManager.SEND_MGMT_FRAME_ERROR_UNKNOWN); + mLooper.dispatchAll(); + verify(mSendMgmtFrameCallback).onFailure(WifiCondManager.SEND_MGMT_FRAME_ERROR_TIMEOUT); + } + + // Create a ArgumentMatcher which captures a SingleScanSettings parameter and checks if it + // matches the provided frequency set and ssid set. + private class ScanMatcher implements ArgumentMatcher { + int mExpectedScanType; + private final Set mExpectedFreqs; + private final List mExpectedSsids; + + ScanMatcher(int expectedScanType, Set expectedFreqs, List expectedSsids) { + this.mExpectedScanType = expectedScanType; + this.mExpectedFreqs = expectedFreqs; + this.mExpectedSsids = expectedSsids; + } + + @Override + public boolean matches(SingleScanSettings settings) { + if (settings.scanType != mExpectedScanType) { + return false; + } + ArrayList channelSettings = settings.channelSettings; + ArrayList hiddenNetworks = settings.hiddenNetworks; + if (mExpectedFreqs != null) { + Set freqSet = new HashSet(); + for (ChannelSettings channel : channelSettings) { + freqSet.add(channel.frequency); + } + if (!mExpectedFreqs.equals(freqSet)) { + return false; + } + } else { + if (channelSettings != null && channelSettings.size() > 0) { + return false; + } + } + + if (mExpectedSsids != null) { + List ssidSet = new ArrayList<>(); + for (HiddenNetwork network : hiddenNetworks) { + ssidSet.add(network.ssid); + } + if (!mExpectedSsids.equals(ssidSet)) { + return false; + } + + } else { + if (hiddenNetworks != null && hiddenNetworks.size() > 0) { + return false; + } + } + return true; + } + + @Override + public String toString() { + return "ScanMatcher{mExpectedFreqs=" + mExpectedFreqs + + ", mExpectedSsids=" + mExpectedSsids + '}'; + } + } + + private static class LocalNativeUtil { + private static final int SSID_BYTES_MAX_LEN = 32; + + /** + * Converts an ArrayList of UTF_8 byte values to string. + * The string will either be: + * a) UTF-8 String encapsulated in quotes (if all the bytes are UTF-8 encodeable and non + * null), + * or + * b) Hex string with no delimiters. + * + * @param bytes List of bytes for ssid. + * @throws IllegalArgumentException for null bytes. + */ + public static String bytesToHexOrQuotedString(ArrayList bytes) { + if (bytes == null) { + throw new IllegalArgumentException("null ssid bytes"); + } + byte[] byteArray = byteArrayFromArrayList(bytes); + // Check for 0's in the byte stream in which case we cannot convert this into a string. + if (!bytes.contains(Byte.valueOf((byte) 0))) { + CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder(); + try { + CharBuffer decoded = decoder.decode(ByteBuffer.wrap(byteArray)); + return "\"" + decoded.toString() + "\""; + } catch (CharacterCodingException cce) { + } + } + return hexStringFromByteArray(byteArray); + } + + /** + * Converts an ssid string to an arraylist of UTF_8 byte values. + * These forms are acceptable: + * a) UTF-8 String encapsulated in quotes, or + * b) Hex string with no delimiters. + * + * @param ssidStr String to be converted. + * @throws IllegalArgumentException for null string. + */ + public static ArrayList decodeSsid(String ssidStr) { + ArrayList ssidBytes = hexOrQuotedStringToBytes(ssidStr); + if (ssidBytes.size() > SSID_BYTES_MAX_LEN) { + throw new IllegalArgumentException( + "ssid bytes size out of range: " + ssidBytes.size()); + } + return ssidBytes; + } + + /** + * Convert from an array list of Byte to an array of primitive bytes. + */ + public static byte[] byteArrayFromArrayList(ArrayList bytes) { + byte[] byteArray = new byte[bytes.size()]; + int i = 0; + for (Byte b : bytes) { + byteArray[i++] = b; + } + return byteArray; + } + + /** + * Converts a byte array to hex string. + * + * @param bytes List of bytes for ssid. + * @throws IllegalArgumentException for null bytes. + */ + public static String hexStringFromByteArray(byte[] bytes) { + if (bytes == null) { + throw new IllegalArgumentException("null hex bytes"); + } + return new String(HexEncoding.encode(bytes)).toLowerCase(); + } + + /** + * Converts an string to an arraylist of UTF_8 byte values. + * These forms are acceptable: + * a) UTF-8 String encapsulated in quotes, or + * b) Hex string with no delimiters. + * + * @param str String to be converted. + * @throws IllegalArgumentException for null string. + */ + public static ArrayList hexOrQuotedStringToBytes(String str) { + if (str == null) { + throw new IllegalArgumentException("null string"); + } + int length = str.length(); + if ((length > 1) && (str.charAt(0) == '"') && (str.charAt(length - 1) == '"')) { + str = str.substring(1, str.length() - 1); + return stringToByteArrayList(str); + } else { + return byteArrayToArrayList(hexStringToByteArray(str)); + } + } + + /** + * Convert the string to byte array list. + * + * @return the UTF_8 char byte values of str, as an ArrayList. + * @throws IllegalArgumentException if a null or unencodable string is sent. + */ + public static ArrayList stringToByteArrayList(String str) { + if (str == null) { + throw new IllegalArgumentException("null string"); + } + // Ensure that the provided string is UTF_8 encoded. + CharsetEncoder encoder = StandardCharsets.UTF_8.newEncoder(); + try { + ByteBuffer encoded = encoder.encode(CharBuffer.wrap(str)); + byte[] byteArray = new byte[encoded.remaining()]; + encoded.get(byteArray); + return byteArrayToArrayList(byteArray); + } catch (CharacterCodingException cce) { + throw new IllegalArgumentException("cannot be utf-8 encoded", cce); + } + } + + /** + * Convert from an array of primitive bytes to an array list of Byte. + */ + public static ArrayList byteArrayToArrayList(byte[] bytes) { + ArrayList byteList = new ArrayList<>(); + for (Byte b : bytes) { + byteList.add(b); + } + return byteList; + } + + /** + * Converts a hex string to byte array. + * + * @param hexStr String to be converted. + * @throws IllegalArgumentException for null string. + */ + public static byte[] hexStringToByteArray(String hexStr) { + if (hexStr == null) { + throw new IllegalArgumentException("null hex string"); + } + return HexEncoding.decode(hexStr.toCharArray(), false); + } + } +} -- cgit v1.2.3 From e722cbd451211ef53496f8b245e1ec934617ab99 Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Wed, 4 Dec 2019 15:50:07 -0800 Subject: [DPP R2] Added support for DPP R2 events Added support for DPP R2 events that provide additional details about the onboarding process of a remote enrollee. Specifically, DPP R2 configurator waits for response from the enrollee, which reports back the SSID, tried channels and band support in case it cannot find the AP. When it reports success, then it means that it is acutally connected. Bug: 139381558 Test: Manual tests with DPP R1 and R2 enrollees Test: atest DppManagerTest Test: atest WifiManagerTest Test: atest EasyConnectStatusCallbackTest Test: act.py -c ../WifiDppConfig.json -tc WifiDppTest Change-Id: I55a8b1e25737e90e304f1933d09ffcd6bcae6ef9 --- .../net/wifi/EasyConnectStatusCallback.java | 102 +++++++++++++++++---- wifi/java/android/net/wifi/IDppCallback.aidl | 2 +- wifi/java/android/net/wifi/WifiManager.java | 86 ++++++++++++++++- .../net/wifi/EasyConnectStatusCallbackTest.java | 84 +++++++++++++++++ .../src/android/net/wifi/WifiManagerTest.java | 60 ++++++++++++ 5 files changed, 312 insertions(+), 22 deletions(-) create mode 100644 wifi/tests/src/android/net/wifi/EasyConnectStatusCallbackTest.java (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/EasyConnectStatusCallback.java b/wifi/java/android/net/wifi/EasyConnectStatusCallback.java index b8c82fd9e0ae..4fa93ee271e9 100644 --- a/wifi/java/android/net/wifi/EasyConnectStatusCallback.java +++ b/wifi/java/android/net/wifi/EasyConnectStatusCallback.java @@ -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 { @@ -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 { @@ -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 = { @@ -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 { @@ -138,9 +181,8 @@ 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, - * EasyConnectStatusCallback)}. + * {@link WifiManager#startEasyConnectAsEnrolleeInitiator(String, Executor, + * EasyConnectStatusCallback)} . * * @param newNetworkId New Wi-Fi configuration with a network ID received from the configurator */ @@ -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. */ @@ -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 channelListArray, @NonNull int[] operatingClassArray) { + onFailure(code); + } /** * Called when Easy Connect events that indicate progress take place. Can be used by UI elements diff --git a/wifi/java/android/net/wifi/IDppCallback.aidl b/wifi/java/android/net/wifi/IDppCallback.aidl index c452c7664c12..d7a958a5b4b1 100644 --- a/wifi/java/android/net/wifi/IDppCallback.aidl +++ b/wifi/java/android/net/wifi/IDppCallback.aidl @@ -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 diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index b98d64dc78f1..5ab05834cd78 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -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; @@ -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; /** @@ -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); }); @@ -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 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); }); @@ -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 parseDppChannelList(String channelList) { + SparseArray channelListArray = new SparseArray<>(); + + if (TextUtils.isEmpty(channelList)) { + return channelListArray; + } + StringTokenizer str = new StringTokenizer(channelList, ","); + String classStr = null; + List 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<>(); + } + } } diff --git a/wifi/tests/src/android/net/wifi/EasyConnectStatusCallbackTest.java b/wifi/tests/src/android/net/wifi/EasyConnectStatusCallbackTest.java new file mode 100644 index 000000000000..b10141434b0b --- /dev/null +++ b/wifi/tests/src/android/net/wifi/EasyConnectStatusCallbackTest.java @@ -0,0 +1,84 @@ +/* + * 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 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); + } +} diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 4a46744a2d32..821661196f4f 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -89,6 +89,7 @@ import android.os.IBinder; import android.os.RemoteException; import android.os.connectivity.WifiActivityEnergyInfo; import android.os.test.TestLooper; +import android.util.SparseArray; import androidx.test.filters.SmallTest; @@ -2089,4 +2090,63 @@ public class WifiManagerTest { .thenReturn(new Long(~WifiManager.WIFI_FEATURE_WAPI)); assertFalse(mWifiManager.isWapiSupported()); } + + /* + * Test that DPP channel list is parsed correctly + */ + @Test + public void testparseDppChannelList() throws Exception { + String channelList = "81/1,2,3,4,5,6,7,8,9,10,11,115/36,40,44,48"; + SparseArray expectedResult = new SparseArray<>(); + expectedResult.append(81, new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}); + expectedResult.append(115, new int[]{36, 40, 44, 48}); + + SparseArray result = WifiManager.parseDppChannelList(channelList); + assertEquals(expectedResult.size(), result.size()); + + int index = 0; + int key; + + // Compare the two primitive int arrays + do { + try { + key = result.keyAt(index); + } catch (java.lang.ArrayIndexOutOfBoundsException e) { + break; + } + int[] expected = expectedResult.get(key); + int[] output = result.get(key); + assertEquals(expected.length, output.length); + for (int i = 0; i < output.length; i++) { + assertEquals(expected[i], output[i]); + } + index++; + } while (true); + } + + /* + * Test that DPP channel list parser gracefully fails for invalid input + */ + @Test + public void testparseDppChannelListWithInvalidFormats() throws Exception { + String channelList = "1,2,3,4,5,6,7,8,9,10,11,36,40,44,48"; + SparseArray result = WifiManager.parseDppChannelList(channelList); + assertEquals(result.size(), 0); + + channelList = "ajgalskgjalskjg3-09683dh"; + result = WifiManager.parseDppChannelList(channelList); + assertEquals(result.size(), 0); + + channelList = "13/abc,46////"; + result = WifiManager.parseDppChannelList(channelList); + assertEquals(result.size(), 0); + + channelList = "11/4,5,13/"; + result = WifiManager.parseDppChannelList(channelList); + assertEquals(result.size(), 0); + + channelList = "/24,6"; + result = WifiManager.parseDppChannelList(channelList); + assertEquals(result.size(), 0); + } } -- cgit v1.2.3 From 98d8f071a405a169fd77016eb8d3bf7053fcbf3d Mon Sep 17 00:00:00 2001 From: Michael Plass Date: Wed, 18 Dec 2019 16:02:09 -0800 Subject: Remove unused plumbing for connected PNO These are not actually used. Bug: 142081306 Test: atest FrameworksWifiWifiTests Change-Id: I51b32b446c3df04954355784c895487f0a96ee9b --- wifi/java/android/net/wifi/WifiScanner.java | 27 ---------------------- .../src/android/net/wifi/WifiScannerTest.java | 20 ---------------- 2 files changed, 47 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index 760497b727cd..da4e9b8268ac 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -742,21 +742,6 @@ public class WifiScanner { public int min24GHzRssi; /** Minimum 6GHz RSSI for a BSSID to be considered */ public int min6GHzRssi; - /** Maximum score that a network can have before bonuses */ - public int initialScoreMax; - /** - * Only report when there is a network's score this much higher - * than the current connection. - */ - public int currentConnectionBonus; - /** score bonus for all networks with the same network flag */ - public int sameNetworkBonus; - /** score bonus for networks that are not open */ - public int secureBonus; - /** 5GHz RSSI score bonus (applied to all 5GHz networks) */ - public int band5GHzBonus; - /** 6GHz RSSI score bonus (applied to all 5GHz networks) */ - public int band6GHzBonus; /** Pno Network filter list */ public PnoNetwork[] networkList; @@ -771,12 +756,6 @@ public class WifiScanner { dest.writeInt(min5GHzRssi); dest.writeInt(min24GHzRssi); dest.writeInt(min6GHzRssi); - dest.writeInt(initialScoreMax); - dest.writeInt(currentConnectionBonus); - dest.writeInt(sameNetworkBonus); - dest.writeInt(secureBonus); - dest.writeInt(band5GHzBonus); - dest.writeInt(band6GHzBonus); if (networkList != null) { dest.writeInt(networkList.length); for (int i = 0; i < networkList.length; i++) { @@ -799,12 +778,6 @@ public class WifiScanner { settings.min5GHzRssi = in.readInt(); settings.min24GHzRssi = in.readInt(); settings.min6GHzRssi = in.readInt(); - settings.initialScoreMax = in.readInt(); - settings.currentConnectionBonus = in.readInt(); - settings.sameNetworkBonus = in.readInt(); - settings.secureBonus = in.readInt(); - settings.band5GHzBonus = in.readInt(); - settings.band6GHzBonus = in.readInt(); int numNetworks = in.readInt(); settings.networkList = new PnoNetwork[numNetworks]; for (int i = 0; i < numNetworks; i++) { diff --git a/wifi/tests/src/android/net/wifi/WifiScannerTest.java b/wifi/tests/src/android/net/wifi/WifiScannerTest.java index fa4f711056db..1af0bcbf3f30 100644 --- a/wifi/tests/src/android/net/wifi/WifiScannerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiScannerTest.java @@ -80,12 +80,6 @@ public class WifiScannerTest { private static final int TEST_PNOSETTINGS_MIN_5GHZ_RSSI = -60; private static final int TEST_PNOSETTINGS_MIN_2GHZ_RSSI = -70; private static final int TEST_PNOSETTINGS_MIN_6GHZ_RSSI = -55; - private static final int TEST_PNOSETTINGS_INITIAL_SCORE_MAX = 50; - private static final int TEST_PNOSETTINGS_CURRENT_CONNECTION_BONUS = 10; - private static final int TEST_PNOSETTINGS_SAME_NETWORK_BONUS = 11; - private static final int TEST_PNOSETTINGS_SECURE_BONUS = 12; - private static final int TEST_PNOSETTINGS_BAND_5GHZ_BONUS = 13; - private static final int TEST_PNOSETTINGS_BAND_6GHZ_BONUS = 15; private static final String TEST_SSID_1 = "TEST1"; private static final String TEST_SSID_2 = "TEST2"; private static final int[] TEST_FREQUENCIES_1 = {}; @@ -186,12 +180,6 @@ public class WifiScannerTest { pnoSettings.min5GHzRssi = TEST_PNOSETTINGS_MIN_5GHZ_RSSI; pnoSettings.min24GHzRssi = TEST_PNOSETTINGS_MIN_2GHZ_RSSI; pnoSettings.min6GHzRssi = TEST_PNOSETTINGS_MIN_6GHZ_RSSI; - pnoSettings.initialScoreMax = TEST_PNOSETTINGS_INITIAL_SCORE_MAX; - pnoSettings.currentConnectionBonus = TEST_PNOSETTINGS_CURRENT_CONNECTION_BONUS; - pnoSettings.sameNetworkBonus = TEST_PNOSETTINGS_SAME_NETWORK_BONUS; - pnoSettings.secureBonus = TEST_PNOSETTINGS_SECURE_BONUS; - pnoSettings.band5GHzBonus = TEST_PNOSETTINGS_BAND_5GHZ_BONUS; - pnoSettings.band6GHzBonus = TEST_PNOSETTINGS_BAND_6GHZ_BONUS; Parcel parcel = Parcel.obtain(); pnoSettings.writeToParcel(parcel, 0); @@ -205,14 +193,6 @@ public class WifiScannerTest { assertEquals(TEST_PNOSETTINGS_MIN_5GHZ_RSSI, pnoSettingsDeserialized.min5GHzRssi); assertEquals(TEST_PNOSETTINGS_MIN_2GHZ_RSSI, pnoSettingsDeserialized.min24GHzRssi); assertEquals(TEST_PNOSETTINGS_MIN_6GHZ_RSSI, pnoSettingsDeserialized.min6GHzRssi); - assertEquals(TEST_PNOSETTINGS_INITIAL_SCORE_MAX, pnoSettingsDeserialized.initialScoreMax); - assertEquals(TEST_PNOSETTINGS_CURRENT_CONNECTION_BONUS, - pnoSettingsDeserialized.currentConnectionBonus); - assertEquals(TEST_PNOSETTINGS_SAME_NETWORK_BONUS, - pnoSettingsDeserialized.sameNetworkBonus); - assertEquals(TEST_PNOSETTINGS_SECURE_BONUS, pnoSettingsDeserialized.secureBonus); - assertEquals(TEST_PNOSETTINGS_BAND_5GHZ_BONUS, pnoSettingsDeserialized.band5GHzBonus); - assertEquals(TEST_PNOSETTINGS_BAND_6GHZ_BONUS, pnoSettingsDeserialized.band6GHzBonus); // Test parsing of PnoNetwork assertEquals(pnoSettings.networkList.length, pnoSettingsDeserialized.networkList.length); -- cgit v1.2.3 From 6929c91d3217ab5acec45600cbc302bb8d7889fd Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Fri, 20 Dec 2019 15:52:00 -0800 Subject: [wificond] Move to wificond namespace Move the rest of the code to the wifi.wificond namespace from the wifi namespace. Cleanup since wificond is outside the Wi-Fi module. Non-functional change. Bug: 140062898 Test: atest android.net.wifi Test: atest com.android.server.wifi Test: ./system/connectivity/wificond/runtests.sh Test: (CTS) atest android.net.wifi.cts Change-Id: I64535329edbf96b1f1a0ddc0d85ebe99f9343c76 --- wifi/java/android/net/wifi/wificond/SingleScanSettings.java | 1 - wifi/java/android/net/wifi/wificond/WifiCondManager.java | 8 -------- .../src/android/net/wifi/wificond/SingleScanSettingsTest.java | 1 - wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java | 8 -------- 4 files changed, 18 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/wificond/SingleScanSettings.java b/wifi/java/android/net/wifi/wificond/SingleScanSettings.java index 8065c01a7f89..8c341b8bd916 100644 --- a/wifi/java/android/net/wifi/wificond/SingleScanSettings.java +++ b/wifi/java/android/net/wifi/wificond/SingleScanSettings.java @@ -16,7 +16,6 @@ package android.net.wifi.wificond; -import android.net.wifi.IWifiScannerImpl; import android.os.Parcel; import android.os.Parcelable; import android.util.Log; diff --git a/wifi/java/android/net/wifi/wificond/WifiCondManager.java b/wifi/java/android/net/wifi/wificond/WifiCondManager.java index 94f1212da0a0..283f2dd78abb 100644 --- a/wifi/java/android/net/wifi/wificond/WifiCondManager.java +++ b/wifi/java/android/net/wifi/wificond/WifiCondManager.java @@ -24,14 +24,6 @@ import android.annotation.SystemApi; import android.annotation.SystemService; import android.app.AlarmManager; import android.content.Context; -import android.net.wifi.IApInterface; -import android.net.wifi.IApInterfaceEventCallback; -import android.net.wifi.IClientInterface; -import android.net.wifi.IPnoScanEvent; -import android.net.wifi.IScanEvent; -import android.net.wifi.ISendMgmtFrameEvent; -import android.net.wifi.IWifiScannerImpl; -import android.net.wifi.IWificond; import android.net.wifi.SoftApInfo; import android.net.wifi.WifiAnnotations; import android.net.wifi.WifiScanner; diff --git a/wifi/tests/src/android/net/wifi/wificond/SingleScanSettingsTest.java b/wifi/tests/src/android/net/wifi/wificond/SingleScanSettingsTest.java index ef598397c12e..f20ec4788655 100644 --- a/wifi/tests/src/android/net/wifi/wificond/SingleScanSettingsTest.java +++ b/wifi/tests/src/android/net/wifi/wificond/SingleScanSettingsTest.java @@ -18,7 +18,6 @@ package android.net.wifi.wificond; import static org.junit.Assert.assertEquals; -import android.net.wifi.IWifiScannerImpl; import android.os.Parcel; import androidx.test.filters.SmallTest; diff --git a/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java b/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java index 68e53362100d..f3867c1c3fdf 100644 --- a/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java +++ b/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java @@ -38,14 +38,6 @@ import static org.mockito.Mockito.when; import android.app.AlarmManager; import android.app.test.TestAlarmManager; import android.content.Context; -import android.net.wifi.IApInterface; -import android.net.wifi.IApInterfaceEventCallback; -import android.net.wifi.IClientInterface; -import android.net.wifi.IPnoScanEvent; -import android.net.wifi.IScanEvent; -import android.net.wifi.ISendMgmtFrameEvent; -import android.net.wifi.IWifiScannerImpl; -import android.net.wifi.IWificond; import android.net.wifi.SoftApInfo; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiScanner; -- cgit v1.2.3 From 7cd8e71494f48344cfb0dea5e9a0037fa8764cf2 Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Mon, 23 Dec 2019 14:24:52 -0800 Subject: [DPP R2] Update ACTION_PROCESS_WIFI_EASY_CONNECT_URI intent Update ACTION_PROCESS_WIFI_EASY_CONNECT_URI intent to include additional information in case of a failure. The intent will return an extra field with result code for R1 and R2 devices, and additional details for R2 devices: SSID, channe list, and band list. Bug: 139381558 Test: Manual test Change-Id: Ib25db37279289acbb3841f4b4862d8cbeb4efdd2 --- .../net/wifi/EasyConnectStatusCallback.java | 40 +++++++++++++++++----- 1 file changed, 31 insertions(+), 9 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/EasyConnectStatusCallback.java b/wifi/java/android/net/wifi/EasyConnectStatusCallback.java index 4fa93ee271e9..8ccf0076f0b0 100644 --- a/wifi/java/android/net/wifi/EasyConnectStatusCallback.java +++ b/wifi/java/android/net/wifi/EasyConnectStatusCallback.java @@ -28,29 +28,27 @@ 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, Executor, - * EasyConnectStatusCallback)} or {@link WifiManager#startEasyConnectAsEnrolleeInitiator(String, - * Executor, EasyConnectStatusCallback)} - * - * @hide + * progress) from the Easy Connect operations. */ -@SystemApi public abstract class EasyConnectStatusCallback { /** * 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. + * {@link #EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED} will be received. + * @hide */ + @SystemApi 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. + * be received, and the {@link #EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT} will be received. + * @hide */ + @SystemApi public static final int EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED = 1; /** @hide */ @@ -64,22 +62,30 @@ public abstract class EasyConnectStatusCallback { /** * Easy Connect Progress event: Initial authentication with peer succeeded. + * @hide */ + @SystemApi public static final int EASY_CONNECT_EVENT_PROGRESS_AUTHENTICATION_SUCCESS = 0; /** * Easy Connect Progress event: Peer requires more time to process bootstrapping. + * @hide */ + @SystemApi public static final int EASY_CONNECT_EVENT_PROGRESS_RESPONSE_PENDING = 1; /** * Easy Connect R2 Progress event: Configuration sent to Enrollee, waiting for response + * @hide */ + @SystemApi 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 + * @hide */ + @SystemApi public static final int EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_ACCEPTED = 3; /** @hide */ @@ -174,6 +180,12 @@ public abstract class EasyConnectStatusCallback { public @interface EasyConnectFailureStatusCode { } + /** @hide */ + @SystemApi + public EasyConnectStatusCallback() { + // Fully-static utility classes must not have constructor + } + /** * Called when local Easy Connect Enrollee successfully receives a new Wi-Fi configuration from * the @@ -185,7 +197,9 @@ public abstract class EasyConnectStatusCallback { * EasyConnectStatusCallback)} . * * @param newNetworkId New Wi-Fi configuration with a network ID received from the configurator + * @hide */ + @SystemApi public abstract void onEnrolleeSuccess(int newNetworkId); /** @@ -197,7 +211,9 @@ public abstract class EasyConnectStatusCallback { * int, Executor,EasyConnectStatusCallback)}. * * @param code Easy Connect success status code. + * @hide */ + @SystemApi public abstract void onConfiguratorSuccess(@EasyConnectSuccessStatusCode int code); /** @@ -205,7 +221,9 @@ public abstract class EasyConnectStatusCallback { * end of the current Easy Connect session, and no further callbacks will be called. * * @param code Easy Connect failure status code. + * @hide */ + @SystemApi public void onFailure(@EasyConnectFailureStatusCode int code) {} /** @@ -227,7 +245,9 @@ public abstract class EasyConnectStatusCallback { * @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. + * @hide */ + @SystemApi public void onFailure(@EasyConnectFailureStatusCode int code, @Nullable String ssid, @NonNull SparseArray channelListArray, @NonNull int[] operatingClassArray) { onFailure(code); @@ -238,6 +258,8 @@ public abstract class EasyConnectStatusCallback { * to show progress. * * @param code Easy Connect progress status code. + * @hide */ + @SystemApi public abstract void onProgress(@EasyConnectProgressStatusCode int code); } -- cgit v1.2.3 From e14a0909efd54753cdc8565a45c394b5273a69ce Mon Sep 17 00:00:00 2001 From: lesl Date: Thu, 12 Dec 2019 17:16:30 +0800 Subject: wifi: Add SoftAp Max Client control support 1. SoftAp Max Client parameter in SoftApConfiguration 2. Add new field in CarrierConfigManager to get carrier max client setting. 3. Add new Callback: onCapabilityChanged to notify Settings to know current supported maximum client number from carrier req and chip limit. Bug: 142752869 Test: atest frameworks/base/wifi/tests/ Change-Id: I03366e22055233b9f77e0c1808e54a473569c9c7 --- wifi/java/android/net/wifi/ISoftApCallback.aidl | 9 ++ wifi/java/android/net/wifi/SoftApCapability.aidl | 19 ++++ wifi/java/android/net/wifi/SoftApCapability.java | 114 +++++++++++++++++++++ .../java/android/net/wifi/SoftApConfiguration.java | 73 +++++++++++-- wifi/java/android/net/wifi/WifiManager.java | 34 ++++++ .../src/android/net/wifi/SoftApCapabilityTest.java | 69 +++++++++++++ .../android/net/wifi/SoftApConfigurationTest.java | 8 +- .../src/android/net/wifi/WifiManagerTest.java | 24 +++++ 8 files changed, 337 insertions(+), 13 deletions(-) create mode 100644 wifi/java/android/net/wifi/SoftApCapability.aidl create mode 100644 wifi/java/android/net/wifi/SoftApCapability.java create mode 100644 wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/ISoftApCallback.aidl b/wifi/java/android/net/wifi/ISoftApCallback.aidl index 452a655edc7b..482b4910921d 100644 --- a/wifi/java/android/net/wifi/ISoftApCallback.aidl +++ b/wifi/java/android/net/wifi/ISoftApCallback.aidl @@ -15,6 +15,7 @@ */ package android.net.wifi; +import android.net.wifi.SoftApCapability; import android.net.wifi.SoftApInfo; import android.net.wifi.WifiClient; @@ -51,4 +52,12 @@ oneway interface ISoftApCallback * @param softApInfo is the softap information. {@link SoftApInfo} */ void onInfoChanged(in SoftApInfo softApInfo); + + + /** + * Service to manager callback providing information of softap. + * + * @param capability is the softap capability. {@link SoftApCapability} + */ + void onCapabilityChanged(in SoftApCapability capability); } diff --git a/wifi/java/android/net/wifi/SoftApCapability.aidl b/wifi/java/android/net/wifi/SoftApCapability.aidl new file mode 100644 index 000000000000..bf30709f15d1 --- /dev/null +++ b/wifi/java/android/net/wifi/SoftApCapability.aidl @@ -0,0 +1,19 @@ +/** + * 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; + +parcelable SoftApCapability; diff --git a/wifi/java/android/net/wifi/SoftApCapability.java b/wifi/java/android/net/wifi/SoftApCapability.java new file mode 100644 index 000000000000..506f49335bc6 --- /dev/null +++ b/wifi/java/android/net/wifi/SoftApCapability.java @@ -0,0 +1,114 @@ +/* + * 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.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.Objects; + +/** + * A class representing capability of the SoftAp. + * {@see WifiManager} + * + * @hide + */ +@SystemApi +public final class SoftApCapability implements Parcelable { + + private int mMaximumSupportedClientNumber; + + /** + * Get the maximum supported client numbers which AP resides on. + */ + public int getMaxSupportedClients() { + return mMaximumSupportedClientNumber; + } + + /** + * Set the maximum supported client numbers which AP resides on. + * @hide + */ + public void setMaxSupportedClients(int maxClient) { + mMaximumSupportedClientNumber = maxClient; + } + + /** + * @hide + */ + public SoftApCapability(@Nullable SoftApCapability source) { + if (source != null) { + mMaximumSupportedClientNumber = source.mMaximumSupportedClientNumber; + } + } + + /** + * @hide + */ + public SoftApCapability() { + } + + @Override + /** Implement the Parcelable interface. */ + public int describeContents() { + return 0; + } + + @Override + /** Implement the Parcelable interface */ + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(mMaximumSupportedClientNumber); + } + + @NonNull + /** Implement the Parcelable interface */ + public static final Creator CREATOR = new Creator() { + public SoftApCapability createFromParcel(Parcel in) { + SoftApCapability capability = new SoftApCapability(); + capability.mMaximumSupportedClientNumber = in.readInt(); + return capability; + } + + public SoftApCapability[] newArray(int size) { + return new SoftApCapability[size]; + } + }; + + @NonNull + @Override + public String toString() { + StringBuilder sbuf = new StringBuilder(); + sbuf.append("MaximumSupportedClientNumber=").append(mMaximumSupportedClientNumber); + return sbuf.toString(); + } + + @Override + public boolean equals(@NonNull Object o) { + if (this == o) return true; + if (!(o instanceof SoftApCapability)) return false; + SoftApCapability capability = (SoftApCapability) o; + return mMaximumSupportedClientNumber == capability.mMaximumSupportedClientNumber; + } + + @Override + public int hashCode() { + return Objects.hash(mMaximumSupportedClientNumber); + } +} diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java index fd8a924bdbee..cd2826bb1764 100644 --- a/wifi/java/android/net/wifi/SoftApConfiguration.java +++ b/wifi/java/android/net/wifi/SoftApConfiguration.java @@ -163,6 +163,11 @@ public final class SoftApConfiguration implements Parcelable { */ private final int mChannel; + /** + * The maximim allowed number of clients that can associate to the AP. + */ + private final int mMaxNumberOfClients; + /** * The operating security type of the AP. * One of the security types from {@link @SecurityType} @@ -191,7 +196,7 @@ public final class SoftApConfiguration implements Parcelable { /** Private constructor for Builder and Parcelable implementation. */ private SoftApConfiguration(@Nullable String ssid, @Nullable MacAddress bssid, @Nullable String wpa2Passphrase, boolean hiddenSsid, @BandType int band, int channel, - @SecurityType int securityType) { + @SecurityType int securityType, int maxNumberOfClients) { mSsid = ssid; mBssid = bssid; mWpa2Passphrase = wpa2Passphrase; @@ -199,6 +204,7 @@ public final class SoftApConfiguration implements Parcelable { mBand = band; mChannel = channel; mSecurityType = securityType; + mMaxNumberOfClients = maxNumberOfClients; } @Override @@ -216,13 +222,14 @@ public final class SoftApConfiguration implements Parcelable { && mHiddenSsid == other.mHiddenSsid && mBand == other.mBand && mChannel == other.mChannel - && mSecurityType == other.mSecurityType; + && mSecurityType == other.mSecurityType + && mMaxNumberOfClients == other.mMaxNumberOfClients; } @Override public int hashCode() { return Objects.hash(mSsid, mBssid, mWpa2Passphrase, mHiddenSsid, - mBand, mChannel, mSecurityType); + mBand, mChannel, mSecurityType, mMaxNumberOfClients); } @Override @@ -236,6 +243,7 @@ public final class SoftApConfiguration implements Parcelable { sbuf.append(" \n Band =").append(mBand); sbuf.append(" \n Channel =").append(mChannel); sbuf.append(" \n SecurityType=").append(getSecurityType()); + sbuf.append(" \n MaxClient=").append(mMaxNumberOfClients); return sbuf.toString(); } @@ -248,6 +256,7 @@ public final class SoftApConfiguration implements Parcelable { dest.writeInt(mBand); dest.writeInt(mChannel); dest.writeInt(mSecurityType); + dest.writeInt(mMaxNumberOfClients); } @Override @@ -262,7 +271,8 @@ public final class SoftApConfiguration implements Parcelable { return new SoftApConfiguration( in.readString(), in.readParcelable(MacAddress.class.getClassLoader()), - in.readString(), in.readBoolean(), in.readInt(), in.readInt(), in.readInt()); + in.readString(), in.readBoolean(), in.readInt(), in.readInt(), in.readInt(), + in.readInt()); } @Override @@ -282,7 +292,7 @@ public final class SoftApConfiguration implements Parcelable { /** * Returns MAC address set to be BSSID for the AP. - * {@link #setBssid(MacAddress)}. + * {@link Builder#setBssid(MacAddress)}. */ @Nullable public MacAddress getBssid() { @@ -291,7 +301,7 @@ public final class SoftApConfiguration implements Parcelable { /** * Returns String set to be passphrase for the WPA2-PSK AP. - * {@link #setWpa2Passphrase(String)}. + * {@link Builder#setWpa2Passphrase(String)}. */ @Nullable public String getWpa2Passphrase() { @@ -301,7 +311,7 @@ public final class SoftApConfiguration implements Parcelable { /** * Returns Boolean set to be indicate hidden (true: doesn't broadcast its SSID) or * not (false: broadcasts its SSID) for the AP. - * {@link #setHiddenSsid(boolean)}. + * {@link Builder#setHiddenSsid(boolean)}. */ public boolean isHiddenSsid() { return mHiddenSsid; @@ -309,7 +319,7 @@ public final class SoftApConfiguration implements Parcelable { /** * Returns {@link BandType} set to be the band for the AP. - * {@link #setBand(@BandType int)}. + * {@link Builder#setBand(@BandType int)}. */ public @BandType int getBand() { return mBand; @@ -317,7 +327,7 @@ public final class SoftApConfiguration implements Parcelable { /** * Returns Integer set to be the channel for the AP. - * {@link #setChannel(int)}. + * {@link Builder#setChannel(int)}. */ public int getChannel() { return mChannel; @@ -332,6 +342,14 @@ public final class SoftApConfiguration implements Parcelable { return mSecurityType; } + /** + * Returns the maximum number of clients that can associate to the AP. + * {@link Builder#setMaxNumberOfClients(int)}. + */ + public int getMaxNumberOfClients() { + return mMaxNumberOfClients; + } + /** * Builds a {@link SoftApConfiguration}, which allows an app to configure various aspects of a * Soft AP. @@ -346,6 +364,7 @@ public final class SoftApConfiguration implements Parcelable { private boolean mHiddenSsid; private int mBand; private int mChannel; + private int mMaxNumberOfClients; private int setSecurityType() { int securityType = SECURITY_TYPE_OPEN; @@ -369,6 +388,7 @@ public final class SoftApConfiguration implements Parcelable { mHiddenSsid = false; mBand = BAND_2GHZ; mChannel = 0; + mMaxNumberOfClients = 0; } /** @@ -383,6 +403,7 @@ public final class SoftApConfiguration implements Parcelable { mHiddenSsid = other.mHiddenSsid; mBand = other.mBand; mChannel = other.mChannel; + mMaxNumberOfClients = other.mMaxNumberOfClients; } /** @@ -393,7 +414,7 @@ public final class SoftApConfiguration implements Parcelable { @NonNull public SoftApConfiguration build() { return new SoftApConfiguration(mSsid, mBssid, mWpa2Passphrase, - mHiddenSsid, mBand, mChannel, setSecurityType()); + mHiddenSsid, mBand, mChannel, setSecurityType(), mMaxNumberOfClients); } /** @@ -523,5 +544,37 @@ public final class SoftApConfiguration implements Parcelable { mChannel = channel; return this; } + + /** + * Specifies the maximum number of clients that can associate to the AP. + * + * The maximum number of clients (STAs) which can associate to the AP. + * The AP will reject association from any clients above this number. + * Specify a value of 0 to have the framework automatically use the maximum number + * which the device can support (based on hardware and carrier constraints). + *

    + * Use {@link WifiManager.SoftApCallback#onCapabilityChanged(SoftApCapability)} and + * {@link SoftApCapability#getMaxSupportedClients} to get the maximum number of clients + * which the device supports (based on hardware and carrier constraints). + * + *

    + *

  • If not set, defaults to 0.
  • + * + * This method requires hardware support. If the method is used to set a + * non-zero {@code maxNumberOfClients} value then + * {@link WifiManager#startTetheredHotspot} will report error code + * {@link WifiManager#SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION}. + * + * @param maxNumberOfClients maximum client number of the AP. + * @return Builder for chaining. + */ + @NonNull + public Builder setMaxNumberOfClients(int maxNumberOfClients) { + if (maxNumberOfClients < 0) { + throw new IllegalArgumentException("maxNumberOfClients should be not negative"); + } + mMaxNumberOfClients = maxNumberOfClients; + return this; + } } } diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 5ab05834cd78..7693f9a1a79a 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -549,6 +549,7 @@ public class WifiManager { * currently support general and no_channel * @see #SAP_START_FAILURE_GENERAL * @see #SAP_START_FAILURE_NO_CHANNEL + * @see #SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION * * @hide */ @@ -652,6 +653,7 @@ public class WifiManager { @IntDef(flag = false, prefix = { "SAP_START_FAILURE_" }, value = { SAP_START_FAILURE_GENERAL, SAP_START_FAILURE_NO_CHANNEL, + SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION, }) @Retention(RetentionPolicy.SOURCE) public @interface SapStartFailure {} @@ -673,6 +675,15 @@ public class WifiManager { @SystemApi public static final int SAP_START_FAILURE_NO_CHANNEL = 1; + /** + * If Wi-Fi AP start failed, this reason code means that the specified configuration + * is not supported by the current HAL version. + * + * @hide + */ + @SystemApi + public static final int SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION = 2; + /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = {"IFACE_IP_MODE_"}, value = { @@ -3431,6 +3442,16 @@ public class WifiManager { default void onInfoChanged(@NonNull SoftApInfo softApInfo) { // Do nothing: can be updated to add SoftApInfo details (e.g. channel) to the UI. } + + /** + * Called when capability of softap changes. + * + * @param softApCapability is the softap capability. {@link SoftApCapability} + */ + default void onCapabilityChanged(@NonNull SoftApCapability softApCapability) { + // Do nothing: can be updated to add SoftApCapability details (e.g. meximum supported + // client number) to the UI. + } } /** @@ -3484,6 +3505,19 @@ public class WifiManager { mCallback.onInfoChanged(softApInfo); }); } + + @Override + public void onCapabilityChanged(SoftApCapability capability) { + if (mVerboseLoggingEnabled) { + Log.v(TAG, "SoftApCallbackProxy: onCapabilityChanged: SoftApCapability=" + + capability); + } + + Binder.clearCallingIdentity(); + mExecutor.execute(() -> { + mCallback.onCapabilityChanged(capability); + }); + } } /** diff --git a/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java b/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java new file mode 100644 index 000000000000..9cb221d81070 --- /dev/null +++ b/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java @@ -0,0 +1,69 @@ +/* + * 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.os.Parcel; + +import static org.junit.Assert.assertEquals; + +import androidx.test.filters.SmallTest; + +import org.junit.Test; + +/** + * Unit tests for {@link android.net.wifi.SoftApCapability}. + */ +@SmallTest +public class SoftApCapabilityTest { + + /** + * Verifies copy constructor. + */ + @Test + public void testCopyOperator() throws Exception { + SoftApCapability capability = new SoftApCapability(); + capability.setMaxSupportedClients(10); + + SoftApCapability copiedCapability = new SoftApCapability(capability); + + assertEquals(capability, copiedCapability); + assertEquals(capability.hashCode(), copiedCapability.hashCode()); + } + + /** + * Verifies parcel serialization/deserialization. + */ + @Test + public void testParcelOperation() throws Exception { + SoftApCapability capability = new SoftApCapability(); + capability.setMaxSupportedClients(10); + + Parcel parcelW = Parcel.obtain(); + capability.writeToParcel(parcelW, 0); + byte[] bytes = parcelW.marshall(); + parcelW.recycle(); + + Parcel parcelR = Parcel.obtain(); + parcelR.unmarshall(bytes, 0, bytes.length); + parcelR.setDataPosition(0); + SoftApCapability fromParcel = SoftApCapability.CREATOR.createFromParcel(parcelR); + + assertEquals(capability, fromParcel); + assertEquals(capability.hashCode(), fromParcel.hashCode()); + } + +} diff --git a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java index 60125e372cd5..1f601036a718 100644 --- a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java @@ -50,6 +50,7 @@ public class SoftApConfigurationTest { assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_2GHZ); assertThat(original.getChannel()).isEqualTo(0); assertThat(original.isHiddenSsid()).isEqualTo(false); + assertThat(original.getMaxNumberOfClients()).isEqualTo(0); SoftApConfiguration unparceled = parcelUnparcel(original); assertThat(unparceled).isNotSameAs(original); @@ -73,7 +74,7 @@ public class SoftApConfigurationTest { assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_2GHZ); assertThat(original.getChannel()).isEqualTo(0); assertThat(original.isHiddenSsid()).isEqualTo(false); - + assertThat(original.getMaxNumberOfClients()).isEqualTo(0); SoftApConfiguration unparceled = parcelUnparcel(original); assertThat(unparceled).isNotSameAs(original); @@ -87,12 +88,13 @@ public class SoftApConfigurationTest { } @Test - public void testWpa2WithBandAndChannelAndHiddenNetwork() { + public void testWpa2WithAllFieldCustomized() { SoftApConfiguration original = new SoftApConfiguration.Builder() .setWpa2Passphrase("secretsecret") .setBand(SoftApConfiguration.BAND_ANY) .setChannel(149, SoftApConfiguration.BAND_5GHZ) .setHiddenSsid(true) + .setMaxNumberOfClients(10) .build(); assertThat(original.getWpa2Passphrase()).isEqualTo("secretsecret"); assertThat(original.getSecurityType()).isEqualTo( @@ -100,7 +102,7 @@ public class SoftApConfigurationTest { assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_5GHZ); assertThat(original.getChannel()).isEqualTo(149); assertThat(original.isHiddenSsid()).isEqualTo(true); - + assertThat(original.getMaxNumberOfClients()).isEqualTo(10); SoftApConfiguration unparceled = parcelUnparcel(original); assertThat(unparceled).isNotSameAs(original); diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 821661196f4f..d8bc1347c332 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -877,6 +877,25 @@ public class WifiManagerTest { verify(mSoftApCallback).onInfoChanged(testSoftApInfo); } + + /* + * Verify client-provided callback is being called through callback proxy + */ + @Test + public void softApCallbackProxyCallsOnCapabilityChanged() throws Exception { + SoftApCapability testSoftApCapability = new SoftApCapability(); + testSoftApCapability.setMaxSupportedClients(10); + ArgumentCaptor callbackCaptor = + ArgumentCaptor.forClass(ISoftApCallback.Stub.class); + mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); + verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(), + anyInt()); + + callbackCaptor.getValue().onCapabilityChanged(testSoftApCapability); + mLooper.dispatchAll(); + verify(mSoftApCallback).onCapabilityChanged(testSoftApCapability); + } + /* * Verify client-provided callback is being called through callback proxy on multiple events */ @@ -885,6 +904,8 @@ public class WifiManagerTest { SoftApInfo testSoftApInfo = new SoftApInfo(); testSoftApInfo.setFrequency(TEST_AP_FREQUENCY); testSoftApInfo.setBandwidth(TEST_AP_BANDWIDTH); + SoftApCapability testSoftApCapability = new SoftApCapability(); + testSoftApCapability.setMaxSupportedClients(10); ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(ISoftApCallback.Stub.class); mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); @@ -896,12 +917,15 @@ public class WifiManagerTest { callbackCaptor.getValue().onConnectedClientsChanged(testClients); callbackCaptor.getValue().onInfoChanged(testSoftApInfo); callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL); + callbackCaptor.getValue().onCapabilityChanged(testSoftApCapability); + mLooper.dispatchAll(); verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLING, 0); verify(mSoftApCallback).onConnectedClientsChanged(testClients); verify(mSoftApCallback).onInfoChanged(testSoftApInfo); verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL); + verify(mSoftApCallback).onCapabilityChanged(testSoftApCapability); } /* -- cgit v1.2.3 From 492e4bd8a75512c68ea2b3ec0b6fbc50e50504a9 Mon Sep 17 00:00:00 2001 From: lesl Date: Tue, 24 Dec 2019 00:08:38 +0800 Subject: wifi: Add features in SoftApCapability Caller can get hotspot feature list from SoftApCapability Bug: 142752869 Test: atest frameworks/base/wifi/tests/ Change-Id: I31fea5c42eab092a838c08b328903d71c720090d --- wifi/java/android/net/wifi/SoftApCapability.java | 67 ++++++++++++++++++++-- .../java/android/net/wifi/SoftApConfiguration.java | 13 +++++ .../src/android/net/wifi/SoftApCapabilityTest.java | 8 ++- .../src/android/net/wifi/WifiManagerTest.java | 4 +- 4 files changed, 84 insertions(+), 8 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/SoftApCapability.java b/wifi/java/android/net/wifi/SoftApCapability.java index 506f49335bc6..c4474e2bc9cc 100644 --- a/wifi/java/android/net/wifi/SoftApCapability.java +++ b/wifi/java/android/net/wifi/SoftApCapability.java @@ -16,12 +16,15 @@ package android.net.wifi; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.Objects; /** @@ -33,6 +36,41 @@ import java.util.Objects; @SystemApi public final class SoftApCapability implements Parcelable { + /** + * Support for automatic channel selection in driver (ACS). + * Driver will auto select best channel based on interference to optimize performance. + * + * flag when {@link R.bool.config_wifi_softap_acs_supported)} is true. + * + *

    + * Use {@link WifiManager.SoftApCallback#onInfoChanged(SoftApInfo)} and + * {@link SoftApInfo#getFrequency} and {@link SoftApInfo#getBandwidth} to get + * driver channel selection result. + */ + public static final int SOFTAP_FEATURE_ACS_OFFLOAD = 1 << 0; + + /** + * Support for client force disconnect. + * flag when {@link R.bool.config_wifi_sofap_client_force_disconnect_supported)} is true + * + *

    + * Several Soft AP client control features, e.g. specifying the maximum number of + * Soft AP clients, only work when this feature support is present. + * Check feature support before invoking + * {@link SoftApConfiguration.Builder#setMaxNumberOfClients(int)} + */ + public static final int SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT = 1 << 1; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(flag = true, prefix = { "SOFTAP_FEATURE_" }, value = { + SOFTAP_FEATURE_ACS_OFFLOAD, + SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT, + }) + public @interface HotspotFeatures {} + + private @HotspotFeatures int mSupportedFeatures = 0; + private int mMaximumSupportedClientNumber; /** @@ -44,25 +82,42 @@ public final class SoftApCapability implements Parcelable { /** * Set the maximum supported client numbers which AP resides on. + * + * @param maxClient maximum supported client numbers for the softap. * @hide */ public void setMaxSupportedClients(int maxClient) { mMaximumSupportedClientNumber = maxClient; } + /** + * Returns true when feature supported, otherwise false. + * + * @param feature one of feature from {@link HotspotFeatures} + */ + public boolean isFeatureSupported(@HotspotFeatures int feature) { + return (mSupportedFeatures & feature) == feature; + } + /** * @hide */ public SoftApCapability(@Nullable SoftApCapability source) { if (source != null) { + mSupportedFeatures = source.mSupportedFeatures; mMaximumSupportedClientNumber = source.mMaximumSupportedClientNumber; } } /** + * Constructor with combination of the feature. + * Zero to no supported feature. + * + * @param features One or combination of the feature from {@link @HotspotFeatures}. * @hide */ - public SoftApCapability() { + public SoftApCapability(@HotspotFeatures int features) { + mSupportedFeatures = features; } @Override @@ -74,6 +129,7 @@ public final class SoftApCapability implements Parcelable { @Override /** Implement the Parcelable interface */ public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(mSupportedFeatures); dest.writeInt(mMaximumSupportedClientNumber); } @@ -81,7 +137,8 @@ public final class SoftApCapability implements Parcelable { /** Implement the Parcelable interface */ public static final Creator CREATOR = new Creator() { public SoftApCapability createFromParcel(Parcel in) { - SoftApCapability capability = new SoftApCapability(); + int supportedFeatures = in.readInt(); + SoftApCapability capability = new SoftApCapability(supportedFeatures); capability.mMaximumSupportedClientNumber = in.readInt(); return capability; } @@ -95,6 +152,7 @@ public final class SoftApCapability implements Parcelable { @Override public String toString() { StringBuilder sbuf = new StringBuilder(); + sbuf.append("SupportedFeatures=").append(mSupportedFeatures); sbuf.append("MaximumSupportedClientNumber=").append(mMaximumSupportedClientNumber); return sbuf.toString(); } @@ -104,11 +162,12 @@ public final class SoftApCapability implements Parcelable { if (this == o) return true; if (!(o instanceof SoftApCapability)) return false; SoftApCapability capability = (SoftApCapability) o; - return mMaximumSupportedClientNumber == capability.mMaximumSupportedClientNumber; + return mSupportedFeatures == capability.mSupportedFeatures + && mMaximumSupportedClientNumber == capability.mMaximumSupportedClientNumber; } @Override public int hashCode() { - return Objects.hash(mMaximumSupportedClientNumber); + return Objects.hash(mSupportedFeatures, mMaximumSupportedClientNumber); } } diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java index cd2826bb1764..05e245b8eabc 100644 --- a/wifi/java/android/net/wifi/SoftApConfiguration.java +++ b/wifi/java/android/net/wifi/SoftApConfiguration.java @@ -523,9 +523,16 @@ public final class SoftApConfiguration implements Parcelable { * Specifies the channel and associated band for the AP. * * The channel which AP resides on. Valid channels are country dependent. + *

    * The default for the channel is a the special value 0 to have the framework * auto-select a valid channel from the band configured with * {@link #setBand(@BandType int)}. + * + * The channel auto selection will offload to driver when + * {@link SoftApCapability#isFeatureSupported(SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD)} + * return true. Driver will auto select best channel which based on environment + * interference to get best performance. Check {@link SoftApCapability} to get more detail. + * * Note, since 6GHz band use the same channel numbering of 2.4GHz and 5GHZ bands, * the caller needs to pass the band containing the selected channel. * @@ -565,6 +572,12 @@ public final class SoftApConfiguration implements Parcelable { * {@link WifiManager#startTetheredHotspot} will report error code * {@link WifiManager#SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION}. * + *

    + * Use {@link WifiManager.SoftApCallback#onCapabilityChanged(SoftApCapability)} and + * {@link SoftApCapability#isFeatureSupported(int)} + * with {@link SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT} to determine whether + * or not this feature is supported. + * * @param maxNumberOfClients maximum client number of the AP. * @return Builder for chaining. */ diff --git a/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java b/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java index 9cb221d81070..ef476ebc2667 100644 --- a/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java +++ b/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java @@ -35,7 +35,9 @@ public class SoftApCapabilityTest { */ @Test public void testCopyOperator() throws Exception { - SoftApCapability capability = new SoftApCapability(); + int testSoftApFeature = SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT + | SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD; + SoftApCapability capability = new SoftApCapability(testSoftApFeature); capability.setMaxSupportedClients(10); SoftApCapability copiedCapability = new SoftApCapability(capability); @@ -49,7 +51,9 @@ public class SoftApCapabilityTest { */ @Test public void testParcelOperation() throws Exception { - SoftApCapability capability = new SoftApCapability(); + int testSoftApFeature = SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT + | SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD; + SoftApCapability capability = new SoftApCapability(testSoftApFeature); capability.setMaxSupportedClients(10); Parcel parcelW = Parcel.obtain(); diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index d8bc1347c332..f9bd31d57ffc 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -883,7 +883,7 @@ public class WifiManagerTest { */ @Test public void softApCallbackProxyCallsOnCapabilityChanged() throws Exception { - SoftApCapability testSoftApCapability = new SoftApCapability(); + SoftApCapability testSoftApCapability = new SoftApCapability(0); testSoftApCapability.setMaxSupportedClients(10); ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(ISoftApCallback.Stub.class); @@ -904,7 +904,7 @@ public class WifiManagerTest { SoftApInfo testSoftApInfo = new SoftApInfo(); testSoftApInfo.setFrequency(TEST_AP_FREQUENCY); testSoftApInfo.setBandwidth(TEST_AP_BANDWIDTH); - SoftApCapability testSoftApCapability = new SoftApCapability(); + SoftApCapability testSoftApCapability = new SoftApCapability(0); testSoftApCapability.setMaxSupportedClients(10); ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(ISoftApCallback.Stub.class); -- cgit v1.2.3 From 725e2d267463e8e1ac76284d05c95312ff15290e Mon Sep 17 00:00:00 2001 From: David Su Date: Wed, 18 Dec 2019 21:36:21 -0800 Subject: Formalize WifiConfiguration#getIpConfiguration() Expose getIpConfiguration() as a @SystemApi for Android TV. Bug: 138801922 Test: boots up and connects to Wifi Test: atest FrameworksWifiApiTests Change-Id: Ied83bc02baaba89369aae81981a448856d33140d --- wifi/java/android/net/wifi/WifiConfiguration.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index d068fc681ae7..acc316e04519 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -2394,10 +2394,14 @@ public class WifiConfiguration implements Parcelable { return key; } - /** @hide */ - @UnsupportedAppUsage + /** + * Get the IpConfiguration object associated with this WifiConfiguration. + * @hide + */ + @NonNull + @SystemApi public IpConfiguration getIpConfiguration() { - return mIpConfiguration; + return new IpConfiguration(mIpConfiguration); } /** -- cgit v1.2.3 From a676b9934cc0cac9b6e6e6b8a531bcd3d74acdfa Mon Sep 17 00:00:00 2001 From: David Su Date: Fri, 3 Jan 2020 02:06:36 +0000 Subject: Revert "ConnectivityManagerTest: grant access to Wifi @hide APIs" This reverts commit 434fe602b8c06c609a2be79f855f20dbe5200c40. Reason for revert: Broke build Change-Id: I15d6fbf06902987e0517f4c72cbf440b7b570a60 --- wifi/Android.bp | 1 - 1 file changed, 1 deletion(-) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 52838f3c2f18..81559224f700 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -47,7 +47,6 @@ test_access_hidden_api_whitelist = [ "//frameworks/base/wifi/tests", "//frameworks/opt/net/wifi/tests/wifitests:__subpackages__", - "//frameworks/base/core/tests/ConnectivityManagerTest", "//frameworks/opt/net/wifi/libs/WifiTrackerLib/tests", ] -- cgit v1.2.3 From 6129ff5a6bc9843ce5e72877f885fc22cd5c24d4 Mon Sep 17 00:00:00 2001 From: David Su Date: Fri, 3 Jan 2020 02:22:40 +0000 Subject: Revert "FrameworksWifiApiTests: build against framework-wifi" This reverts commit ff7b3326cd83bc16e2d4e0235792738b03fb9a5b. Reason for revert: Broke build Change-Id: I0b1daaf443fce341c66a6ca12d89b8691538ed30 --- wifi/tests/Android.bp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'wifi') diff --git a/wifi/tests/Android.bp b/wifi/tests/Android.bp index 9e3acc9107ce..f54d40eb0887 100644 --- a/wifi/tests/Android.bp +++ b/wifi/tests/Android.bp @@ -37,8 +37,6 @@ jacoco_include = ["android.net.wifi.*"] android_test { name: "FrameworksWifiApiTests", - defaults: ["framework-wifi-test-defaults"], - srcs: ["**/*.java"], jacoco: { @@ -61,6 +59,7 @@ android_test { "android.test.base", ], + platform_apis: true, test_suites: [ "device-tests", "mts", -- cgit v1.2.3 From 8b055fdc1c5c43bbc0d0318f2d1f7b8737196b53 Mon Sep 17 00:00:00 2001 From: David Su Date: Fri, 3 Jan 2020 02:21:35 +0000 Subject: Revert "Convert FrameworksWifiApiTests mk to bp" This reverts commit 5eac974c590a33d09a5486042aca7ee0e7f795ad. Reason for revert: Broke build Change-Id: I82e58c215fa7c6f3162fe76a82002e251a7fe68c --- wifi/tests/Android.bp | 67 --------------------------------------------------- wifi/tests/Android.mk | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 67 deletions(-) delete mode 100644 wifi/tests/Android.bp create mode 100644 wifi/tests/Android.mk (limited to 'wifi') diff --git a/wifi/tests/Android.bp b/wifi/tests/Android.bp deleted file mode 100644 index f54d40eb0887..000000000000 --- a/wifi/tests/Android.bp +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (C) 2016 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. - -// Make test APK -// ============================================================ - -// This list is generated from the java source files in this module -// The list is a comma separated list of class names with * matching zero or more characters. -// Example: -// Input files: src/com/android/server/wifi/Test.java src/com/android/server/wifi/AnotherTest.java -// Generated exclude list: com.android.server.wifi.Test*,com.android.server.wifi.AnotherTest* - -// Filter all src files to just java files -local_java_files = ["__builtin_func:filter %.java <'LOCAL_SRC_FILES' unset>"] -// Transform java file names into full class names. -// This only works if the class name matches the file name and the directory structure -// matches the package. -local_classes = ["__builtin_func:subst / . __builtin_func:patsubst src/%.java % <'local_java_files' unset>"] -// Convert class name list to jacoco exclude list -// This appends a * to all classes and replace the space separators with commas. -// These patterns will match all classes in this module and their inner classes. -jacoco_exclude = ["__builtin_func:subst <'space' unset> <'comma' unset> __builtin_func:patsubst % %* <'local_classes' unset>"] - -jacoco_include = ["android.net.wifi.*"] - -android_test { - name: "FrameworksWifiApiTests", - - srcs: ["**/*.java"], - - jacoco: { - include_filter: jacoco_include, - exclude_filter: jacoco_exclude, - }, - - static_libs: [ - "androidx.test.rules", - "core-test-rules", - "guava", - "mockito-target-minus-junit4", - "net-tests-utils", - "frameworks-base-testutils", - "truth-prebuilt", - ], - - libs: [ - "android.test.runner", - "android.test.base", - ], - - platform_apis: true, - test_suites: [ - "device-tests", - "mts", - ], -} diff --git a/wifi/tests/Android.mk b/wifi/tests/Android.mk new file mode 100644 index 000000000000..d2c385b46eb1 --- /dev/null +++ b/wifi/tests/Android.mk @@ -0,0 +1,66 @@ +# Copyright (C) 2016 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. + +LOCAL_PATH:= $(call my-dir) + +# Make test APK +# ============================================================ +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +# This list is generated from the java source files in this module +# The list is a comma separated list of class names with * matching zero or more characters. +# Example: +# Input files: src/com/android/server/wifi/Test.java src/com/android/server/wifi/AnotherTest.java +# Generated exclude list: com.android.server.wifi.Test*,com.android.server.wifi.AnotherTest* + +# Filter all src files to just java files +local_java_files := $(filter %.java,$(LOCAL_SRC_FILES)) +# Transform java file names into full class names. +# This only works if the class name matches the file name and the directory structure +# matches the package. +local_classes := $(subst /,.,$(patsubst src/%.java,%,$(local_java_files))) +# Convert class name list to jacoco exclude list +# This appends a * to all classes and replace the space separators with commas. +# These patterns will match all classes in this module and their inner classes. +jacoco_exclude := $(subst $(space),$(comma),$(patsubst %,%*,$(local_classes))) + +jacoco_include := android.net.wifi.* + +LOCAL_JACK_COVERAGE_INCLUDE_FILTER := $(jacoco_include) +LOCAL_JACK_COVERAGE_EXCLUDE_FILTER := $(jacoco_exclude) + +LOCAL_STATIC_JAVA_LIBRARIES := \ + androidx.test.rules \ + core-test-rules \ + guava \ + mockito-target-minus-junit4 \ + net-tests-utils \ + frameworks-base-testutils \ + truth-prebuilt \ + +LOCAL_JAVA_LIBRARIES := \ + android.test.runner \ + android.test.base \ + +LOCAL_PACKAGE_NAME := FrameworksWifiApiTests +LOCAL_PRIVATE_PLATFORM_APIS := true +LOCAL_COMPATIBILITY_SUITE := \ + device-tests \ + mts \ + +include $(BUILD_PACKAGE) -- cgit v1.2.3 From 50124a0fe52acc8765795bb7b146c354bbe240e6 Mon Sep 17 00:00:00 2001 From: Daulet Zhanguzin Date: Fri, 20 Dec 2019 17:14:52 +0000 Subject: Replace com.android.internal.util.Preconditions.checkNotNull with java.util.Objects.requireNonNull Bug: 126528330 Test: Treehugger Exempt-From-Owner-Approval: Global refactoring. Change-Id: I4a122f5117100e402a81a55a889e99bdd55f19dd --- wifi/java/android/net/wifi/WifiClient.java | 4 +--- .../android/net/wifi/WifiNetworkScoreCache.java | 4 ++-- wifi/java/android/net/wifi/WifiScanner.java | 26 +++++++++++----------- 3 files changed, 16 insertions(+), 18 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiClient.java b/wifi/java/android/net/wifi/WifiClient.java index 3e09580802ce..3794566f3d8f 100644 --- a/wifi/java/android/net/wifi/WifiClient.java +++ b/wifi/java/android/net/wifi/WifiClient.java @@ -22,8 +22,6 @@ import android.net.MacAddress; import android.os.Parcel; import android.os.Parcelable; -import com.android.internal.util.Preconditions; - import java.util.Objects; /** @hide */ @@ -46,7 +44,7 @@ public final class WifiClient implements Parcelable { /** @hide */ public WifiClient(@NonNull MacAddress macAddress) { - Preconditions.checkNotNull(macAddress, "mMacAddress must not be null."); + Objects.requireNonNull(macAddress, "mMacAddress must not be null."); this.mMacAddress = macAddress; } diff --git a/wifi/java/android/net/wifi/WifiNetworkScoreCache.java b/wifi/java/android/net/wifi/WifiNetworkScoreCache.java index be37c229dd14..378549d62edf 100755 --- a/wifi/java/android/net/wifi/WifiNetworkScoreCache.java +++ b/wifi/java/android/net/wifi/WifiNetworkScoreCache.java @@ -29,11 +29,11 @@ import android.util.Log; import android.util.LruCache; import com.android.internal.annotations.GuardedBy; -import com.android.internal.util.Preconditions; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.List; +import java.util.Objects; /** * {@link INetworkScoreCache} implementation for Wifi Networks. @@ -290,7 +290,7 @@ public class WifiNetworkScoreCache extends INetworkScoreCache.Stub { * This cannot be null. */ public CacheListener(@NonNull Handler handler) { - Preconditions.checkNotNull(handler); + Objects.requireNonNull(handler); mHandler = handler; } diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index 8badcc0c2552..2c39c32ac81e 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -40,7 +40,6 @@ import android.util.Log; import android.util.SparseArray; import com.android.internal.util.AsyncChannel; -import com.android.internal.util.Preconditions; import com.android.internal.util.Protocol; import java.lang.annotation.Retention; @@ -48,6 +47,7 @@ import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Objects; import java.util.concurrent.Executor; /** @@ -840,8 +840,8 @@ public class WifiScanner { @RequiresPermission(Manifest.permission.NETWORK_STACK) public void registerScanListener(@NonNull @CallbackExecutor Executor executor, @NonNull ScanListener listener) { - Preconditions.checkNotNull(executor, "executor cannot be null"); - Preconditions.checkNotNull(listener, "listener cannot be null"); + Objects.requireNonNull(executor, "executor cannot be null"); + Objects.requireNonNull(listener, "listener cannot be null"); int key = addListener(listener, executor); if (key == INVALID_KEY) return; validateChannel(); @@ -864,7 +864,7 @@ public class WifiScanner { * #registerScanListener} */ public void unregisterScanListener(@NonNull ScanListener listener) { - Preconditions.checkNotNull(listener, "listener cannot be null"); + Objects.requireNonNull(listener, "listener cannot be null"); int key = removeListener(listener); if (key == INVALID_KEY) return; validateChannel(); @@ -894,7 +894,7 @@ public class WifiScanner { @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startBackgroundScan(ScanSettings settings, ScanListener listener, WorkSource workSource) { - Preconditions.checkNotNull(listener, "listener cannot be null"); + Objects.requireNonNull(listener, "listener cannot be null"); int key = addListener(listener); if (key == INVALID_KEY) return; validateChannel(); @@ -913,7 +913,7 @@ public class WifiScanner { */ @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void stopBackgroundScan(ScanListener listener) { - Preconditions.checkNotNull(listener, "listener cannot be null"); + Objects.requireNonNull(listener, "listener cannot be null"); int key = removeListener(listener); if (key == INVALID_KEY) return; validateChannel(); @@ -962,7 +962,7 @@ public class WifiScanner { */ @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startScan(ScanSettings settings, ScanListener listener, WorkSource workSource) { - Preconditions.checkNotNull(listener, "listener cannot be null"); + Objects.requireNonNull(listener, "listener cannot be null"); int key = addListener(listener); if (key == INVALID_KEY) return; validateChannel(); @@ -981,7 +981,7 @@ public class WifiScanner { */ @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void stopScan(ScanListener listener) { - Preconditions.checkNotNull(listener, "listener cannot be null"); + Objects.requireNonNull(listener, "listener cannot be null"); int key = removeListener(listener); if (key == INVALID_KEY) return; validateChannel(); @@ -1036,8 +1036,8 @@ public class WifiScanner { */ public void startConnectedPnoScan(ScanSettings scanSettings, PnoSettings pnoSettings, PnoScanListener listener) { - Preconditions.checkNotNull(listener, "listener cannot be null"); - Preconditions.checkNotNull(pnoSettings, "pnoSettings cannot be null"); + Objects.requireNonNull(listener, "listener cannot be null"); + Objects.requireNonNull(pnoSettings, "pnoSettings cannot be null"); int key = addListener(listener); if (key == INVALID_KEY) return; validateChannel(); @@ -1058,8 +1058,8 @@ public class WifiScanner { @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void startDisconnectedPnoScan(ScanSettings scanSettings, PnoSettings pnoSettings, PnoScanListener listener) { - Preconditions.checkNotNull(listener, "listener cannot be null"); - Preconditions.checkNotNull(pnoSettings, "pnoSettings cannot be null"); + Objects.requireNonNull(listener, "listener cannot be null"); + Objects.requireNonNull(pnoSettings, "pnoSettings cannot be null"); int key = addListener(listener); if (key == INVALID_KEY) return; validateChannel(); @@ -1074,7 +1074,7 @@ public class WifiScanner { */ @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void stopPnoScan(ScanListener listener) { - Preconditions.checkNotNull(listener, "listener cannot be null"); + Objects.requireNonNull(listener, "listener cannot be null"); int key = removeListener(listener); if (key == INVALID_KEY) return; validateChannel(); -- cgit v1.2.3 From ae86a373c3e498d11d14d668e2149f90f55f434a Mon Sep 17 00:00:00 2001 From: David Su Date: Fri, 3 Jan 2020 14:26:11 -0800 Subject: Wifi: Add java_api_finder plugin Add java_api_finder to find APIs that framework-wifi depends on. Bug: 146163587 Test: none Change-Id: I57a101780490a93b358a467590997118b1ef99d0 --- wifi/Android.bp | 1 + 1 file changed, 1 insertion(+) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 81559224f700..35a892a55423 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -69,6 +69,7 @@ java_library { "//frameworks/base", // TODO(b/140299412) remove once all dependencies are fixed "//frameworks/opt/net/wifi/service:__subpackages__", ] + test_access_hidden_api_whitelist, + plugins: ["java_api_finder"], } droidstubs { -- cgit v1.2.3 From 465bba9047de667f50d7f2b3d6e3ff0c8cd03821 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Mon, 6 Jan 2020 18:26:48 +0800 Subject: Wifi: validate the wep key specified by the key index WEP supports multiple keys and wifi should check the corresponding one, but not always the first one. Bug: 140541572 Test: atest FrameworksWifiApiTests Change-Id: I0aa653db069b2811e1d6ede7f34bd7150b16d64c --- wifi/java/android/net/wifi/WifiConfiguration.java | 3 ++- .../src/android/net/wifi/WifiConfigurationTest.java | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 2a165d390494..716aa8e57a59 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -2428,7 +2428,8 @@ public class WifiConfiguration implements Parcelable { } else if (allowedKeyManagement.get(KeyMgmt.WPA_EAP) || allowedKeyManagement.get(KeyMgmt.IEEE8021X)) { key = SSID + KeyMgmt.strings[KeyMgmt.WPA_EAP]; - } else if (wepKeys[0] != null) { + } else if (wepTxKeyIndex >= 0 && wepTxKeyIndex < wepKeys.length + && wepKeys[wepTxKeyIndex] != null) { key = SSID + "WEP"; } else if (allowedKeyManagement.get(KeyMgmt.OWE)) { key = SSID + KeyMgmt.strings[KeyMgmt.OWE]; diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java index 5d6549ed5f13..909cfefba941 100644 --- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java @@ -270,7 +270,23 @@ public class WifiConfigurationTest { config.allowedKeyManagement.clear(); assertEquals(mSsid + "WEP", config.getSsidAndSecurityTypeString()); + // set WEP key and give a valid index. config.wepKeys[0] = null; + config.wepKeys[2] = "TestWep"; + config.wepTxKeyIndex = 2; + config.allowedKeyManagement.clear(); + assertEquals(mSsid + "WEP", config.getSsidAndSecurityTypeString()); + + // set WEP key but does not give a valid index. + config.wepKeys[0] = null; + config.wepKeys[2] = "TestWep"; + config.wepTxKeyIndex = 0; + config.allowedKeyManagement.clear(); + config.allowedKeyManagement.set(KeyMgmt.OWE); + assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.OWE], config.getSsidAndSecurityTypeString()); + + config.wepKeys[0] = null; + config.wepTxKeyIndex = 0; config.allowedKeyManagement.clear(); config.allowedKeyManagement.set(KeyMgmt.OWE); assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.OWE], config.getSsidAndSecurityTypeString()); -- cgit v1.2.3 From fa083fdc7f57ed3d419e44169fc192a811190f46 Mon Sep 17 00:00:00 2001 From: David Su Date: Sun, 5 Jan 2020 16:00:28 -0800 Subject: Formalize WifiConfiguration copy constructor Copy constructor is used by WifiTrackerLib. Bug: 138801922 Test: compiles Change-Id: Icec13c808b875cde9d8204d55996bb18d8da1eb4 --- wifi/java/android/net/wifi/WifiConfiguration.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 2a165d390494..7cbdc3add497 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -2590,9 +2590,8 @@ public class WifiConfiguration implements Parcelable { return mPasspointManagementObjectTree; } - /** copy constructor {@hide} */ - @UnsupportedAppUsage - public WifiConfiguration(WifiConfiguration source) { + /** Copy constructor */ + public WifiConfiguration(@NonNull WifiConfiguration source) { if (source != null) { networkId = source.networkId; status = source.status; -- cgit v1.2.3 From b37d4c65c12c754f47a9e359b969193e3b7786fe Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Mon, 6 Jan 2020 16:17:41 -0800 Subject: [SAE] Add support to add SAE Authentication algorithm Add support to add SAE Authentication algorithm in the framework (public API), and in the Supplicant HAL. Bug: 147253259 Test: Manual connection to SAE, PSK, OWE and Open APs Test: atest WifiConfigurationTest Change-Id: If37d1e131d12c06fe10b606e5f98db2fd1ad9a7d --- wifi/java/android/net/wifi/WifiConfiguration.java | 10 +++- .../android/net/wifi/WifiConfigurationTest.java | 57 ++++++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index e3a945de7526..b9181dc63de9 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -253,9 +253,12 @@ public class WifiConfiguration implements Parcelable { /** LEAP/Network EAP (only used with LEAP) */ public static final int LEAP = 2; + /** SAE (Used only for WPA3-Personal) */ + public static final int SAE = 3; + public static final String varName = "auth_alg"; - public static final String[] strings = { "OPEN", "SHARED", "LEAP" }; + public static final String[] strings = { "OPEN", "SHARED", "LEAP", "SAE" }; } /** @@ -468,10 +471,13 @@ public class WifiConfiguration implements Parcelable { break; case SECURITY_TYPE_SAE: allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SAE); + allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP); + allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); requirePMF = true; break; case SECURITY_TYPE_EAP_SUITE_B: allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SUITE_B_192); + allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_256); allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256); allowedGroupManagementCiphers.set(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256); // Note: allowedSuiteBCiphers bitset will be set by the service once the @@ -480,6 +486,8 @@ public class WifiConfiguration implements Parcelable { break; case SECURITY_TYPE_OWE: allowedKeyManagement.set(WifiConfiguration.KeyMgmt.OWE); + allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP); + allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); requirePMF = true; break; case SECURITY_TYPE_WAPI_PSK: diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java index 5d6549ed5f13..d8e313d4912b 100644 --- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java @@ -16,6 +16,10 @@ package android.net.wifi; +import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B; +import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_OWE; +import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_SAE; + import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -312,4 +316,57 @@ public class WifiConfigurationTest { assertNotNull(NetworkSelectionStatus.DISABLE_REASON_INFOS.get(i)); } } + + /** + * Ensure that {@link WifiConfiguration#setSecurityParams(int)} sets up the + * {@link WifiConfiguration} object correctly for SAE security type. + * @throws Exception + */ + @Test + public void testSetSecurityParamsForSae() throws Exception { + WifiConfiguration config = new WifiConfiguration(); + + config.setSecurityParams(SECURITY_TYPE_SAE); + + assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SAE)); + assertTrue(config.allowedPairwiseCiphers.get(WifiConfiguration.PairwiseCipher.CCMP)); + assertTrue(config.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.CCMP)); + assertTrue(config.requirePMF); + } + + /** + * Ensure that {@link WifiConfiguration#setSecurityParams(int)} sets up the + * {@link WifiConfiguration} object correctly for OWE security type. + * @throws Exception + */ + @Test + public void testSetSecurityParamsForOwe() throws Exception { + WifiConfiguration config = new WifiConfiguration(); + + config.setSecurityParams(SECURITY_TYPE_OWE); + + assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.OWE)); + assertTrue(config.allowedPairwiseCiphers.get(WifiConfiguration.PairwiseCipher.CCMP)); + assertTrue(config.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.CCMP)); + assertTrue(config.requirePMF); + } + + /** + * Ensure that {@link WifiConfiguration#setSecurityParams(int)} sets up the + * {@link WifiConfiguration} object correctly for Suite-B security type. + * @throws Exception + */ + @Test + public void testSetSecurityParamsForSuiteB() throws Exception { + WifiConfiguration config = new WifiConfiguration(); + + config.setSecurityParams(SECURITY_TYPE_EAP_SUITE_B); + + assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SUITE_B_192)); + assertTrue(config.allowedPairwiseCiphers.get(WifiConfiguration.PairwiseCipher.GCMP_256)); + assertTrue(config.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.GCMP_256)); + assertTrue(config.allowedGroupManagementCiphers + .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256)); + assertTrue(config.requirePMF); + } } -- cgit v1.2.3 From b1be20a2ac798905bb05f50624937bee009fcd7e Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Mon, 30 Dec 2019 18:37:15 +0800 Subject: Wifi: define OEM IE parsing hook function OEM needs to implement this hook for OEM-supported security type. This hook function is empty by default in AOSP. Bug: 139257562 Test: FrameworksWifiApiTests Change-Id: Id223c6acc015d33a42afa4dababc1ca6304d471a --- wifi/java/android/net/wifi/ScanResult.java | 25 +++++++++ wifi/java/android/net/wifi/WifiAnnotations.java | 41 ++++++++++++++ .../android/net/wifi/wificond/WifiCondManager.java | 64 ++++++++++++++++++++++ 3 files changed, 130 insertions(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java index 83a18008919d..61b5aef462df 100644 --- a/wifi/java/android/net/wifi/ScanResult.java +++ b/wifi/java/android/net/wifi/ScanResult.java @@ -82,16 +82,19 @@ public class ScanResult implements Parcelable { * @hide * No security protocol. */ + @SystemApi public static final int PROTOCOL_NONE = 0; /** * @hide * Security protocol type: WPA version 1. */ + @SystemApi public static final int PROTOCOL_WPA = 1; /** * @hide * Security protocol type: RSN, for WPA version 2, and version 3. */ + @SystemApi public static final int PROTOCOL_RSN = 2; /** * @hide @@ -99,79 +102,94 @@ public class ScanResult implements Parcelable { * OSU Server-only authenticated layer 2 Encryption Network. * Used for Hotspot 2.0. */ + @SystemApi public static final int PROTOCOL_OSEN = 3; /** * @hide * Security protocol type: WAPI. */ + @SystemApi public static final int PROTOCOL_WAPI = 4; /** * @hide * No security key management scheme. */ + @SystemApi public static final int KEY_MGMT_NONE = 0; /** * @hide * Security key management scheme: PSK. */ + @SystemApi public static final int KEY_MGMT_PSK = 1; /** * @hide * Security key management scheme: EAP. */ + @SystemApi public static final int KEY_MGMT_EAP = 2; /** * @hide * Security key management scheme: FT_PSK. */ + @SystemApi public static final int KEY_MGMT_FT_PSK = 3; /** * @hide * Security key management scheme: FT_EAP. */ + @SystemApi public static final int KEY_MGMT_FT_EAP = 4; /** * @hide * Security key management scheme: PSK_SHA256 */ + @SystemApi public static final int KEY_MGMT_PSK_SHA256 = 5; /** * @hide * Security key management scheme: EAP_SHA256. */ + @SystemApi public static final int KEY_MGMT_EAP_SHA256 = 6; /** * @hide * Security key management scheme: OSEN. * Used for Hotspot 2.0. */ + @SystemApi public static final int KEY_MGMT_OSEN = 7; /** * @hide * Security key management scheme: SAE. */ + @SystemApi public static final int KEY_MGMT_SAE = 8; /** * @hide * Security key management scheme: OWE. */ + @SystemApi public static final int KEY_MGMT_OWE = 9; /** * @hide * Security key management scheme: SUITE_B_192. */ + @SystemApi public static final int KEY_MGMT_EAP_SUITE_B_192 = 10; /** * @hide * Security key management scheme: FT_SAE. */ + @SystemApi public static final int KEY_MGMT_FT_SAE = 11; /** * @hide * Security key management scheme: OWE in transition mode. */ + @SystemApi public static final int KEY_MGMT_OWE_TRANSITION = 12; /** * @hide @@ -185,35 +203,42 @@ public class ScanResult implements Parcelable { */ @SystemApi public static final int KEY_MGMT_WAPI_CERT = 14; + /** * @hide * No cipher suite. */ + @SystemApi public static final int CIPHER_NONE = 0; /** * @hide * No group addressed, only used for group data cipher. */ + @SystemApi public static final int CIPHER_NO_GROUP_ADDRESSED = 1; /** * @hide * Cipher suite: TKIP */ + @SystemApi public static final int CIPHER_TKIP = 2; /** * @hide * Cipher suite: CCMP */ + @SystemApi public static final int CIPHER_CCMP = 3; /** * @hide * Cipher suite: GCMP */ + @SystemApi public static final int CIPHER_GCMP_256 = 4; /** * @hide * Cipher suite: SMS4 */ + @SystemApi public static final int CIPHER_SMS4 = 5; /** diff --git a/wifi/java/android/net/wifi/WifiAnnotations.java b/wifi/java/android/net/wifi/WifiAnnotations.java index 9223d28836b6..05e5b1d45684 100644 --- a/wifi/java/android/net/wifi/WifiAnnotations.java +++ b/wifi/java/android/net/wifi/WifiAnnotations.java @@ -60,4 +60,45 @@ public final class WifiAnnotations { }) @Retention(RetentionPolicy.SOURCE) public @interface Bandwidth {} + + @IntDef(prefix = { "PROTOCOL_" }, value = { + ScanResult.PROTOCOL_NONE, + ScanResult.PROTOCOL_WPA, + ScanResult.PROTOCOL_RSN, + ScanResult.PROTOCOL_OSEN, + ScanResult.PROTOCOL_WAPI + }) + @Retention(RetentionPolicy.SOURCE) + public @interface Protocol {} + + @IntDef(prefix = { "KEY_MGMT_" }, value = { + ScanResult.KEY_MGMT_NONE, + ScanResult.KEY_MGMT_PSK, + ScanResult.KEY_MGMT_EAP, + ScanResult.KEY_MGMT_FT_PSK, + ScanResult.KEY_MGMT_FT_EAP, + ScanResult.KEY_MGMT_PSK_SHA256, + ScanResult.KEY_MGMT_EAP_SHA256, + ScanResult.KEY_MGMT_OSEN, + ScanResult.KEY_MGMT_SAE, + ScanResult.KEY_MGMT_OWE, + ScanResult.KEY_MGMT_EAP_SUITE_B_192, + ScanResult.KEY_MGMT_FT_SAE, + ScanResult.KEY_MGMT_OWE_TRANSITION, + ScanResult.KEY_MGMT_WAPI_PSK, + ScanResult.KEY_MGMT_WAPI_CERT + }) + @Retention(RetentionPolicy.SOURCE) + public @interface KeyMgmt {} + + @IntDef(prefix = { "CIPHER_" }, value = { + ScanResult.CIPHER_NONE, + ScanResult.CIPHER_NO_GROUP_ADDRESSED, + ScanResult.CIPHER_TKIP, + ScanResult.CIPHER_CCMP, + ScanResult.CIPHER_GCMP_256, + ScanResult.CIPHER_SMS4 + }) + @Retention(RetentionPolicy.SOURCE) + public @interface Cipher {} } diff --git a/wifi/java/android/net/wifi/wificond/WifiCondManager.java b/wifi/java/android/net/wifi/wificond/WifiCondManager.java index 283f2dd78abb..f70bdac25c33 100644 --- a/wifi/java/android/net/wifi/wificond/WifiCondManager.java +++ b/wifi/java/android/net/wifi/wificond/WifiCondManager.java @@ -1154,4 +1154,68 @@ public class WifiCondManager { mApInterfaceListeners.clear(); mSendMgmtFrameInProgress.set(false); } + + /** + * OEM parsed security type + */ + public static class OemSecurityType { + /** The protocol defined in {@link android.net.wifi.WifiAnnotations.Protocol}. */ + public final @WifiAnnotations.Protocol int protocol; + /** + * Supported key management types defined + * in {@link android.net.wifi.WifiAnnotations.KeyMgmt}. + */ + @NonNull public final List keyManagement; + /** + * Supported pairwise cipher types defined + * in {@link android.net.wifi.WifiAnnotations.Cipher}. + */ + @NonNull public final List pairwiseCipher; + /** The group cipher type defined in {@link android.net.wifi.WifiAnnotations.Cipher}. */ + public final @WifiAnnotations.Cipher int groupCipher; + /** + * Default constructor for OemSecurityType + * + * @param protocol The protocol defined in + * {@link android.net.wifi.WifiAnnotations.Protocol}. + * @param keyManagement Supported key management types defined + * in {@link android.net.wifi.WifiAnnotations.KeyMgmt}. + * @param pairwiseCipher Supported pairwise cipher types defined + * in {@link android.net.wifi.WifiAnnotations.Cipher}. + * @param groupCipher The group cipher type defined + * in {@link android.net.wifi.WifiAnnotations.Cipher}. + */ + public OemSecurityType( + @WifiAnnotations.Protocol int protocol, + @NonNull List keyManagement, + @NonNull List pairwiseCipher, + @WifiAnnotations.Cipher int groupCipher) { + this.protocol = protocol; + this.keyManagement = (keyManagement != null) + ? keyManagement : new ArrayList(); + this.pairwiseCipher = (pairwiseCipher != null) + ? pairwiseCipher : new ArrayList(); + this.groupCipher = groupCipher; + } + } + + /** + * OEM information element parser for security types not parsed by the framework. + * + * The OEM method should use the method inputs {@code id}, {@code idExt}, and {@code bytes} + * to perform the parsing. The method should place the results in an OemSecurityType objct. + * + * @param id The information element id. + * @param idExt The information element extension id. This is valid only when id is + * the extension id, {@code 255}. + * @param bytes The raw bytes of information element data, 'Element ID' and 'Length' are + * stripped off already. + * @return an OemSecurityType object if this IE is parsed successfully, null otherwise. + */ + @Nullable public static OemSecurityType parseOemSecurityTypeElement( + int id, + int idExt, + @NonNull byte[] bytes) { + return null; + } } -- cgit v1.2.3 From 74cb7199641e4bc34358f70c608a10938464517b Mon Sep 17 00:00:00 2001 From: Artur Satayev Date: Tue, 10 Dec 2019 17:47:56 +0000 Subject: Use new UnsupportedAppUsage annotation. Existing annotations in libcore/ and frameworks/ will deleted after the migration. This also means that any java library that compiles @UnsupportedAppUsage requires a direct dependency on "unsupportedappusage" java_library. Bug: 145132366 Test: m && diff unsupportedappusage_index.csv Change-Id: I547d7fb2e6bc2e9707bbc0d14dc1e8cd632c5a23 --- wifi/Android.bp | 1 + wifi/java/android/net/wifi/ScanResult.java | 2 +- wifi/java/android/net/wifi/WifiConfiguration.java | 2 +- wifi/java/android/net/wifi/WifiEnterpriseConfig.java | 2 +- wifi/java/android/net/wifi/WifiInfo.java | 2 +- wifi/java/android/net/wifi/WifiManager.java | 2 +- wifi/java/android/net/wifi/WifiSsid.java | 2 +- wifi/java/android/net/wifi/p2p/WifiP2pConfig.java | 2 +- wifi/java/android/net/wifi/p2p/WifiP2pDevice.java | 2 +- wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java | 5 ++--- wifi/java/android/net/wifi/p2p/WifiP2pGroup.java | 2 +- wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java | 2 +- wifi/java/android/net/wifi/p2p/WifiP2pManager.java | 2 +- wifi/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java | 2 +- wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java | 2 +- wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java | 2 +- wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.java | 2 +- wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java | 2 +- 18 files changed, 19 insertions(+), 19 deletions(-) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 35a892a55423..3934af10eddd 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -57,6 +57,7 @@ java_library { libs: [ // TODO(b/140299412) should be framework-system-stubs once we fix all @hide dependencies "framework-minus-apex", + "unsupportedappusage", ], srcs: [ ":framework-wifi-updatable-sources", diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java index 61b5aef462df..c6aca07ebe94 100644 --- a/wifi/java/android/net/wifi/ScanResult.java +++ b/wifi/java/android/net/wifi/ScanResult.java @@ -19,7 +19,7 @@ package android.net.wifi; import android.annotation.IntDef; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index e9f7a4602dc6..a379c75360ac 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -20,7 +20,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.PackageManager; import android.net.IpConfiguration; import android.net.IpConfiguration.ProxySettings; diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java index 7a59a4f9be30..148e8a410aac 100644 --- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java +++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java @@ -19,7 +19,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java index f728491d33cd..62337cbf7e22 100644 --- a/wifi/java/android/net/wifi/WifiInfo.java +++ b/wifi/java/android/net/wifi/WifiInfo.java @@ -19,7 +19,7 @@ package android.net.wifi; import android.annotation.IntRange; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.net.NetworkInfo.DetailedState; import android.net.shared.Inet4AddressUtils; import android.os.Build; diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 7693f9a1a79a..378c67ba4fcb 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -29,8 +29,8 @@ import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ParceledListSlice; import android.net.ConnectivityManager; diff --git a/wifi/java/android/net/wifi/WifiSsid.java b/wifi/java/android/net/wifi/WifiSsid.java index 90756d860a21..704ae81f71aa 100644 --- a/wifi/java/android/net/wifi/WifiSsid.java +++ b/wifi/java/android/net/wifi/WifiSsid.java @@ -18,7 +18,7 @@ package android.net.wifi; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java index c9bca4f20f03..8fa9c3d6f1a6 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java @@ -19,7 +19,7 @@ package android.net.wifi.p2p; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.net.MacAddress; import android.net.wifi.WpsInfo; import android.os.Parcel; diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java index 98ec208f32e6..710175fee747 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java @@ -18,7 +18,7 @@ package android.net.wifi.p2p; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.util.Log; diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java b/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java index acf06fbac681..ededf67fec7f 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java @@ -16,10 +16,9 @@ package android.net.wifi.p2p; -import android.annotation.UnsupportedAppUsage; -import android.os.Parcelable; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; -import android.net.wifi.p2p.WifiP2pDevice; +import android.os.Parcelable; import android.text.TextUtils; import java.util.ArrayList; diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java index d8c50f2ed5f8..21f6704be0bb 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java @@ -17,7 +17,7 @@ package android.net.wifi.p2p; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java index 10fd09aa638f..cdb2806af0b1 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java @@ -17,7 +17,7 @@ package android.net.wifi.p2p; import android.annotation.NonNull; import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.util.LruCache; diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java index 6120e4e8a23a..3459c9496595 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java @@ -24,7 +24,7 @@ import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.annotation.SystemService; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.net.NetworkInfo; import android.net.wifi.WpsInfo; diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java b/wifi/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java index 153e03cc4d9d..d0fe92d5249d 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java @@ -16,7 +16,7 @@ package android.net.wifi.p2p; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; /** * A class representing a Wi-Fi p2p provisional discovery request/response diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java index 48b07032162b..a4115027b6c1 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java @@ -19,7 +19,7 @@ package android.net.wifi.p2p; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java index e32c8e80ad1c..0de7ba6439eb 100644 --- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java +++ b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java @@ -16,7 +16,7 @@ package android.net.wifi.p2p.nsd; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.net.nsd.DnsSdTxtRecord; import android.os.Build; import android.text.TextUtils; diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.java index db0bdb81fef3..37b442baeb3f 100644 --- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.java +++ b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.java @@ -16,7 +16,7 @@ package android.net.wifi.p2p.nsd; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java index 87528c4180af..68cbb88037b0 100644 --- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java +++ b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java @@ -16,7 +16,7 @@ package android.net.wifi.p2p.nsd; -import android.annotation.UnsupportedAppUsage; +import android.compat.annotation.UnsupportedAppUsage; import android.net.wifi.p2p.WifiP2pManager; import android.os.Build; import android.os.Parcel; -- cgit v1.2.3 From 4c5bab630a9175a205b6b71389596c721a10f539 Mon Sep 17 00:00:00 2001 From: David Su Date: Tue, 7 Jan 2020 13:01:30 -0800 Subject: Robolectric shadows: grant access to @hide Wifi APIs Robolectric can continue to use @hide APIs from Mainline modules. Bug: 138801922 Test: m Robolectric_shadows_framework Change-Id: I331a61d337ec5fe021dfb3e4c9b7246267051517 --- wifi/Android.bp | 1 + 1 file changed, 1 insertion(+) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 81559224f700..1d171c771696 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -48,6 +48,7 @@ test_access_hidden_api_whitelist = [ "//frameworks/opt/net/wifi/tests/wifitests:__subpackages__", "//frameworks/opt/net/wifi/libs/WifiTrackerLib/tests", + "//external/robolectric-shadows:__subpackages__", ] java_library { -- cgit v1.2.3 From 9d57adef7ef5ad9b2bc539ceee96f5391aaf7892 Mon Sep 17 00:00:00 2001 From: "Nate(Qiang) Jiang" Date: Tue, 7 Jan 2020 13:57:02 -0800 Subject: make requireSimCredential() public API make this API to public for Settings App use. Bug: 147310480 Test: atest android.net.wifi Change-Id: I809afcfc8da4906aaf7bd884d723c4d42d538282 --- wifi/java/android/net/wifi/WifiEnterpriseConfig.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java index 7a59a4f9be30..f8c107459672 100644 --- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java +++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java @@ -1336,20 +1336,18 @@ public class WifiEnterpriseConfig implements Parcelable { } /** - * If the current authentication method needs SIM card. - * @return true if the credential information require SIM card for current authentication + * Utility method to determine whether the configuration's authentication method is SIM-based. + * + * @return true if the credential information requires SIM card for current authentication * method, otherwise it returns false. - * @hide */ - public boolean requireSimCredential() { + public boolean isAuthenticationSimBased() { if (mEapMethod == Eap.SIM || mEapMethod == Eap.AKA || mEapMethod == Eap.AKA_PRIME) { return true; } if (mEapMethod == Eap.PEAP) { - if (mPhase2Method == Phase2.SIM || mPhase2Method == Phase2.AKA - || mPhase2Method == Phase2.AKA_PRIME) { - return true; - } + return mPhase2Method == Phase2.SIM || mPhase2Method == Phase2.AKA + || mPhase2Method == Phase2.AKA_PRIME; } return false; } -- cgit v1.2.3 From 6395988c7117429de3ba46a2c9cd447b47404239 Mon Sep 17 00:00:00 2001 From: David Su Date: Tue, 7 Jan 2020 17:20:32 -0800 Subject: WifiManager: Promote EXTRA_WIFI_AP_FAILURE_REASON to @SystemApi EXTRA_WIFI_AP_FAILURE_REASON is @hide, but used by Android Auto for debugging purposes. Promote it to @SystemApi. Bug: 143970861 Test: compiles Change-Id: I427ea9a2af0c74cb3edfb84fbb2305cd76355185 --- wifi/java/android/net/wifi/WifiManager.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 378c67ba4fcb..c4ec44edce4b 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -545,15 +545,22 @@ public class WifiManager { public static final String EXTRA_WIFI_AP_STATE = "wifi_state"; /** - * The look up key for an int that indicates why softAP started failed - * currently support general and no_channel - * @see #SAP_START_FAILURE_GENERAL - * @see #SAP_START_FAILURE_NO_CHANNEL - * @see #SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION + * An extra containing the int error code for Soft AP start failure. + * Can be obtained from the {@link #WIFI_AP_STATE_CHANGED_ACTION} using + * {@link android.content.Intent#getIntExtra}. + * This extra will only be attached if {@link #EXTRA_WIFI_AP_STATE} is + * attached and is equal to {@link #WIFI_AP_STATE_FAILED}. + * + * The error code will be one of: + * {@link #SAP_START_FAILURE_GENERAL}, + * {@link #SAP_START_FAILURE_NO_CHANNEL}, + * {@link #SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION} * * @hide */ - public static final String EXTRA_WIFI_AP_FAILURE_REASON = "wifi_ap_error_code"; + @SystemApi + public static final String EXTRA_WIFI_AP_FAILURE_REASON = + "android.net.wifi.extra.WIFI_AP_FAILURE_REASON"; /** * The previous Wi-Fi state. * -- cgit v1.2.3 From cc38e1f5dca78cf6e095581f5c9be9fd17ffe637 Mon Sep 17 00:00:00 2001 From: David Su Date: Tue, 7 Jan 2020 19:47:28 -0800 Subject: framework-wifi-test-defaults: use framework instead of framework-minus-apex framework-minus-apex is now restricted visibility, instead use framework.jar. Bug: 138801922 Test: compiles Change-Id: I2a33de91dbf9609b93f427f641483b74da7cf82a --- wifi/Android.bp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 634f6746d815..09d5386dcfc5 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -106,8 +106,10 @@ java_defaults { name: "framework-wifi-test-defaults", sdk_version: "core_platform", // tests can use @CorePlatformApi's libs: [ + // order matters: classes in framework-wifi are resolved before framework, meaning + // @hide APIs in framework-wifi are resolved before @SystemApi stubs in framework "framework-wifi", - "framework-minus-apex", + "framework", // if sdk_version="" this gets automatically included, but here we need to add manually. "framework-res", -- cgit v1.2.3 From 3562952f8369e496b412c73f8a0b86b0ffd5cf1a Mon Sep 17 00:00:00 2001 From: lesl Date: Fri, 27 Dec 2019 18:26:07 +0800 Subject: softap: Add SAE and SAE transition mode in configuration Bug: 142752869 Test: atest frameworks/base/wifi/tests/ Change-Id: I2eac1b7291554cd69db9833d494ba741a65d86c3 --- wifi/java/android/net/wifi/SoftApCapability.java | 9 ++ .../java/android/net/wifi/SoftApConfiguration.java | 120 +++++++++++++------ .../android/net/wifi/SoftApConfigurationTest.java | 128 ++++++++++++++++++++- 3 files changed, 218 insertions(+), 39 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/SoftApCapability.java b/wifi/java/android/net/wifi/SoftApCapability.java index c4474e2bc9cc..2bbe7d2aa4ec 100644 --- a/wifi/java/android/net/wifi/SoftApCapability.java +++ b/wifi/java/android/net/wifi/SoftApCapability.java @@ -61,11 +61,20 @@ public final class SoftApCapability implements Parcelable { */ public static final int SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT = 1 << 1; + + /** + * Support for WPA3 Simultaneous Authentication of Equals (WPA3-SAE). + * + * flag when {@link config_wifi_softap_sae_supported)} is true. + */ + public static final int SOFTAP_FEATURE_WPA3_SAE = 1 << 2; + /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(flag = true, prefix = { "SOFTAP_FEATURE_" }, value = { SOFTAP_FEATURE_ACS_OFFLOAD, SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT, + SOFTAP_FEATURE_WPA3_SAE, }) public @interface HotspotFeatures {} diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java index 05e245b8eabc..65e9b7910e5e 100644 --- a/wifi/java/android/net/wifi/SoftApConfiguration.java +++ b/wifi/java/android/net/wifi/SoftApConfiguration.java @@ -25,6 +25,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; import java.lang.annotation.Retention; @@ -55,6 +56,11 @@ import java.util.concurrent.Executor; @SystemApi public final class SoftApConfiguration implements Parcelable { + @VisibleForTesting + static final int PSK_MIN_LEN = 8; + @VisibleForTesting + static final int PSK_MAX_LEN = 63; + /** * 2GHz band. * @hide @@ -142,9 +148,10 @@ public final class SoftApConfiguration implements Parcelable { private final @Nullable MacAddress mBssid; /** - * Pre-shared key for WPA2-PSK encryption (non-null enables WPA2-PSK). + * Pre-shared key for WPA2-PSK or WPA3-SAE-Transition or WPA3-SAE encryption which depends on + * the security type. */ - private final @Nullable String mWpa2Passphrase; + private final @Nullable String mPassphrase; /** * This is a network that does not broadcast its SSID, so an @@ -185,21 +192,31 @@ public final class SoftApConfiguration implements Parcelable { @SystemApi public static final int SECURITY_TYPE_WPA2_PSK = 1; + /** @hide */ + @SystemApi + public static final int SECURITY_TYPE_WPA3_SAE_TRANSITION = 2; + + /** @hide */ + @SystemApi + public static final int SECURITY_TYPE_WPA3_SAE = 3; + /** @hide */ @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = { "SECURITY_TYPE" }, value = { + @IntDef(prefix = { "SECURITY_TYPE_" }, value = { SECURITY_TYPE_OPEN, SECURITY_TYPE_WPA2_PSK, + SECURITY_TYPE_WPA3_SAE_TRANSITION, + SECURITY_TYPE_WPA3_SAE, }) public @interface SecurityType {} /** Private constructor for Builder and Parcelable implementation. */ private SoftApConfiguration(@Nullable String ssid, @Nullable MacAddress bssid, - @Nullable String wpa2Passphrase, boolean hiddenSsid, @BandType int band, int channel, + @Nullable String passphrase, boolean hiddenSsid, @BandType int band, int channel, @SecurityType int securityType, int maxNumberOfClients) { mSsid = ssid; mBssid = bssid; - mWpa2Passphrase = wpa2Passphrase; + mPassphrase = passphrase; mHiddenSsid = hiddenSsid; mBand = band; mChannel = channel; @@ -218,7 +235,7 @@ public final class SoftApConfiguration implements Parcelable { SoftApConfiguration other = (SoftApConfiguration) otherObj; return Objects.equals(mSsid, other.mSsid) && Objects.equals(mBssid, other.mBssid) - && Objects.equals(mWpa2Passphrase, other.mWpa2Passphrase) + && Objects.equals(mPassphrase, other.mPassphrase) && mHiddenSsid == other.mHiddenSsid && mBand == other.mBand && mChannel == other.mChannel @@ -228,7 +245,7 @@ public final class SoftApConfiguration implements Parcelable { @Override public int hashCode() { - return Objects.hash(mSsid, mBssid, mWpa2Passphrase, mHiddenSsid, + return Objects.hash(mSsid, mBssid, mPassphrase, mHiddenSsid, mBand, mChannel, mSecurityType, mMaxNumberOfClients); } @@ -237,8 +254,8 @@ public final class SoftApConfiguration implements Parcelable { StringBuilder sbuf = new StringBuilder(); sbuf.append("ssid=").append(mSsid); if (mBssid != null) sbuf.append(" \n bssid=").append(mBssid.toString()); - sbuf.append(" \n Wpa2Passphrase =").append( - TextUtils.isEmpty(mWpa2Passphrase) ? "" : ""); + sbuf.append(" \n Passphrase =").append( + TextUtils.isEmpty(mPassphrase) ? "" : ""); sbuf.append(" \n HiddenSsid =").append(mHiddenSsid); sbuf.append(" \n Band =").append(mBand); sbuf.append(" \n Channel =").append(mChannel); @@ -251,7 +268,7 @@ public final class SoftApConfiguration implements Parcelable { public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeString(mSsid); dest.writeParcelable(mBssid, flags); - dest.writeString(mWpa2Passphrase); + dest.writeString(mPassphrase); dest.writeBoolean(mHiddenSsid); dest.writeInt(mBand); dest.writeInt(mChannel); @@ -299,13 +316,26 @@ public final class SoftApConfiguration implements Parcelable { return mBssid; } + // TODO: Remove it after update the caller /** * Returns String set to be passphrase for the WPA2-PSK AP. - * {@link Builder#setWpa2Passphrase(String)}. + * {@link #setWpa2Passphrase(String)}. */ @Nullable public String getWpa2Passphrase() { - return mWpa2Passphrase; + if (mSecurityType == SECURITY_TYPE_WPA2_PSK) { + return mPassphrase; + } + return null; + } + + /** + * Returns String set to be passphrase for current AP. + * {@link #setPassphrase(String, @SecurityType int)}. + */ + @Nullable + public String getPassphrase() { + return mPassphrase; } /** @@ -360,23 +390,12 @@ public final class SoftApConfiguration implements Parcelable { public static final class Builder { private String mSsid; private MacAddress mBssid; - private String mWpa2Passphrase; + private String mPassphrase; private boolean mHiddenSsid; private int mBand; private int mChannel; private int mMaxNumberOfClients; - - private int setSecurityType() { - int securityType = SECURITY_TYPE_OPEN; - if (!TextUtils.isEmpty(mWpa2Passphrase)) { // WPA2-PSK network. - securityType = SECURITY_TYPE_WPA2_PSK; - } - return securityType; - } - - private void clearAllPassphrase() { - mWpa2Passphrase = null; - } + private int mSecurityType; /** * Constructs a Builder with default values (see {@link Builder}). @@ -384,11 +403,12 @@ public final class SoftApConfiguration implements Parcelable { public Builder() { mSsid = null; mBssid = null; - mWpa2Passphrase = null; + mPassphrase = null; mHiddenSsid = false; mBand = BAND_2GHZ; mChannel = 0; mMaxNumberOfClients = 0; + mSecurityType = SECURITY_TYPE_OPEN; } /** @@ -399,11 +419,12 @@ public final class SoftApConfiguration implements Parcelable { mSsid = other.mSsid; mBssid = other.mBssid; - mWpa2Passphrase = other.mWpa2Passphrase; + mPassphrase = other.mPassphrase; mHiddenSsid = other.mHiddenSsid; mBand = other.mBand; mChannel = other.mChannel; mMaxNumberOfClients = other.mMaxNumberOfClients; + mSecurityType = other.mSecurityType; } /** @@ -413,8 +434,8 @@ public final class SoftApConfiguration implements Parcelable { */ @NonNull public SoftApConfiguration build() { - return new SoftApConfiguration(mSsid, mBssid, mWpa2Passphrase, - mHiddenSsid, mBand, mChannel, setSecurityType(), mMaxNumberOfClients); + return new SoftApConfiguration(mSsid, mBssid, mPassphrase, + mHiddenSsid, mBand, mChannel, mSecurityType, mMaxNumberOfClients); } /** @@ -461,6 +482,7 @@ public final class SoftApConfiguration implements Parcelable { return this; } + // TODO: Remove it after update the caller /** * Specifies that this AP should use WPA2-PSK with the given ASCII WPA2 passphrase. * When set to null, an open network is created. @@ -473,15 +495,47 @@ public final class SoftApConfiguration implements Parcelable { */ @NonNull public Builder setWpa2Passphrase(@Nullable String passphrase) { - if (passphrase != null) { + return setPassphrase(passphrase, SECURITY_TYPE_WPA2_PSK); + } + + /** + * Specifies that this AP should use specific security type with the given ASCII passphrase. + * + * @param securityType one of the security types from {@link @SecurityType}. + * @param passphrase The passphrase to use for sepcific {@link @SecurityType} configuration + * or null with {@link @SecurityType#SECURITY_TYPE_OPEN}. + * + * @return Builder for chaining. + * @throws IllegalArgumentException when the passphrase length is invalid and + * {@code securityType} is not {@link @SecurityType#SECURITY_TYPE_OPEN} + * or non-null passphrase and {@code securityType} is + * {@link @SecurityType#SECURITY_TYPE_OPEN}. + */ + @NonNull + public Builder setPassphrase(@Nullable String passphrase, @SecurityType int securityType) { + if (securityType == SECURITY_TYPE_OPEN) { + if (passphrase != null) { + throw new IllegalArgumentException( + "passphrase should be null when security type is open"); + } + } else { + Preconditions.checkStringNotEmpty(passphrase); final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder(); if (!asciiEncoder.canEncode(passphrase)) { throw new IllegalArgumentException("passphrase not ASCII encodable"); } - Preconditions.checkStringNotEmpty(passphrase); + if (securityType == SECURITY_TYPE_WPA2_PSK + || securityType == SECURITY_TYPE_WPA3_SAE_TRANSITION) { + if (passphrase.length() < PSK_MIN_LEN || passphrase.length() > PSK_MAX_LEN) { + throw new IllegalArgumentException( + "Password size must be at least " + PSK_MIN_LEN + + " and no more than " + PSK_MAX_LEN + + " for WPA2_PSK and WPA3_SAE_TRANSITION Mode"); + } + } } - clearAllPassphrase(); - mWpa2Passphrase = passphrase; + mSecurityType = securityType; + mPassphrase = passphrase; return this; } diff --git a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java index 1f601036a718..acd334355806 100644 --- a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java @@ -25,8 +25,12 @@ import androidx.test.filters.SmallTest; import org.junit.Test; +import java.util.Random; + @SmallTest public class SoftApConfigurationTest { + private static final String TEST_CHAR_SET_AS_STRING = "abcdefghijklmnopqrstuvwxyz0123456789"; + private SoftApConfiguration parcelUnparcel(SoftApConfiguration configIn) { Parcel parcel = Parcel.obtain(); parcel.writeParcelable(configIn, 0); @@ -37,6 +41,25 @@ public class SoftApConfigurationTest { return configOut; } + /** + * Helper method to generate random string. + * + * Note: this method has limited use as a random string generator. + * The characters used in this method do no not cover all valid inputs. + * @param length number of characters to generate for the string + * @return String generated string of random characters + */ + private String generateRandomString(int length) { + Random random = new Random(); + StringBuilder stringBuilder = new StringBuilder(length); + int index = -1; + while (stringBuilder.length() < length) { + index = random.nextInt(TEST_CHAR_SET_AS_STRING.length()); + stringBuilder.append(TEST_CHAR_SET_AS_STRING.charAt(index)); + } + return stringBuilder.toString(); + } + @Test public void testBasicSettings() { SoftApConfiguration original = new SoftApConfiguration.Builder() @@ -45,7 +68,7 @@ public class SoftApConfigurationTest { .build(); assertThat(original.getSsid()).isEqualTo("ssid"); assertThat(original.getBssid()).isEqualTo(MacAddress.fromString("11:22:33:44:55:66")); - assertThat(original.getWpa2Passphrase()).isNull(); + assertThat(original.getPassphrase()).isNull(); assertThat(original.getSecurityType()).isEqualTo(SoftApConfiguration.SECURITY_TYPE_OPEN); assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_2GHZ); assertThat(original.getChannel()).isEqualTo(0); @@ -66,9 +89,9 @@ public class SoftApConfigurationTest { @Test public void testWpa2() { SoftApConfiguration original = new SoftApConfiguration.Builder() - .setWpa2Passphrase("secretsecret") + .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) .build(); - assertThat(original.getWpa2Passphrase()).isEqualTo("secretsecret"); + assertThat(original.getPassphrase()).isEqualTo("secretsecret"); assertThat(original.getSecurityType()).isEqualTo( SoftApConfiguration.SECURITY_TYPE_WPA2_PSK); assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_2GHZ); @@ -90,13 +113,12 @@ public class SoftApConfigurationTest { @Test public void testWpa2WithAllFieldCustomized() { SoftApConfiguration original = new SoftApConfiguration.Builder() - .setWpa2Passphrase("secretsecret") - .setBand(SoftApConfiguration.BAND_ANY) + .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) .setChannel(149, SoftApConfiguration.BAND_5GHZ) .setHiddenSsid(true) .setMaxNumberOfClients(10) .build(); - assertThat(original.getWpa2Passphrase()).isEqualTo("secretsecret"); + assertThat(original.getPassphrase()).isEqualTo("secretsecret"); assertThat(original.getSecurityType()).isEqualTo( SoftApConfiguration.SECURITY_TYPE_WPA2_PSK); assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_5GHZ); @@ -114,4 +136,98 @@ public class SoftApConfigurationTest { assertThat(copy).isEqualTo(original); assertThat(copy.hashCode()).isEqualTo(original.hashCode()); } + + @Test + public void testWpa3Sae() { + SoftApConfiguration original = new SoftApConfiguration.Builder() + .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE) + .setChannel(149, SoftApConfiguration.BAND_5GHZ) + .setHiddenSsid(true) + .build(); + assertThat(original.getPassphrase()).isEqualTo("secretsecret"); + assertThat(original.getSecurityType()).isEqualTo( + SoftApConfiguration.SECURITY_TYPE_WPA3_SAE); + assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_5GHZ); + assertThat(original.getChannel()).isEqualTo(149); + assertThat(original.isHiddenSsid()).isEqualTo(true); + + + SoftApConfiguration unparceled = parcelUnparcel(original); + assertThat(unparceled).isNotSameAs(original); + assertThat(unparceled).isEqualTo(original); + assertThat(unparceled.hashCode()).isEqualTo(original.hashCode()); + + SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build(); + assertThat(copy).isNotSameAs(original); + assertThat(copy).isEqualTo(original); + assertThat(copy.hashCode()).isEqualTo(original.hashCode()); + } + + @Test + public void testWpa3SaeTransition() { + SoftApConfiguration original = new SoftApConfiguration.Builder() + .setPassphrase("secretsecret", + SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION) + .setChannel(149, SoftApConfiguration.BAND_5GHZ) + .setHiddenSsid(true) + .build(); + assertThat(original.getSecurityType()).isEqualTo( + SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION); + assertThat(original.getPassphrase()).isEqualTo("secretsecret"); + assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_5GHZ); + assertThat(original.getChannel()).isEqualTo(149); + assertThat(original.isHiddenSsid()).isEqualTo(true); + + + SoftApConfiguration unparceled = parcelUnparcel(original); + assertThat(unparceled).isNotSameAs(original); + assertThat(unparceled).isEqualTo(original); + assertThat(unparceled.hashCode()).isEqualTo(original.hashCode()); + + SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build(); + assertThat(copy).isNotSameAs(original); + assertThat(copy).isEqualTo(original); + assertThat(copy.hashCode()).isEqualTo(original.hashCode()); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidShortPasswordLengthForWpa2() { + SoftApConfiguration original = new SoftApConfiguration.Builder() + .setPassphrase(generateRandomString(SoftApConfiguration.PSK_MIN_LEN - 1), + SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) + .setChannel(149, SoftApConfiguration.BAND_5GHZ) + .setHiddenSsid(true) + .build(); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidLongPasswordLengthForWpa2() { + SoftApConfiguration original = new SoftApConfiguration.Builder() + .setPassphrase(generateRandomString(SoftApConfiguration.PSK_MAX_LEN + 1), + SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) + .setChannel(149, SoftApConfiguration.BAND_5GHZ) + .setHiddenSsid(true) + .build(); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidShortPasswordLengthForWpa3SaeTransition() { + SoftApConfiguration original = new SoftApConfiguration.Builder() + .setPassphrase(generateRandomString(SoftApConfiguration.PSK_MIN_LEN - 1), + SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION) + .setChannel(149, SoftApConfiguration.BAND_5GHZ) + .setHiddenSsid(true) + .build(); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidLongPasswordLengthForWpa3SaeTransition() { + SoftApConfiguration original = new SoftApConfiguration.Builder() + .setPassphrase(generateRandomString(SoftApConfiguration.PSK_MAX_LEN + 1), + SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION) + .setChannel(149, SoftApConfiguration.BAND_5GHZ) + .setHiddenSsid(true) + .build(); + } + } -- cgit v1.2.3 From b6f262f5524d4de09e43ac55d140fb3c8c429c38 Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Fri, 27 Dec 2019 12:43:21 -0800 Subject: Add auto-join API for Passpoint configurations Add API to enable/disable the auto-join configurations for Passpoint profiles. Bug: 139199957 Test: atest android.net.wifi Change-Id: I08729b1c31b9fdf10d513dd04d35ead18f2eaa62 --- wifi/java/android/net/wifi/IWifiManager.aidl | 2 + wifi/java/android/net/wifi/WifiManager.java | 17 +++++++++ .../net/wifi/hotspot2/PasspointConfiguration.java | 43 +++++++++++++++++++++- .../com/android/server/wifi/BaseWifiService.java | 5 +++ .../src/android/net/wifi/WifiManagerTest.java | 14 ++++++- .../wifi/hotspot2/PasspointConfigurationTest.java | 1 + 6 files changed, 80 insertions(+), 2 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 1678d5a4776b..71942f0f80f4 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -90,6 +90,8 @@ interface IWifiManager void allowAutojoin(int netId, boolean choice); + void allowAutojoinPasspoint(String fqdn, boolean enableAutoJoin); + boolean startScan(String packageName, String featureId); List getScanResults(String callingPackage, String callingFeatureId); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 7693f9a1a79a..b797e6ba04d0 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -4102,6 +4102,23 @@ public class WifiManager { } } + /** + * Configure auto-join settings for a Passpoint profile. + * + * @param fqdn the FQDN (fully qualified domain name) of the passpoint profile. + * @param enableAutoJoin true to enable autojoin, false to disable autojoin. + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) + public void allowAutojoinPasspoint(@NonNull String fqdn, boolean enableAutoJoin) { + try { + mService.allowAutojoinPasspoint(fqdn, enableAutoJoin); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Disable an ephemeral network. * diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java index 5befb54ce50a..1822e84fdd57 100644 --- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java +++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java @@ -17,6 +17,7 @@ package android.net.wifi.hotspot2; import android.annotation.Nullable; +import android.annotation.SystemApi; import android.net.wifi.hotspot2.pps.Credential; import android.net.wifi.hotspot2.pps.HomeSp; import android.net.wifi.hotspot2.pps.Policy; @@ -422,6 +423,41 @@ public final class PasspointConfiguration implements Parcelable { return mCarrierId; } + /** + * The auto-join configuration specifies whether or not the Passpoint Configuration is + * considered for auto-connection. If true then yes, if false then it isn't considered as part + * of auto-connection - but can still be manually connected to. + */ + private boolean mIsAutoJoinEnabled = true; + + /** + * Configures the auto-association status of this Passpoint configuration. A value of true + * indicates that the configuration will be considered for auto-connection, a value of false + * indicates that only manual connection will work - the framework will not auto-associate to + * this Passpoint network. + * + * @param autoJoinEnabled true to be considered for framework auto-connection, false otherwise. + * @hide + */ + public void setAutoJoinEnabled(boolean autoJoinEnabled) { + mIsAutoJoinEnabled = autoJoinEnabled; + } + + /** + * Indicates whether the Passpoint configuration may be auto-connected to by the framework. A + * value of true indicates that auto-connection can happen, a value of false indicates that it + * cannot. However, even when auto-connection is not possible manual connection by the user is + * possible. + * + * @return the auto-join configuration: true for auto-connection (or join) enabled, false + * otherwise. + * @hide + */ + @SystemApi + public boolean isAutoJoinEnabled() { + return mIsAutoJoinEnabled; + } + /** * Constructor for creating PasspointConfiguration with default values. */ @@ -464,6 +500,7 @@ public final class PasspointConfiguration implements Parcelable { mServiceFriendlyNames = source.mServiceFriendlyNames; mAaaServerTrustedNames = source.mAaaServerTrustedNames; mCarrierId = source.mCarrierId; + mIsAutoJoinEnabled = source.mIsAutoJoinEnabled; } @Override @@ -493,6 +530,7 @@ public final class PasspointConfiguration implements Parcelable { (HashMap) mServiceFriendlyNames); dest.writeBundle(bundle); dest.writeInt(mCarrierId); + dest.writeBoolean(mIsAutoJoinEnabled); } @Override @@ -523,6 +561,7 @@ public final class PasspointConfiguration implements Parcelable { && mUsageLimitDataLimit == that.mUsageLimitDataLimit && mUsageLimitTimeLimitInMinutes == that.mUsageLimitTimeLimitInMinutes && mCarrierId == that.mCarrierId + && mIsAutoJoinEnabled == that.mIsAutoJoinEnabled && (mServiceFriendlyNames == null ? that.mServiceFriendlyNames == null : mServiceFriendlyNames.equals(that.mServiceFriendlyNames)); } @@ -533,7 +572,7 @@ public final class PasspointConfiguration implements Parcelable { mUpdateIdentifier, mCredentialPriority, mSubscriptionCreationTimeInMillis, mSubscriptionExpirationTimeInMillis, mUsageLimitUsageTimePeriodInMinutes, mUsageLimitStartTimeInMillis, mUsageLimitDataLimit, mUsageLimitTimeLimitInMinutes, - mServiceFriendlyNames, mCarrierId); + mServiceFriendlyNames, mCarrierId, mIsAutoJoinEnabled); } @Override @@ -587,6 +626,7 @@ public final class PasspointConfiguration implements Parcelable { builder.append("ServiceFriendlyNames: ").append(mServiceFriendlyNames); } builder.append("CarrierId:" + mCarrierId); + builder.append("IsAutoJoinEnabled:" + mIsAutoJoinEnabled); return builder.toString(); } @@ -692,6 +732,7 @@ public final class PasspointConfiguration implements Parcelable { "serviceFriendlyNames"); config.setServiceFriendlyNames(friendlyNamesMap); config.mCarrierId = in.readInt(); + config.mIsAutoJoinEnabled = in.readBoolean(); return config; } diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index d58083c92df6..d91efbccc2de 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -181,6 +181,11 @@ public class BaseWifiService extends IWifiManager.Stub { throw new UnsupportedOperationException(); } + @Override + public void allowAutojoinPasspoint(String fqdn, boolean enableAutoJoin) { + throw new UnsupportedOperationException(); + } + @Override public boolean startScan(String packageName, String featureId) { throw new UnsupportedOperationException(); diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index f9bd31d57ffc..5ac50a0d1c97 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -1672,9 +1672,21 @@ public class WifiManagerTest { @Test public void testAllowAutojoin() throws Exception { mWifiManager.allowAutojoin(1, true); - verify(mWifiService).allowAutojoin(eq(1), eq(true)); + verify(mWifiService).allowAutojoin(1, true); } + /** + * Test behavior of {@link WifiManager#allowAutojoinPasspoint(String, boolean)} + * @throws Exception + */ + @Test + public void testAllowAutojoinPasspoint() throws Exception { + final String fqdn = "FullyQualifiedDomainName"; + mWifiManager.allowAutojoinPasspoint(fqdn, true); + verify(mWifiService).allowAutojoinPasspoint(fqdn, true); + } + + /** * Test behavior of {@link WifiManager#disconnect()} */ diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java index f501b16d2c79..94054fdde8da 100644 --- a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java @@ -171,6 +171,7 @@ public class PasspointConfigurationTest { assertFalse(config.validate()); assertFalse(config.validateForR2()); + assertTrue(config.isAutoJoinEnabled()); } /** -- cgit v1.2.3 From c81df3f859afc36fa0726d38be222767aa6d8767 Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Mon, 6 Jan 2020 13:30:59 +0900 Subject: Platform shouldn't directly link to jars in APEXes The non-updatable part of the platform shouldn't directly link to the boot jars in APEXes. Ensure this by 1) setting the visibility property for the boot jars so that they are not visible to non-APEX modules and 2) setting the apex_available property so that the boot jars are only built for the corresponding APEXes, but not for others. Bug: b/146167933 Bug: b/146218515 Bug: b/147200698 Test: m Change-Id: I251fabd773bc31f46d572d143c72dd9162f3f0a6 --- wifi/Android.bp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 09d5386dcfc5..180368cbd9f7 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -67,10 +67,15 @@ java_library { optimize: { enabled: false }, + hostdex: true, // for hiddenapi check visibility: [ "//frameworks/base", // TODO(b/140299412) remove once all dependencies are fixed "//frameworks/opt/net/wifi/service:__subpackages__", ] + test_access_hidden_api_whitelist, + apex_available: [ + "com.android.wifi", + "test_com.android.wifi", + ], plugins: ["java_api_finder"], } -- cgit v1.2.3 From 7888cc304cd0f248dd627f6fef83ad0baebae154 Mon Sep 17 00:00:00 2001 From: "Nate(Qiang) Jiang" Date: Wed, 18 Dec 2019 11:14:28 -0800 Subject: show suggestion in Wifi picker Add API to get matched suggestion for given scanResults Bug: 146423406 Test: atest android.net.wifi Change-Id: Id2a6a7406498ddb281b1113c612ae076216e4f1e --- wifi/java/android/net/wifi/IWifiManager.aidl | 2 ++ wifi/java/android/net/wifi/WifiManager.java | 30 ++++++++++++++++++++++ .../com/android/server/wifi/BaseWifiService.java | 6 +++++ .../src/android/net/wifi/WifiManagerTest.java | 14 ++++++++++ 4 files changed, 52 insertions(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 71942f0f80f4..f490766559de 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -250,4 +250,6 @@ interface IWifiManager void unregisterSuggestionConnectionStatusListener(int listenerIdentifier, String packageName); int calculateSignalLevel(int rssi); + + List getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(in List scanResults); } diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index e870481ccf26..1baab12b8ab5 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1365,6 +1365,36 @@ public class WifiManager { return configs; } + /** + * Retrieve a list of {@link WifiConfiguration} for available {@link WifiNetworkSuggestion} + * matching the given list of {@link ScanResult}. + * + * An available {@link WifiNetworkSuggestion} must satisfy: + *

      + *
    • Matching one of the {@link ScanResult} from the given list. + *
    • and {@link WifiNetworkSuggestion.Builder#setIsUserAllowedToManuallyConnect(boolean)} set + * to true. + *
    + * + * @param scanResults a list of scanResult. + * @return a list of @link WifiConfiguration} for available {@link WifiNetworkSuggestion} + * @hide + */ + @SystemApi + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_SETTINGS, + android.Manifest.permission.NETWORK_SETUP_WIZARD + }) + @NonNull + public List getWifiConfigForMatchedNetworkSuggestionsSharedWithUser( + @NonNull List scanResults) { + try { + return mService.getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(scanResults); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + } + /** * Returns a list of unique Hotspot 2.0 OSU (Online Sign-Up) providers associated with a given * list of ScanResult. diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index d91efbccc2de..3c13562d6952 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -589,4 +589,10 @@ public class BaseWifiService extends IWifiManager.Stub { public int calculateSignalLevel(int rssi) { throw new UnsupportedOperationException(); } + + @Override + public List getWifiConfigForMatchedNetworkSuggestionsSharedWithUser( + List scanResults) { + throw new UnsupportedOperationException(); + } } diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 5ac50a0d1c97..4b837184dc9a 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -2185,4 +2185,18 @@ public class WifiManagerTest { result = WifiManager.parseDppChannelList(channelList); assertEquals(result.size(), 0); } + + /** + * Test getWifiConfigsForMatchedNetworkSuggestions for given scanResults. + */ + @Test + public void testGetWifiConfigsForMatchedNetworkSuggestions() throws Exception { + List testResults = new ArrayList<>(); + testResults.add(new WifiConfiguration()); + + when(mWifiService.getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(any(List.class))) + .thenReturn(testResults); + assertEquals(testResults, mWifiManager + .getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(new ArrayList<>())); + } } -- cgit v1.2.3 From 51cf9107de1e20398434153f8fc316f53f0cde64 Mon Sep 17 00:00:00 2001 From: lesl Date: Fri, 27 Dec 2019 17:50:51 +0800 Subject: softap: Add TimeoutDelay in SoftApConfiguration. 1. Add customize TimeoutDelay Bug: 142752869 Test: atest frameworks/base/wifi/tests/ Change-Id: I17552e87b7a3618f32885ff18cba5d11f8c9d45d --- .../java/android/net/wifi/SoftApConfiguration.java | 58 ++++++++++++++++++++-- .../android/net/wifi/SoftApConfigurationTest.java | 8 +++ 2 files changed, 61 insertions(+), 5 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java index 65e9b7910e5e..945a23605b74 100644 --- a/wifi/java/android/net/wifi/SoftApConfiguration.java +++ b/wifi/java/android/net/wifi/SoftApConfiguration.java @@ -181,6 +181,12 @@ public final class SoftApConfiguration implements Parcelable { */ private final @SecurityType int mSecurityType; + /** + * Delay in milliseconds before shutting down soft AP when + * there are no connected devices. + */ + private final int mShutdownTimeoutMillis; + /** * Security types we support. */ @@ -213,7 +219,7 @@ public final class SoftApConfiguration implements Parcelable { /** Private constructor for Builder and Parcelable implementation. */ private SoftApConfiguration(@Nullable String ssid, @Nullable MacAddress bssid, @Nullable String passphrase, boolean hiddenSsid, @BandType int band, int channel, - @SecurityType int securityType, int maxNumberOfClients) { + @SecurityType int securityType, int maxNumberOfClients, int shutdownTimeoutMillis) { mSsid = ssid; mBssid = bssid; mPassphrase = passphrase; @@ -222,6 +228,7 @@ public final class SoftApConfiguration implements Parcelable { mChannel = channel; mSecurityType = securityType; mMaxNumberOfClients = maxNumberOfClients; + mShutdownTimeoutMillis = shutdownTimeoutMillis; } @Override @@ -240,13 +247,14 @@ public final class SoftApConfiguration implements Parcelable { && mBand == other.mBand && mChannel == other.mChannel && mSecurityType == other.mSecurityType - && mMaxNumberOfClients == other.mMaxNumberOfClients; + && mMaxNumberOfClients == other.mMaxNumberOfClients + && mShutdownTimeoutMillis == other.mShutdownTimeoutMillis; } @Override public int hashCode() { return Objects.hash(mSsid, mBssid, mPassphrase, mHiddenSsid, - mBand, mChannel, mSecurityType, mMaxNumberOfClients); + mBand, mChannel, mSecurityType, mMaxNumberOfClients, mShutdownTimeoutMillis); } @Override @@ -261,6 +269,7 @@ public final class SoftApConfiguration implements Parcelable { sbuf.append(" \n Channel =").append(mChannel); sbuf.append(" \n SecurityType=").append(getSecurityType()); sbuf.append(" \n MaxClient=").append(mMaxNumberOfClients); + sbuf.append(" \n ShutdownTimeoutMillis=").append(mShutdownTimeoutMillis); return sbuf.toString(); } @@ -274,6 +283,7 @@ public final class SoftApConfiguration implements Parcelable { dest.writeInt(mChannel); dest.writeInt(mSecurityType); dest.writeInt(mMaxNumberOfClients); + dest.writeInt(mShutdownTimeoutMillis); } @Override @@ -289,7 +299,7 @@ public final class SoftApConfiguration implements Parcelable { in.readString(), in.readParcelable(MacAddress.class.getClassLoader()), in.readString(), in.readBoolean(), in.readInt(), in.readInt(), in.readInt(), - in.readInt()); + in.readInt(), in.readInt()); } @Override @@ -380,6 +390,15 @@ public final class SoftApConfiguration implements Parcelable { return mMaxNumberOfClients; } + /** + * Returns the shutdown timeout in milliseconds. + * The Soft AP will shutdown when there are no devices associated to it for + * the timeout duration. See {@link Builder#setShutdownTimeoutMillis(int)}. + */ + public int getShutdownTimeoutMillis() { + return mShutdownTimeoutMillis; + } + /** * Builds a {@link SoftApConfiguration}, which allows an app to configure various aspects of a * Soft AP. @@ -396,6 +415,7 @@ public final class SoftApConfiguration implements Parcelable { private int mChannel; private int mMaxNumberOfClients; private int mSecurityType; + private int mShutdownTimeoutMillis; /** * Constructs a Builder with default values (see {@link Builder}). @@ -409,6 +429,7 @@ public final class SoftApConfiguration implements Parcelable { mChannel = 0; mMaxNumberOfClients = 0; mSecurityType = SECURITY_TYPE_OPEN; + mShutdownTimeoutMillis = 0; } /** @@ -425,6 +446,7 @@ public final class SoftApConfiguration implements Parcelable { mChannel = other.mChannel; mMaxNumberOfClients = other.mMaxNumberOfClients; mSecurityType = other.mSecurityType; + mShutdownTimeoutMillis = other.mShutdownTimeoutMillis; } /** @@ -435,7 +457,8 @@ public final class SoftApConfiguration implements Parcelable { @NonNull public SoftApConfiguration build() { return new SoftApConfiguration(mSsid, mBssid, mPassphrase, - mHiddenSsid, mBand, mChannel, mSecurityType, mMaxNumberOfClients); + mHiddenSsid, mBand, mChannel, mSecurityType, mMaxNumberOfClients, + mShutdownTimeoutMillis); } /** @@ -643,5 +666,30 @@ public final class SoftApConfiguration implements Parcelable { mMaxNumberOfClients = maxNumberOfClients; return this; } + + /** + * Specifies the shutdown timeout in milliseconds. + * The Soft AP will shut down when there are no devices connected to it for + * the timeout duration. + * + * Specify a value of 0 to have the framework automatically use default timeout + * setting which defined in {@link R.integer.config_wifi_framework_soft_ap_timeout_delay} + * + *

    + *

  • If not set, defaults to 0
  • + *
  • The shut down timout will apply when + * {@link Settings.Global.SOFT_AP_TIMEOUT_ENABLED} is true
  • + * + * @param timeoutMillis milliseconds of the timeout delay. + * @return Builder for chaining. + */ + @NonNull + public Builder setShutdownTimeoutMillis(int timeoutMillis) { + if (timeoutMillis < 0) { + throw new IllegalArgumentException("Invalid timeout value"); + } + mShutdownTimeoutMillis = timeoutMillis; + return this; + } } } diff --git a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java index acd334355806..eeea7e2a6cd8 100644 --- a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java @@ -117,6 +117,7 @@ public class SoftApConfigurationTest { .setChannel(149, SoftApConfiguration.BAND_5GHZ) .setHiddenSsid(true) .setMaxNumberOfClients(10) + .setShutdownTimeoutMillis(500000) .build(); assertThat(original.getPassphrase()).isEqualTo("secretsecret"); assertThat(original.getSecurityType()).isEqualTo( @@ -125,6 +126,7 @@ public class SoftApConfigurationTest { assertThat(original.getChannel()).isEqualTo(149); assertThat(original.isHiddenSsid()).isEqualTo(true); assertThat(original.getMaxNumberOfClients()).isEqualTo(10); + assertThat(original.getShutdownTimeoutMillis()).isEqualTo(500000); SoftApConfiguration unparceled = parcelUnparcel(original); assertThat(unparceled).isNotSameAs(original); @@ -230,4 +232,10 @@ public class SoftApConfigurationTest { .build(); } + @Test(expected = IllegalArgumentException.class) + public void testInvalieShutdownTimeoutMillis() { + SoftApConfiguration original = new SoftApConfiguration.Builder() + .setShutdownTimeoutMillis(-1) + .build(); + } } -- cgit v1.2.3 From 0a3011e505c33b5d66b9346501047e4e02dae13e Mon Sep 17 00:00:00 2001 From: lesl Date: Thu, 9 Jan 2020 19:13:46 +0800 Subject: softap: remove set/getWpa2Passphrase It can be replaced by set/getPassphrase Bug: 142752869 Test: atest frameworks/base/wifi/tests/ Change-Id: I58af7ba041f4f100e55eab9132d3eea8e15a7da6 --- .../java/android/net/wifi/SoftApConfiguration.java | 29 ---------------------- 1 file changed, 29 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java index 945a23605b74..2b7f8af728d7 100644 --- a/wifi/java/android/net/wifi/SoftApConfiguration.java +++ b/wifi/java/android/net/wifi/SoftApConfiguration.java @@ -326,19 +326,6 @@ public final class SoftApConfiguration implements Parcelable { return mBssid; } - // TODO: Remove it after update the caller - /** - * Returns String set to be passphrase for the WPA2-PSK AP. - * {@link #setWpa2Passphrase(String)}. - */ - @Nullable - public String getWpa2Passphrase() { - if (mSecurityType == SECURITY_TYPE_WPA2_PSK) { - return mPassphrase; - } - return null; - } - /** * Returns String set to be passphrase for current AP. * {@link #setPassphrase(String, @SecurityType int)}. @@ -505,22 +492,6 @@ public final class SoftApConfiguration implements Parcelable { return this; } - // TODO: Remove it after update the caller - /** - * Specifies that this AP should use WPA2-PSK with the given ASCII WPA2 passphrase. - * When set to null, an open network is created. - *

    - * - * @param passphrase The passphrase to use, or null to unset a previously-set WPA2-PSK - * configuration. - * @return Builder for chaining. - * @throws IllegalArgumentException when the passphrase is the empty string - */ - @NonNull - public Builder setWpa2Passphrase(@Nullable String passphrase) { - return setPassphrase(passphrase, SECURITY_TYPE_WPA2_PSK); - } - /** * Specifies that this AP should use specific security type with the given ASCII passphrase. * -- cgit v1.2.3 From d26a9f75ee5e250da136c77a9e10a8a26e7792bb Mon Sep 17 00:00:00 2001 From: lesl Date: Fri, 3 Jan 2020 17:50:06 +0800 Subject: softap: Add blocked/allowed client list support Bug: 142752869 Test: atest frameworks/base/wifi/tests/ Test: Manuel test, enable softap with feature enable. check client connect log and use test code to simulate the real use case. Change-Id: I05b0c0d376ec8437556a66e372c2693b5ce5f266 --- wifi/java/android/net/wifi/ISoftApCallback.aidl | 10 +- .../java/android/net/wifi/SoftApConfiguration.java | 161 ++++++++++++++++++++- wifi/java/android/net/wifi/WifiManager.java | 77 +++++++++- .../android/net/wifi/SoftApConfigurationTest.java | 24 +++ .../src/android/net/wifi/WifiManagerTest.java | 20 +++ 5 files changed, 283 insertions(+), 9 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/ISoftApCallback.aidl b/wifi/java/android/net/wifi/ISoftApCallback.aidl index 482b4910921d..f81bcb9e06d7 100644 --- a/wifi/java/android/net/wifi/ISoftApCallback.aidl +++ b/wifi/java/android/net/wifi/ISoftApCallback.aidl @@ -55,9 +55,17 @@ oneway interface ISoftApCallback /** - * Service to manager callback providing information of softap. + * Service to manager callback providing capability of softap. * * @param capability is the softap capability. {@link SoftApCapability} */ void onCapabilityChanged(in SoftApCapability capability); + + /** + * Service to manager callback providing blocked client of softap with specific reason code. + * + * @param client the currently blocked client. + * @param blockedReason one of blocked reason from {@link WifiManager.SapClientBlockedReason} + */ + void onBlockedClientConnecting(in WifiClient client, int blockedReason); } diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java index 2b7f8af728d7..a77d30a18817 100644 --- a/wifi/java/android/net/wifi/SoftApConfiguration.java +++ b/wifi/java/android/net/wifi/SoftApConfiguration.java @@ -32,6 +32,9 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.nio.charset.CharsetEncoder; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; import java.util.Objects; import java.util.concurrent.Executor; @@ -181,6 +184,22 @@ public final class SoftApConfiguration implements Parcelable { */ private final @SecurityType int mSecurityType; + /** + * The flag to indicate client need to authorize by user + * when client is connecting to AP. + */ + private final boolean mClientControlByUser; + + /** + * The list of blocked client that can't associate to the AP. + */ + private final List mBlockedClientList; + + /** + * The list of allowed client that can associate to the AP. + */ + private final List mAllowedClientList; + /** * Delay in milliseconds before shutting down soft AP when * there are no connected devices. @@ -219,7 +238,9 @@ public final class SoftApConfiguration implements Parcelable { /** Private constructor for Builder and Parcelable implementation. */ private SoftApConfiguration(@Nullable String ssid, @Nullable MacAddress bssid, @Nullable String passphrase, boolean hiddenSsid, @BandType int band, int channel, - @SecurityType int securityType, int maxNumberOfClients, int shutdownTimeoutMillis) { + @SecurityType int securityType, int maxNumberOfClients, int shutdownTimeoutMillis, + boolean clientControlByUser, @NonNull List blockedList, + @NonNull List allowedList) { mSsid = ssid; mBssid = bssid; mPassphrase = passphrase; @@ -229,6 +250,9 @@ public final class SoftApConfiguration implements Parcelable { mSecurityType = securityType; mMaxNumberOfClients = maxNumberOfClients; mShutdownTimeoutMillis = shutdownTimeoutMillis; + mClientControlByUser = clientControlByUser; + mBlockedClientList = new ArrayList<>(blockedList); + mAllowedClientList = new ArrayList<>(allowedList); } @Override @@ -248,13 +272,17 @@ public final class SoftApConfiguration implements Parcelable { && mChannel == other.mChannel && mSecurityType == other.mSecurityType && mMaxNumberOfClients == other.mMaxNumberOfClients - && mShutdownTimeoutMillis == other.mShutdownTimeoutMillis; + && mShutdownTimeoutMillis == other.mShutdownTimeoutMillis + && mClientControlByUser == other.mClientControlByUser + && Objects.equals(mBlockedClientList, other.mBlockedClientList) + && Objects.equals(mAllowedClientList, other.mAllowedClientList); } @Override public int hashCode() { return Objects.hash(mSsid, mBssid, mPassphrase, mHiddenSsid, - mBand, mChannel, mSecurityType, mMaxNumberOfClients, mShutdownTimeoutMillis); + mBand, mChannel, mSecurityType, mMaxNumberOfClients, mShutdownTimeoutMillis, + mClientControlByUser, mBlockedClientList, mAllowedClientList); } @Override @@ -270,6 +298,9 @@ public final class SoftApConfiguration implements Parcelable { sbuf.append(" \n SecurityType=").append(getSecurityType()); sbuf.append(" \n MaxClient=").append(mMaxNumberOfClients); sbuf.append(" \n ShutdownTimeoutMillis=").append(mShutdownTimeoutMillis); + sbuf.append(" \n ClientControlByUser=").append(mClientControlByUser); + sbuf.append(" \n BlockedClientList=").append(mBlockedClientList); + sbuf.append(" \n AllowedClientList=").append(mAllowedClientList); return sbuf.toString(); } @@ -284,6 +315,9 @@ public final class SoftApConfiguration implements Parcelable { dest.writeInt(mSecurityType); dest.writeInt(mMaxNumberOfClients); dest.writeInt(mShutdownTimeoutMillis); + dest.writeBoolean(mClientControlByUser); + dest.writeTypedList(mBlockedClientList); + dest.writeTypedList(mAllowedClientList); } @Override @@ -299,7 +333,9 @@ public final class SoftApConfiguration implements Parcelable { in.readString(), in.readParcelable(MacAddress.class.getClassLoader()), in.readString(), in.readBoolean(), in.readInt(), in.readInt(), in.readInt(), - in.readInt(), in.readInt()); + in.readInt(), in.readInt(), in.readBoolean(), + in.createTypedArrayList(MacAddress.CREATOR), + in.createTypedArrayList(MacAddress.CREATOR)); } @Override @@ -386,6 +422,34 @@ public final class SoftApConfiguration implements Parcelable { return mShutdownTimeoutMillis; } + /** + * Returns a flag indicating whether clients need to be pre-approved by the user. + * (true: authorization required) or not (false: not required). + * {@link Builder#enableClientControlByUser(Boolean)}. + */ + public boolean isClientControlByUserEnabled() { + return mClientControlByUser; + } + + /** + * Returns List of clients which aren't allowed to associate to the AP. + * + * Clients are configured using {@link Builder#setClientList(List, List)} + */ + @NonNull + public List getBlockedClientList() { + return mBlockedClientList; + } + + /** + * List of clients which are allowed to associate to the AP. + * Clients are configured using {@link Builder#setClientList(List, List)} + */ + @NonNull + public List getAllowedClientList() { + return mAllowedClientList; + } + /** * Builds a {@link SoftApConfiguration}, which allows an app to configure various aspects of a * Soft AP. @@ -403,6 +467,9 @@ public final class SoftApConfiguration implements Parcelable { private int mMaxNumberOfClients; private int mSecurityType; private int mShutdownTimeoutMillis; + private boolean mClientControlByUser; + private List mBlockedClientList; + private List mAllowedClientList; /** * Constructs a Builder with default values (see {@link Builder}). @@ -417,6 +484,9 @@ public final class SoftApConfiguration implements Parcelable { mMaxNumberOfClients = 0; mSecurityType = SECURITY_TYPE_OPEN; mShutdownTimeoutMillis = 0; + mClientControlByUser = false; + mBlockedClientList = new ArrayList<>(); + mAllowedClientList = new ArrayList<>(); } /** @@ -434,6 +504,9 @@ public final class SoftApConfiguration implements Parcelable { mMaxNumberOfClients = other.mMaxNumberOfClients; mSecurityType = other.mSecurityType; mShutdownTimeoutMillis = other.mShutdownTimeoutMillis; + mClientControlByUser = other.mClientControlByUser; + mBlockedClientList = new ArrayList<>(other.mBlockedClientList); + mAllowedClientList = new ArrayList<>(other.mAllowedClientList); } /** @@ -445,7 +518,8 @@ public final class SoftApConfiguration implements Parcelable { public SoftApConfiguration build() { return new SoftApConfiguration(mSsid, mBssid, mPassphrase, mHiddenSsid, mBand, mChannel, mSecurityType, mMaxNumberOfClients, - mShutdownTimeoutMillis); + mShutdownTimeoutMillis, mClientControlByUser, mBlockedClientList, + mAllowedClientList); } /** @@ -662,5 +736,82 @@ public final class SoftApConfiguration implements Parcelable { mShutdownTimeoutMillis = timeoutMillis; return this; } + + /** + * Configure the Soft AP to require manual user control of client association. + * If disabled (the default) then any client can associate to this Soft AP using the + * correct credentials until the Soft AP capacity is reached (capacity is hardware, carrier, + * or user limited - using {@link #setMaxNumberOfClients(int)}). + * + * If manual user control is enabled then clients will be accepted, rejected, or require + * a user approval based on the configuration provided by + * {@link #setClientList(List, List)}. + * + *

    + * This method requires hardware support. Hardware support can be determined using + * {@link WifiManager.SoftApCallback#onCapabilityChanged(SoftApCapability)} and + * {@link SoftApCapability#isFeatureSupported(int)} + * with {@link SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT} + * + *

    + * If the method is called on a device without hardware support then starting the soft AP + * using {@link WifiManager#startTetheredHotspot(SoftApConfiguration)} will fail with + * {@link WifiManager#SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION}. + * + *

    + *

  • If not set, defaults to false (i.e The authoriztion is not required).
  • + * + * @param enabled true for enabling the control by user, false otherwise. + * @return Builder for chaining. + */ + @NonNull + public Builder enableClientControlByUser(boolean enabled) { + mClientControlByUser = enabled; + return this; + } + + + /** + * This method together with {@link enableClientControlByUser(boolean)} control client + * connections to the AP. If {@link enableClientControlByUser(false)} is configured than + * this API has no effect and clients are allowed to associate to the AP (within limit of + * max number of clients). + * + * If {@link enableClientControlByUser(true)} is configured then this API configures + * 2 lists: + *
      + *
    • List of clients which are blocked. These are rejected.
    • + *
    • List of clients which are explicitly allowed. These are auto-accepted.
    • + *
    + * + *

    + * All other clients which attempt to associate, whose MAC addresses are on neither list, + * are: + *

      + *
    • Rejected
    • + *
    • A callback {@link WifiManager.SoftApCallback#onBlockedClientConnecting(WifiClient)} + * is issued (which allows the user to add them to the allowed client list if desired).
    • + *
    + * + * @param blockedClientList list of clients which are not allowed to associate to the AP. + * @param allowedClientList list of clients which are allowed to associate to the AP + * without user pre-approval. + * @return Builder for chaining. + */ + @NonNull + public Builder setClientList(@NonNull List blockedClientList, + @NonNull List allowedClientList) { + mBlockedClientList = new ArrayList<>(blockedClientList); + mAllowedClientList = new ArrayList<>(allowedClientList); + Iterator iterator = mAllowedClientList.iterator(); + while (iterator.hasNext()) { + MacAddress client = iterator.next(); + int index = mBlockedClientList.indexOf(client); + if (index != -1) { + throw new IllegalArgumentException("A MacAddress exist in both list"); + } + } + return this; + } } } diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 1baab12b8ab5..729ac14b8b73 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -666,7 +666,8 @@ public class WifiManager { public @interface SapStartFailure {} /** - * All other reasons for AP start failure besides {@link #SAP_START_FAILURE_NO_CHANNEL}. + * All other reasons for AP start failure besides {@link #SAP_START_FAILURE_NO_CHANNEL} and + * {@link #SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION}. * * @hide */ @@ -691,6 +692,37 @@ public class WifiManager { @SystemApi public static final int SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION = 2; + + /** @hide */ + @IntDef(flag = false, prefix = { "SAP_CLIENT_BLOCKED_REASON_" }, value = { + SAP_CLIENT_BLOCK_REASON_CODE_BLOCKED_BY_USER, + SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface SapClientBlockedReason {} + + /** + * If Soft Ap client is blocked, this reason code means that client doesn't exist in the + * specified configuration {@link SoftApConfiguration.Builder#setClientList(List, List)} + * and the {@link SoftApConfiguration.Builder#enableClientControlByUser(true)} + * is configured as well. + * @hide + */ + @SystemApi + public static final int SAP_CLIENT_BLOCK_REASON_CODE_BLOCKED_BY_USER = 0; + + /** + * If Soft Ap client is blocked, this reason code means that no more clients can be + * associated to this AP since it reached maximum capacity. The maximum capacity is + * the minimum of {@link SoftApConfiguration.Builder#setMaxNumberOfClients(int)} and + * {@link SoftApCapability#getMaxSupportedClients} which get from + * {@link WifiManager.SoftApCallback#onCapabilityChanged(SoftApCapability)}. + * + * @hide + */ + @SystemApi + public static final int SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS = 1; + /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = {"IFACE_IP_MODE_"}, value = { @@ -3229,8 +3261,17 @@ public class WifiManager { /** * Sets the Wi-Fi AP Configuration. * + * If the API is called while the soft AP is enabled, the configuration will apply to + * the current soft AP if the new configuration only includes + * {@link SoftApConfiguration.Builder#setMaxNumberOfClients(int)} + * or {@link SoftApConfiguration.Builder#setShutdownTimeoutMillis(int)} + * or {@link SoftApConfiguration.Builder#enableClientControlByUser(boolean)} + * or {@link SoftApConfiguration.Builder#setClientList(List, List)}. + * + * Otherwise, the configuration changes will be applied when the Soft AP is next started + * (the framework will not stop/start the AP). + * * @param softApConfig A valid SoftApConfiguration specifying the configuration of the SAP. - * @return {@code true} if the operation succeeded, {@code false} otherwise * * @hide @@ -3460,7 +3501,8 @@ public class WifiManager { * {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED} * @param failureReason reason when in failed state. One of * {@link #SAP_START_FAILURE_GENERAL}, - * {@link #SAP_START_FAILURE_NO_CHANNEL} + * {@link #SAP_START_FAILURE_NO_CHANNEL}, + * {@link #SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION} */ default void onStateChanged(@WifiApState int state, @SapStartFailure int failureReason) {} @@ -3489,6 +3531,22 @@ public class WifiManager { // Do nothing: can be updated to add SoftApCapability details (e.g. meximum supported // client number) to the UI. } + + /** + * Called when client trying to connect but device blocked the client with specific reason. + * + * Can be used to ask user to update client to allowed list or blocked list + * when reason is {@link SAP_CLIENT_BLOCK_REASON_CODE_BLOCKED_BY_USER}, or + * indicate the block due to maximum supported client number limitation when reason is + * {@link SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS}. + * + * @param client the currently blocked client. + * @param blockedReason one of blocked reason from {@link SapClientBlockedReason} + */ + default void onBlockedClientConnecting(@NonNull WifiClient client, + @SapClientBlockedReason int blockedReason) { + // Do nothing: can be used to ask user to update client to allowed list or blocked list. + } } /** @@ -3555,6 +3613,19 @@ public class WifiManager { mCallback.onCapabilityChanged(capability); }); } + + @Override + public void onBlockedClientConnecting(@NonNull WifiClient client, int blockedReason) { + if (mVerboseLoggingEnabled) { + Log.v(TAG, "SoftApCallbackProxy: onBlockedClientConnecting: client=" + client + + " with reason = " + blockedReason); + } + + Binder.clearCallingIdentity(); + mExecutor.execute(() -> { + mCallback.onBlockedClientConnecting(client, blockedReason); + }); + } } /** diff --git a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java index eeea7e2a6cd8..6884a4ede27a 100644 --- a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java @@ -25,6 +25,8 @@ import androidx.test.filters.SmallTest; import org.junit.Test; +import java.util.ArrayList; +import java.util.List; import java.util.Random; @SmallTest @@ -112,12 +114,18 @@ public class SoftApConfigurationTest { @Test public void testWpa2WithAllFieldCustomized() { + List testBlockedClientList = new ArrayList<>(); + List testAllowedClientList = new ArrayList<>(); + testBlockedClientList.add(MacAddress.fromString("11:22:33:44:55:66")); + testAllowedClientList.add(MacAddress.fromString("aa:bb:cc:dd:ee:ff")); SoftApConfiguration original = new SoftApConfiguration.Builder() .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) .setChannel(149, SoftApConfiguration.BAND_5GHZ) .setHiddenSsid(true) .setMaxNumberOfClients(10) .setShutdownTimeoutMillis(500000) + .enableClientControlByUser(true) + .setClientList(testBlockedClientList, testAllowedClientList) .build(); assertThat(original.getPassphrase()).isEqualTo("secretsecret"); assertThat(original.getSecurityType()).isEqualTo( @@ -127,6 +135,9 @@ public class SoftApConfigurationTest { assertThat(original.isHiddenSsid()).isEqualTo(true); assertThat(original.getMaxNumberOfClients()).isEqualTo(10); assertThat(original.getShutdownTimeoutMillis()).isEqualTo(500000); + assertThat(original.isClientControlByUserEnabled()).isEqualTo(true); + assertThat(original.getBlockedClientList()).isEqualTo(testBlockedClientList); + assertThat(original.getAllowedClientList()).isEqualTo(testAllowedClientList); SoftApConfiguration unparceled = parcelUnparcel(original); assertThat(unparceled).isNotSameAs(original); @@ -238,4 +249,17 @@ public class SoftApConfigurationTest { .setShutdownTimeoutMillis(-1) .build(); } + + @Test(expected = IllegalArgumentException.class) + public void testsetClientListExceptionWhenExistMacAddressInBothList() { + final MacAddress testMacAddress_1 = MacAddress.fromString("22:33:44:55:66:77"); + final MacAddress testMacAddress_2 = MacAddress.fromString("aa:bb:cc:dd:ee:ff"); + ArrayList testAllowedClientList = new ArrayList<>(); + testAllowedClientList.add(testMacAddress_1); + testAllowedClientList.add(testMacAddress_2); + ArrayList testBlockedClientList = new ArrayList<>(); + testBlockedClientList.add(testMacAddress_1); + SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder(); + configBuilder.setClientList(testBlockedClientList, testAllowedClientList); + } } diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 4b837184dc9a..5bdc34402cc4 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -70,6 +70,7 @@ import android.app.ActivityManager; import android.content.Context; import android.content.pm.ApplicationInfo; import android.net.DhcpInfo; +import android.net.MacAddress; import android.net.wifi.WifiManager.LocalOnlyHotspotCallback; import android.net.wifi.WifiManager.LocalOnlyHotspotObserver; import android.net.wifi.WifiManager.LocalOnlyHotspotReservation; @@ -896,6 +897,25 @@ public class WifiManagerTest { verify(mSoftApCallback).onCapabilityChanged(testSoftApCapability); } + /* + * Verify client-provided callback is being called through callback proxy + */ + @Test + public void softApCallbackProxyCallsOnBlockedClientConnecting() throws Exception { + WifiClient testWifiClient = new WifiClient(MacAddress.fromString("22:33:44:55:66:77")); + ArgumentCaptor callbackCaptor = + ArgumentCaptor.forClass(ISoftApCallback.Stub.class); + mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); + verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(), + anyInt()); + + callbackCaptor.getValue().onBlockedClientConnecting(testWifiClient, + WifiManager.SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS); + mLooper.dispatchAll(); + verify(mSoftApCallback).onBlockedClientConnecting(testWifiClient, + WifiManager.SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS); + } + /* * Verify client-provided callback is being called through callback proxy on multiple events */ -- cgit v1.2.3 From 2f8fec07b9c423799ea0ed2602014908970137d2 Mon Sep 17 00:00:00 2001 From: "Nate(Qiang) Jiang" Date: Fri, 10 Jan 2020 09:47:36 -0800 Subject: Rename API setIsUserAllowedToManuallyConnect to setCredentialSharedWithUser Bug: 146423406 Test: atest android.net.wifi Change-Id: I699b8e48e009d82a5a1cd237dca7c5b1ec54f0f2 --- .../android/net/wifi/WifiNetworkSuggestion.java | 26 +++++++++++----------- .../net/wifi/WifiNetworkSuggestionTest.java | 8 +++---- 2 files changed, 17 insertions(+), 17 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java index 9c1475ffc8cd..c0e089090dc9 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java +++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java @@ -116,12 +116,12 @@ public final class WifiNetworkSuggestion implements Parcelable { /** * Whether this network is shared credential with user to allow user manually connect. */ - private boolean mIsUserAllowed; + private boolean mIsSharedWithUser; /** - * Whether the setIsUserAllowedToManuallyConnect have been called. + * Whether the setCredentialSharedWithUser have been called. */ - private boolean mIsUserAllowedBeenSet; + private boolean mIsSharedWithUserSet; /** * Pre-shared key for use with WAPI-PSK networks. */ @@ -146,8 +146,8 @@ public final class WifiNetworkSuggestion implements Parcelable { mIsAppInteractionRequired = false; mIsUserInteractionRequired = false; mIsMetered = false; - mIsUserAllowed = true; - mIsUserAllowedBeenSet = false; + mIsSharedWithUser = true; + mIsSharedWithUserSet = false; mPriority = UNASSIGNED_PRIORITY; mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID; mWapiPskPassphrase = null; @@ -430,13 +430,13 @@ public final class WifiNetworkSuggestion implements Parcelable { *
  • If not set, defaults to true (i.e. allow user to manually connect) for secure * networks and false for open networks.
  • * - * @param isAllowed {@code true} to indicate that the credentials may be used by the user to + * @param isShared {@code true} to indicate that the credentials may be used by the user to * manually connect to the network, {@code false} otherwise. * @return Instance of {@link Builder} to enable chaining of the builder method. */ - public @NonNull Builder setIsUserAllowedToManuallyConnect(boolean isAllowed) { - mIsUserAllowed = isAllowed; - mIsUserAllowedBeenSet = true; + public @NonNull Builder setCredentialSharedWithUser(boolean isShared) { + mIsSharedWithUser = isShared; + mIsSharedWithUserSet = true; return this; } @@ -602,11 +602,11 @@ public final class WifiNetworkSuggestion implements Parcelable { } wifiConfiguration = buildWifiConfiguration(); if (wifiConfiguration.isOpenNetwork()) { - if (mIsUserAllowedBeenSet && mIsUserAllowed) { + if (mIsSharedWithUserSet && mIsSharedWithUser) { throw new IllegalStateException("Open network should not be " - + "setIsUserAllowedToManuallyConnect to true"); + + "setCredentialSharedWithUser to true"); } - mIsUserAllowed = false; + mIsSharedWithUser = false; } } @@ -615,7 +615,7 @@ public final class WifiNetworkSuggestion implements Parcelable { mPasspointConfiguration, mIsAppInteractionRequired, mIsUserInteractionRequired, - mIsUserAllowed); + mIsSharedWithUser); } } diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java index 4cdc4bc2ad48..ac915447f3c4 100644 --- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java +++ b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java @@ -76,7 +76,7 @@ public class WifiNetworkSuggestionTest { .setSsid(TEST_SSID) .setWpa2Passphrase(TEST_PRESHARED_KEY) .setIsAppInteractionRequired(true) - .setIsUserAllowedToManuallyConnect(false) + .setCredentialSharedWithUser(false) .setPriority(0) .build(); @@ -151,7 +151,7 @@ public class WifiNetworkSuggestionTest { WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() .setSsid(TEST_SSID) .setWpa3Passphrase(TEST_PRESHARED_KEY) - .setIsUserAllowedToManuallyConnect(true) + .setCredentialSharedWithUser(true) .build(); assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID); @@ -709,14 +709,14 @@ public class WifiNetworkSuggestionTest { /** * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception - * when {@link WifiNetworkSuggestion.Builder#setIsUserAllowedToManuallyConnect(boolean)} to + * when {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} to * true on a open network suggestion. */ @Test(expected = IllegalStateException.class) public void testSetIsUserAllowedToManuallyConnectToWithOpenNetwork() { WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() .setSsid(TEST_SSID) - .setIsUserAllowedToManuallyConnect(true) + .setCredentialSharedWithUser(true) .build(); } } -- cgit v1.2.3 From 9dc9affb96c2bf2703be4d942b70c71133420de4 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Thu, 9 Jan 2020 09:06:29 -0800 Subject: Add WifiOemConfigStoreMigrationHook class for OEM migration Add a helper class (not part of the wifi mainline module) to migrate config store data from existing OEM devices. This will be used when the device upgrades from a build containing OEM impl of wifi to a build containing wifi mainline module. OEM should implement this class if they had any non-AOSP changes in the config store format/field names on their devices. Bug: 142394776 Test: Compiles Change-Id: Ie11e0ffe8e4b8f1edcaa23d35284c3b564dc97f4 --- wifi/Android.bp | 1 + .../net/wifi/WifiOemConfigStoreMigrationHook.java | 180 +++++++++++++++++++++ 2 files changed, 181 insertions(+) create mode 100755 wifi/java/android/net/wifi/WifiOemConfigStoreMigrationHook.java (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 180368cbd9f7..286be0b82db7 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -32,6 +32,7 @@ filegroup { // framework-wifi.jar. This is not a good idea, should move WifiNetworkScoreCache // to a separate package. "java/android/net/wifi/WifiNetworkScoreCache.java", + "java/android/net/wifi/WifiOemConfigStoreMigrationHook.java", "java/android/net/wifi/wificond/*.java", ":libwificond_ipc_aidl", ], diff --git a/wifi/java/android/net/wifi/WifiOemConfigStoreMigrationHook.java b/wifi/java/android/net/wifi/WifiOemConfigStoreMigrationHook.java new file mode 100755 index 000000000000..642dcb9211ae --- /dev/null +++ b/wifi/java/android/net/wifi/WifiOemConfigStoreMigrationHook.java @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2020 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 com.android.internal.util.Preconditions.checkNotNull; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.List; + +/** + * Class used to provide one time hooks for existing OEM devices to migrate their config store + * data to the wifi mainline module. + *

    + * Note: + *

  • OEM's need to implement {@link #load()} only if their + * existing config store format or file locations differs from the vanilla AOSP implementation ( + * which is what the wifi mainline module understands). + *
  • + *
  • The wifi mainline module will invoke {@link #load()} method on every bootup, its + * the responsibility of the OEM implementation to ensure that this method returns non-null data + * only on the first bootup. Once the migration is done, the OEM can safely delete their config + * store files and then return null on any subsequent reboots. The first & only relevant invocation + * of {@link #load()} occurs when a previously released device upgrades to the wifi + * mainline module from an OEM implementation of the wifi stack. + *
  • + * @hide + */ +@SystemApi +public final class WifiOemConfigStoreMigrationHook { + /** + * Container for all the wifi config data to migrate. + */ + public static final class MigrationData implements Parcelable { + /** + * Builder to create instance of {@link MigrationData}. + */ + public static final class Builder { + private List mUserSavedNetworkConfigurations; + private SoftApConfiguration mUserSoftApConfiguration; + + public Builder() { + mUserSavedNetworkConfigurations = null; + mUserSoftApConfiguration = null; + } + + /** + * Sets the list of all user's saved network configurations parsed from OEM config + * store files. + * + * @param userSavedNetworkConfigurations List of {@link WifiConfiguration} representing + * the list of user's saved networks + * @return Instance of {@link Builder} to enable chaining of the builder method. + */ + public @NonNull Builder setUserSavedNetworkConfigurations( + @NonNull List userSavedNetworkConfigurations) { + checkNotNull(userSavedNetworkConfigurations); + mUserSavedNetworkConfigurations = userSavedNetworkConfigurations; + return this; + } + + /** + * Sets the user's softap configuration parsed from OEM config store files. + * + * @param userSoftApConfiguration {@link SoftApConfiguration} representing user's + * SoftAp configuration + * @return Instance of {@link Builder} to enable chaining of the builder method. + */ + public @NonNull Builder setUserSoftApConfiguration( + @NonNull SoftApConfiguration userSoftApConfiguration) { + checkNotNull(userSoftApConfiguration); + mUserSoftApConfiguration = userSoftApConfiguration; + return this; + } + + /** + * Build an instance of {@link MigrationData}. + * + * @return Instance of {@link MigrationData}. + */ + public @NonNull MigrationData build() { + return new MigrationData(mUserSavedNetworkConfigurations, mUserSoftApConfiguration); + } + } + + private final List mUserSavedNetworkConfigurations; + private final SoftApConfiguration mUserSoftApConfiguration; + + private MigrationData( + @Nullable List userSavedNetworkConfigurations, + @Nullable SoftApConfiguration userSoftApConfiguration) { + mUserSavedNetworkConfigurations = userSavedNetworkConfigurations; + mUserSoftApConfiguration = userSoftApConfiguration; + } + + public static final @NonNull Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @Override + public MigrationData createFromParcel(Parcel in) { + List userSavedNetworkConfigurations = + in.readArrayList(null); + SoftApConfiguration userSoftApConfiguration = in.readParcelable(null); + return new MigrationData( + userSavedNetworkConfigurations, userSoftApConfiguration); + } + + @Override + public MigrationData[] newArray(int size) { + return new MigrationData[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeList(mUserSavedNetworkConfigurations); + dest.writeParcelable(mUserSoftApConfiguration, flags); + } + + /** + * Returns list of all user's saved network configurations. + * + * Note: Only to be returned if there is any format change in how OEM persisted this info. + * @return List of {@link WifiConfiguration} representing the list of user's saved networks, + * or null if no migration necessary. + */ + @Nullable + public List getUserSavedNetworkConfigurations() { + return mUserSavedNetworkConfigurations; + } + + /** + * Returns user's softap configuration. + * + * Note: Only to be returned if there is any format change in how OEM persisted this info. + * @return {@link SoftApConfiguration} representing user's SoftAp configuration, + * or null if no migration necessary. + */ + @Nullable + public SoftApConfiguration getUserSoftApConfiguration() { + return mUserSoftApConfiguration; + } + } + + private WifiOemConfigStoreMigrationHook() { } + + /** + * Load data from OEM's config store. + * + * @return Instance of {@link MigrationData} for migrating data, null if no + * migration is necessary. + */ + @Nullable + public static MigrationData load() { + // Note: OEM's should add code to parse data from their config store format here! + return null; + } +} -- cgit v1.2.3 From 04d6cf41d23ade9bd06a7ca43a739d13c9d87eec Mon Sep 17 00:00:00 2001 From: David Su Date: Fri, 10 Jan 2020 13:18:59 -0800 Subject: Make WifiManager.ACTION_WIFI_SCAN_AVAILABLE public Make WifiManager.ACTION_WIFI_SCAN_AVAILABLE a public API so that it can be used by CTS. Bug: 144036594 Test: compiles Change-Id: I960fa13016b2a7913d1948449500e95316a87f95 --- wifi/java/android/net/wifi/WifiManager.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index e870481ccf26..65ad34acf89f 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -233,16 +233,20 @@ public class WifiManager { public @interface SuggestionConnectionStatusCode {} /** - * Broadcast intent action indicating whether Wi-Fi scanning is allowed currently - * @hide + * Broadcast intent action indicating whether Wi-Fi scanning is currently available. + * Available extras: + * - {@link #EXTRA_SCAN_AVAILABLE} */ - public static final String WIFI_SCAN_AVAILABLE = "wifi_scan_available"; + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_WIFI_SCAN_AVAILABLE = + "android.net.wifi.action.WIFI_SCAN_AVAILABLE"; /** - * Extra int indicating scan availability, WIFI_STATE_ENABLED and WIFI_STATE_DISABLED - * @hide + * A boolean extra indicating whether scanning is currently available. + * Sent in the broadcast {@link #ACTION_WIFI_SCAN_AVAILABLE}. + * Its value is true if scanning is currently available, false otherwise. */ - public static final String EXTRA_SCAN_AVAILABLE = "scan_enabled"; + public static final String EXTRA_SCAN_AVAILABLE = "android.net.wifi.extra.SCAN_AVAILABLE"; /** * Broadcast intent action indicating that the credential of a Wi-Fi network -- cgit v1.2.3 From 511a814a109169383f6aecad2ba86e4e5c770345 Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 9 Jan 2020 14:02:21 -0800 Subject: Jarjar utils into framework-wifi and share with wifi-service Jarjar utility classes used by both framework-wifi and wifi-service into framework-wifi and allow them to be referenced by wifi-service. Create framework-wifi-util-lib which contains utility classes that we will copy into the Wifi module. It is statically linked into framework-wifi and dynamically linked by wifi-service. Create framework-wifi-pre-jarjar to allow wifi-service to use the pre-rename symbols in framework-wifi-util-lib. In essence: 1. build framework-wifi-util-lib, framework-wifi-pre-jarjar, wifi-service-pre-jarjar using original symbol names. 2. rename everything afterwards at the same time. This ensures that all symbol names are consistent at each step in the build process. Bug: 142886292 Test: device boots up and connects to wifi Change-Id: I27b3519657d652787714b4b34de6cdbfef2a81e4 --- wifi/Android.bp | 29 ++++++++++++++++++++++++++++- wifi/jarjar-rules.txt | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 wifi/jarjar-rules.txt (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 286be0b82db7..a69803a435e2 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -52,10 +52,15 @@ test_access_hidden_api_whitelist = [ "//external/robolectric-shadows:__subpackages__", ] +// wifi-service needs pre-jarjared version of framework-wifi so it can reference copied utility +// classes before they are renamed. java_library { - name: "framework-wifi", + name: "framework-wifi-pre-jarjar", // TODO(b/140299412) should be core_current once we build against framework-system-stubs sdk_version: "core_platform", + static_libs: [ + "framework-wifi-util-lib", + ], libs: [ // TODO(b/140299412) should be framework-system-stubs once we fix all @hide dependencies "framework-minus-apex", @@ -64,6 +69,23 @@ java_library { srcs: [ ":framework-wifi-updatable-sources", ], + installable: false, + visibility: [ + "//frameworks/opt/net/wifi/service", + "//frameworks/opt/net/wifi/tests/wifitests", + ], +} + +// post-jarjar version of framework-wifi +java_library { + name: "framework-wifi", + // TODO(b/140299412) should be core_current once we build against framework-system-stubs + sdk_version: "core_platform", + static_libs: [ + "framework-wifi-pre-jarjar", + ], + jarjar_rules: ":wifi-jarjar-rules", + installable: true, optimize: { enabled: false @@ -122,3 +144,8 @@ java_defaults { ], visibility: test_access_hidden_api_whitelist, } + +filegroup { + name: "wifi-jarjar-rules", + srcs: ["jarjar-rules.txt"], +} diff --git a/wifi/jarjar-rules.txt b/wifi/jarjar-rules.txt new file mode 100644 index 000000000000..f0da1ec54080 --- /dev/null +++ b/wifi/jarjar-rules.txt @@ -0,0 +1,37 @@ +rule android.net.InterfaceConfigurationParcel* @0 +rule android.net.InterfaceConfiguration* com.android.server.x.wifi.net.InterfaceConfiguration@1 + +# We don't jar-jar the entire package because, we still use some classes (like +# AsyncChannel in com.android.internal.util) from these packages which are not +# inside our jar (currently in framework.jar, but will be in wifisdk.jar in the future). +rule com.android.internal.util.FastXmlSerializer* com.android.server.x.wifi.util.FastXmlSerializer@1 +rule com.android.internal.util.HexDump* com.android.server.x.wifi.util.HexDump@1 +rule com.android.internal.util.IState* com.android.server.x.wifi.util.IState@1 +rule com.android.internal.util.MessageUtils* com.android.server.x.wifi.util.MessageUtils@1 +rule com.android.internal.util.State* com.android.server.x.wifi.util.State@1 +rule com.android.internal.util.StateMachine* com.android.server.x.wifi.util.StateMachine@1 +rule com.android.internal.util.WakeupMessage* com.android.server.x.wifi.util.WakeupMessage@1 +rule com.android.internal.util.XmlUtils* com.android.server.x.wifi.util.XmlUtils@1 + +rule android.util.BackupUtils* com.android.server.x.wifi.util.BackupUtils@1 +rule android.util.LocalLog* com.android.server.x.wifi.util.LocalLog@1 +rule android.util.Rational* com.android.server.x.wifi.util.Rational@1 + +rule android.os.BasicShellCommandHandler* com.android.server.x.wifi.os.BasicShellCommandHandler@1 +rule android.os.HandlerExecutor* com.android.server.x.wifi.os.HandlerExecutor@1 + +# Use our statically linked bouncy castle library +rule org.bouncycastle.** com.android.server.x.wifi.bouncycastle.@1 +# Use our statically linked protobuf library +rule com.google.protobuf.** com.android.server.x.wifi.protobuf.@1 +# Use our statically linked PlatformProperties library +rule android.sysprop.** com.android.server.x.wifi.sysprop.@1 + + +# used by both framework-wifi and wifi-service +rule android.content.pm.BaseParceledListSlice* android.x.net.wifi.util.BaseParceledListSlice@1 +rule android.content.pm.ParceledListSlice* android.x.net.wifi.util.ParceledListSlice@1 +rule com.android.internal.util.AsyncChannel* android.x.net.wifi.util.AsyncChannel@1 +rule com.android.internal.util.AsyncService* android.x.net.wifi.util.AsyncService@1 +rule com.android.internal.util.Preconditions* android.x.net.wifi.util.Preconditions@1 +rule com.android.internal.util.Protocol* android.x.net.wifi.util.Protocol@1 -- cgit v1.2.3 From 369c920552d28b3ac759035f89af06f83b9db684 Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 9 Jan 2020 18:09:56 -0800 Subject: Jarjar more classes into framework-wifi Jarjar annotations, Inet4AddressUtils, and HandlerExecutor into framework-wifi.jar. Statically link Wifi hardware constants as well. Bug: 142886292 Test: boots up and connects to wifi Change-Id: Ib0e2e55ae5158d65dd012511ac3d4d2a73225b57 --- wifi/Android.bp | 5 ++++- wifi/jarjar-rules.txt | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index a69803a435e2..6326f14bc6fd 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -60,11 +60,14 @@ java_library { sdk_version: "core_platform", static_libs: [ "framework-wifi-util-lib", + "android.hardware.wifi-V1.0-java-constants", ], libs: [ // TODO(b/140299412) should be framework-system-stubs once we fix all @hide dependencies "framework-minus-apex", - "unsupportedappusage", + "framework-annotations-lib", + "unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage + "unsupportedappusage-annotation", // for dalvik.annotation.compat.UnsupportedAppUsage ], srcs: [ ":framework-wifi-updatable-sources", diff --git a/wifi/jarjar-rules.txt b/wifi/jarjar-rules.txt index f0da1ec54080..0746d62d5115 100644 --- a/wifi/jarjar-rules.txt +++ b/wifi/jarjar-rules.txt @@ -18,7 +18,6 @@ rule android.util.LocalLog* com.android.server.x.wifi.util.LocalLog@1 rule android.util.Rational* com.android.server.x.wifi.util.Rational@1 rule android.os.BasicShellCommandHandler* com.android.server.x.wifi.os.BasicShellCommandHandler@1 -rule android.os.HandlerExecutor* com.android.server.x.wifi.os.HandlerExecutor@1 # Use our statically linked bouncy castle library rule org.bouncycastle.** com.android.server.x.wifi.bouncycastle.@1 @@ -31,6 +30,9 @@ rule android.sysprop.** com.android.server.x.wifi.sysprop.@1 # used by both framework-wifi and wifi-service rule android.content.pm.BaseParceledListSlice* android.x.net.wifi.util.BaseParceledListSlice@1 rule android.content.pm.ParceledListSlice* android.x.net.wifi.util.ParceledListSlice@1 +rule android.net.shared.Inet4AddressUtils* android.x.net.wifi.util.Inet4AddressUtils@1 +rule android.os.HandlerExecutor* android.x.net.wifi.util.HandlerExecutor@1 +rule android.telephony.Annotation* android.x.net.wifi.util.TelephonyAnnotation@1 rule com.android.internal.util.AsyncChannel* android.x.net.wifi.util.AsyncChannel@1 rule com.android.internal.util.AsyncService* android.x.net.wifi.util.AsyncService@1 rule com.android.internal.util.Preconditions* android.x.net.wifi.util.Preconditions@1 -- cgit v1.2.3 From 6bb0d10cf7c7c6a0ce1e7dee1a688f1fa9946f33 Mon Sep 17 00:00:00 2001 From: David Su Date: Sun, 12 Jan 2020 15:41:07 -0800 Subject: Statically link SystemMessageProto into wifi-service Statically link SystemMessagesProto since Wifi uses a few constants defined here e.g. NOTE_NETWORK_NO_MAC_RANDOMIZATION_SUPPORT, NOTE_NETWORK_AVAILABLE, etc. Proto should ensure backwards compatibility of these constants. Bug: 147387246 Test: compiles Change-Id: Id6e704fa50e3500d191ecfa57cbb5a237dfaf01a --- wifi/jarjar-rules.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'wifi') diff --git a/wifi/jarjar-rules.txt b/wifi/jarjar-rules.txt index 0746d62d5115..a76a455f6333 100644 --- a/wifi/jarjar-rules.txt +++ b/wifi/jarjar-rules.txt @@ -23,6 +23,8 @@ rule android.os.BasicShellCommandHandler* com.android.server.x.wifi.os.BasicShel rule org.bouncycastle.** com.android.server.x.wifi.bouncycastle.@1 # Use our statically linked protobuf library rule com.google.protobuf.** com.android.server.x.wifi.protobuf.@1 +# use statically linked SystemMessageProto +rule com.android.internal.messages.SystemMessageProto* com.android.server.x.wifi.messages.SystemMessageProto@1 # Use our statically linked PlatformProperties library rule android.sysprop.** com.android.server.x.wifi.sysprop.@1 -- cgit v1.2.3 From 05d65140d9cee720309f69d3a8619fdd21c0f642 Mon Sep 17 00:00:00 2001 From: David Su Date: Sun, 12 Jan 2020 17:09:32 -0800 Subject: wifi-service: Remove jarjar of XmlUtils Instead, copy XmlUtils source file into wifi-service to remove XmlUtils usage of @hide libcore.util.HexEncoding. Bug: 147559755 Test: boots up and connects to wifi Change-Id: I4ec92bf31d0ebe616658410f5101b726452fb180 --- wifi/jarjar-rules.txt | 1 - 1 file changed, 1 deletion(-) (limited to 'wifi') diff --git a/wifi/jarjar-rules.txt b/wifi/jarjar-rules.txt index a76a455f6333..8f720407f4d7 100644 --- a/wifi/jarjar-rules.txt +++ b/wifi/jarjar-rules.txt @@ -11,7 +11,6 @@ rule com.android.internal.util.MessageUtils* com.android.server.x.wifi.util.Mess rule com.android.internal.util.State* com.android.server.x.wifi.util.State@1 rule com.android.internal.util.StateMachine* com.android.server.x.wifi.util.StateMachine@1 rule com.android.internal.util.WakeupMessage* com.android.server.x.wifi.util.WakeupMessage@1 -rule com.android.internal.util.XmlUtils* com.android.server.x.wifi.util.XmlUtils@1 rule android.util.BackupUtils* com.android.server.x.wifi.util.BackupUtils@1 rule android.util.LocalLog* com.android.server.x.wifi.util.LocalLog@1 -- cgit v1.2.3 From c34c2bfab1b433af0c3ba64aadf4ac30a91cb928 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Fri, 10 Jan 2020 13:01:17 -0800 Subject: WifiScanner: Create @hide API's with executor Add/Modify @hide versions of the following API's which accept an executor along with the listener: a) startSingleScan b) startDisconnectedPnoScan c) staryConnectedPnoScan These new @hide API's will be used by wifi service to ensure that the listener callbacks happen on the wifi service thread. Note: This uses the infra support added in WifiScanner class recently for the public registerScanListener API which accepts an executor. Bug: 145746458 Test: Device boots up and connects to wifi networks. Change-Id: I6feaf4614153dabe2f493dcfcbbbf2dc8cf7b71e --- wifi/java/android/net/wifi/WifiScanner.java | 31 +++++++++++++++++----- .../src/android/net/wifi/WifiScannerTest.java | 15 ++++++----- 2 files changed, 34 insertions(+), 12 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index 2c39c32ac81e..4f602fac7a36 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -833,6 +833,7 @@ public class WifiScanner { * delivered to the listener. It is possible that onFullResult will not be called for all * results of the first scan if the listener was registered during the scan. * + * @param executor the Executor on which to run the callback. * @param listener specifies the object to report events to. This object is also treated as a * key for this request, and must also be specified to cancel the request. * Multiple requests should also not share this object. @@ -955,15 +956,32 @@ public class WifiScanner { * starts a single scan and reports results asynchronously * @param settings specifies various parameters for the scan; for more information look at * {@link ScanSettings} - * @param workSource WorkSource to blame for power usage * @param listener specifies the object to report events to. This object is also treated as a * key for this scan, and must also be specified to cancel the scan. Multiple * scans should also not share this object. + * @param workSource WorkSource to blame for power usage */ @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startScan(ScanSettings settings, ScanListener listener, WorkSource workSource) { + startScan(settings, null, listener, workSource); + } + + /** + * starts a single scan and reports results asynchronously + * @param settings specifies various parameters for the scan; for more information look at + * {@link ScanSettings} + * @param executor the Executor on which to run the callback. + * @param listener specifies the object to report events to. This object is also treated as a + * key for this scan, and must also be specified to cancel the scan. Multiple + * scans should also not share this object. + * @param workSource WorkSource to blame for power usage + * @hide + */ + @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) + public void startScan(ScanSettings settings, @Nullable @CallbackExecutor Executor executor, + ScanListener listener, WorkSource workSource) { Objects.requireNonNull(listener, "listener cannot be null"); - int key = addListener(listener); + int key = addListener(listener, executor); if (key == INVALID_KEY) return; validateChannel(); Bundle scanParams = new Bundle(); @@ -1029,16 +1047,17 @@ public class WifiScanner { * {@link ScanSettings} * @param pnoSettings specifies various parameters for PNO; for more information look at * {@link PnoSettings} + * @param executor the Executor on which to run the callback. * @param listener specifies the object to report events to. This object is also treated as a * key for this scan, and must also be specified to cancel the scan. Multiple * scans should also not share this object. * {@hide} */ public void startConnectedPnoScan(ScanSettings scanSettings, PnoSettings pnoSettings, - PnoScanListener listener) { + @NonNull @CallbackExecutor Executor executor, PnoScanListener listener) { Objects.requireNonNull(listener, "listener cannot be null"); Objects.requireNonNull(pnoSettings, "pnoSettings cannot be null"); - int key = addListener(listener); + int key = addListener(listener, executor); if (key == INVALID_KEY) return; validateChannel(); pnoSettings.isConnected = true; @@ -1057,10 +1076,10 @@ public class WifiScanner { */ @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void startDisconnectedPnoScan(ScanSettings scanSettings, PnoSettings pnoSettings, - PnoScanListener listener) { + @NonNull @CallbackExecutor Executor executor, PnoScanListener listener) { Objects.requireNonNull(listener, "listener cannot be null"); Objects.requireNonNull(pnoSettings, "pnoSettings cannot be null"); - int key = addListener(listener); + int key = addListener(listener, executor); if (key == INVALID_KEY) return; validateChannel(); pnoSettings.isConnected = false; diff --git a/wifi/tests/src/android/net/wifi/WifiScannerTest.java b/wifi/tests/src/android/net/wifi/WifiScannerTest.java index 1af0bcbf3f30..0cc76b68a15e 100644 --- a/wifi/tests/src/android/net/wifi/WifiScannerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiScannerTest.java @@ -366,7 +366,7 @@ public class WifiScannerTest { /** * Test behavior of {@link WifiScanner#startDisconnectedPnoScan(ScanSettings, PnoSettings, - * WifiScanner.PnoScanListener)} + * Executor, WifiScanner.PnoScanListener)} * @throws Exception */ @Test @@ -375,7 +375,8 @@ public class WifiScannerTest { PnoSettings pnoSettings = new PnoSettings(); WifiScanner.PnoScanListener pnoScanListener = mock(WifiScanner.PnoScanListener.class); - mWifiScanner.startDisconnectedPnoScan(scanSettings, pnoSettings, pnoScanListener); + mWifiScanner.startDisconnectedPnoScan( + scanSettings, pnoSettings, mock(Executor.class), pnoScanListener); mLooper.dispatchAll(); ArgumentCaptor messageArgumentCaptor = ArgumentCaptor.forClass(Message.class); @@ -396,7 +397,7 @@ public class WifiScannerTest { /** * Test behavior of {@link WifiScanner#startConnectedPnoScan(ScanSettings, PnoSettings, - * WifiScanner.PnoScanListener)} + * Executor, WifiScanner.PnoScanListener)} * @throws Exception */ @Test @@ -405,7 +406,8 @@ public class WifiScannerTest { PnoSettings pnoSettings = new PnoSettings(); WifiScanner.PnoScanListener pnoScanListener = mock(WifiScanner.PnoScanListener.class); - mWifiScanner.startConnectedPnoScan(scanSettings, pnoSettings, pnoScanListener); + mWifiScanner.startConnectedPnoScan( + scanSettings, pnoSettings, mock(Executor.class), pnoScanListener); mLooper.dispatchAll(); ArgumentCaptor messageArgumentCaptor = ArgumentCaptor.forClass(Message.class); @@ -426,7 +428,7 @@ public class WifiScannerTest { /** * Test behavior of {@link WifiScanner#stopPnoScan(ScanListener)} - * WifiScanner.PnoScanListener)} + * Executor, WifiScanner.PnoScanListener)} * @throws Exception */ @Test @@ -435,7 +437,8 @@ public class WifiScannerTest { PnoSettings pnoSettings = new PnoSettings(); WifiScanner.PnoScanListener pnoScanListener = mock(WifiScanner.PnoScanListener.class); - mWifiScanner.startDisconnectedPnoScan(scanSettings, pnoSettings, pnoScanListener); + mWifiScanner.startDisconnectedPnoScan( + scanSettings, pnoSettings, mock(Executor.class), pnoScanListener); mLooper.dispatchAll(); mWifiScanner.stopPnoScan(pnoScanListener); mLooper.dispatchAll(); -- cgit v1.2.3 From 6c00e387abe178132445e243d1445b0d2d707f0e Mon Sep 17 00:00:00 2001 From: David Su Date: Mon, 6 Jan 2020 15:24:42 -0800 Subject: SettingsLibTests: grant access to Wifi @hide APIs Allow SettingsLib integration tests to access @hide Wifi APIs. This should only be temporary since WifiTracker (and by extension WifiTrackerTest) will be replaced by WifiTracker2. Bug: 146513037 Test: atest SettingsLibTests Test: m ANDROID_BUILDSPEC=vendor/google/build/app_build_spec.mk (build against git_master/apps target) Change-Id: Iefcdaceafedaf4d3c07af2c1370b53d04539e88f --- wifi/Android.bp | 1 + 1 file changed, 1 insertion(+) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 286be0b82db7..9739b2ae78f1 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -50,6 +50,7 @@ test_access_hidden_api_whitelist = [ "//frameworks/opt/net/wifi/libs/WifiTrackerLib/tests", "//external/robolectric-shadows:__subpackages__", + "//frameworks/base/packages/SettingsLib/tests/integ", ] java_library { -- cgit v1.2.3 From cbc8aab5f92adee61d32f3c8f01c2fe95a122b3b Mon Sep 17 00:00:00 2001 From: David Su Date: Sat, 11 Jan 2020 16:21:25 -0800 Subject: Expose ScanResult constructor for SettingsLibRoboTests Expose ScanResult default constructor so that SettingsLibRoboTests can construct a ScanResult object in the desired state and parcel/unparcel it. Bug: 138801922 Test: make RunSettingsLibRoboTests -j40 Change-Id: Ie57e0e20b1a9d9269d99cc020c3b259b39a35592 --- wifi/java/android/net/wifi/ScanResult.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java index c6aca07ebe94..341330587614 100644 --- a/wifi/java/android/net/wifi/ScanResult.java +++ b/wifi/java/android/net/wifi/ScanResult.java @@ -23,6 +23,8 @@ import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; +import com.android.internal.annotations.VisibleForTesting; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; @@ -793,10 +795,19 @@ public class ScanResult implements Parcelable { } } - /** empty scan result + /** + * Construct an empty scan result. * - * {@hide} - * */ + * Test code has a need to construct a ScanResult in a specific state. + * (Note that mocking using Mockito does not work if the object needs to be parceled and + * unparceled.) + * Export a @SystemApi default constructor to allow tests to construct an empty ScanResult + * object. The test can then directly set the fields it cares about. + * + * @hide + */ + @SystemApi + @VisibleForTesting public ScanResult() { } -- cgit v1.2.3 From da340ae101a50c79fc5e3fdd95f4b809137f2073 Mon Sep 17 00:00:00 2001 From: David Su Date: Sat, 11 Jan 2020 16:41:36 -0800 Subject: Expose WifiEnterpriseConfig.getClientPrivateKey() for WifiConfigurationProviderTest Bug: 138801922 Test: atest WifiConfigurationProviderTest Change-Id: Ic36adea1496c9684f1f47c03ff6b477510eb2df4 --- wifi/java/android/net/wifi/WifiEnterpriseConfig.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java index 41f7c6e2bb0d..5edcc2df3804 100644 --- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java +++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java @@ -1028,8 +1028,10 @@ public class WifiEnterpriseConfig implements Parcelable { } /** - * @hide + * Get the client private key as supplied in {@link #setClientKeyEntryWithCertificateChain}, or + * null if unset. */ + @Nullable public PrivateKey getClientPrivateKey() { return mClientPrivateKey; } -- cgit v1.2.3 From 7db7ce17a7385ae8d6f463a9c47b1605c1154f80 Mon Sep 17 00:00:00 2001 From: David Su Date: Sat, 11 Jan 2020 18:41:08 -0800 Subject: Expose WifiInfo & NetworkSelectionStatus Builders for SettingsUnitTests SettingsUnitTests needs to set up WifiInfo & NetworkSelectionStatus objects in a specific state and parcel/unparcel them. Create @SystemApi Builder classes in order to allow SettingsUnitTests to create these objects while maintaining the immutability of their APIs. Bug: 138801922 Test: atest SettingsUnitTests Change-Id: I40034d08396efc45bd24e16bd788e702366d5dd2 --- wifi/java/android/net/wifi/WifiConfiguration.java | 90 +++++++++++++++++++---- wifi/java/android/net/wifi/WifiInfo.java | 69 +++++++++++++++++ 2 files changed, 145 insertions(+), 14 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index f4c5b9168cd0..ee2b57535b50 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -39,6 +39,8 @@ import android.text.TextUtils; import android.util.Log; import android.util.SparseArray; +import com.android.internal.annotations.VisibleForTesting; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Arrays; @@ -1208,22 +1210,27 @@ public class WifiConfiguration implements Parcelable { */ @SystemApi public static class NetworkSelectionStatus { - // Quality Network Selection Status enable, temporary disabled, permanently disabled + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = "NETWORK_SELECTION_", + value = { + NETWORK_SELECTION_ENABLED, + NETWORK_SELECTION_TEMPORARY_DISABLED, + NETWORK_SELECTION_PERMANENTLY_DISABLED}) + public @interface NetworkEnabledStatus {} /** - * This network is allowed to join Quality Network Selection - * @hide + * This network will be considered as a potential candidate to connect to during network + * selection. */ public static final int NETWORK_SELECTION_ENABLED = 0; /** - * network was temporary disabled. Can be re-enabled after a time period expire - * @hide + * This network was temporary disabled. May be re-enabled after a time out. */ - public static final int NETWORK_SELECTION_TEMPORARY_DISABLED = 1; + public static final int NETWORK_SELECTION_TEMPORARY_DISABLED = 1; /** - * network was permanently disabled. - * @hide + * This network was permanently disabled. */ - public static final int NETWORK_SELECTION_PERMANENTLY_DISABLED = 2; + public static final int NETWORK_SELECTION_PERMANENTLY_DISABLED = 2; /** * Maximum Network selection status * @hide @@ -1455,6 +1462,7 @@ public class WifiConfiguration implements Parcelable { * Network selection status, should be in one of three status: enable, temporaily disabled * or permanently disabled */ + @NetworkEnabledStatus private int mStatus; /** @@ -1634,6 +1642,56 @@ public class WifiConfiguration implements Parcelable { mHasEverConnected = false; } + /** + * NetworkSelectionStatus exports an immutable public API. + * However, test code has a need to construct a NetworkSelectionStatus in a specific state. + * (Note that mocking using Mockito does not work if the object needs to be parceled and + * unparceled.) + * Export a @SystemApi Builder to allow tests to construct a NetworkSelectionStatus object + * in the desired state, without sacrificing NetworkSelectionStatus's immutability. + */ + @VisibleForTesting + public static final class Builder { + private final NetworkSelectionStatus mNetworkSelectionStatus = + new NetworkSelectionStatus(); + + /** + * Set the current network selection status. + * One of: + * {@link #NETWORK_SELECTION_ENABLED}, + * {@link #NETWORK_SELECTION_TEMPORARY_DISABLED}, + * {@link #NETWORK_SELECTION_PERMANENTLY_DISABLED} + * @see NetworkSelectionStatus#getNetworkSelectionStatus() + */ + @NonNull + public Builder setNetworkSelectionStatus(@NetworkEnabledStatus int status) { + mNetworkSelectionStatus.setNetworkSelectionStatus(status); + return this; + } + + /** + * + * Set the current network's disable reason. + * One of the {@link #NETWORK_SELECTION_ENABLE} or DISABLED_* constants. + * e.g. {@link #DISABLED_ASSOCIATION_REJECTION}. + * @see NetworkSelectionStatus#getNetworkSelectionDisableReason() + */ + @NonNull + public Builder setNetworkSelectionDisableReason( + @NetworkSelectionDisableReason int reason) { + mNetworkSelectionStatus.setNetworkSelectionDisableReason(reason); + return this; + } + + /** + * Build a NetworkSelectionStatus object. + */ + @NonNull + public NetworkSelectionStatus build() { + return mNetworkSelectionStatus; + } + } + /** * Get the network disable reason string for a reason code (for debugging). * @param reason specific error reason. One of the {@link #NETWORK_SELECTION_ENABLE} or @@ -1660,10 +1718,13 @@ public class WifiConfiguration implements Parcelable { } /** - * get current network network selection status - * @return return current network network selection status - * @hide + * Get the current network network selection status. + * One of: + * {@link #NETWORK_SELECTION_ENABLED}, + * {@link #NETWORK_SELECTION_TEMPORARY_DISABLED}, + * {@link #NETWORK_SELECTION_PERMANENTLY_DISABLED} */ + @NetworkEnabledStatus public int getNetworkSelectionStatus() { return mStatus; } @@ -1965,10 +2026,11 @@ public class WifiConfiguration implements Parcelable { } /** - * Set the network selection status + * Set the network selection status. * @hide */ - public void setNetworkSelectionStatus(NetworkSelectionStatus status) { + @SystemApi + public void setNetworkSelectionStatus(@NonNull NetworkSelectionStatus status) { mNetworkSelectionStatus = status; } diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java index 62337cbf7e22..51b15afec3ab 100644 --- a/wifi/java/android/net/wifi/WifiInfo.java +++ b/wifi/java/android/net/wifi/WifiInfo.java @@ -17,6 +17,7 @@ package android.net.wifi; import android.annotation.IntRange; +import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; @@ -27,6 +28,8 @@ import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; +import com.android.internal.annotations.VisibleForTesting; + import java.net.Inet4Address; import java.net.InetAddress; import java.net.UnknownHostException; @@ -356,6 +359,72 @@ public class WifiInfo implements Parcelable { } } + /** + * WifiInfo exports an immutable public API. + * However, test code has a need to construct a WifiInfo in a specific state. + * (Note that mocking using Mockito does not work if the object needs to be parceled and + * unparceled.) + * Export a @SystemApi Builder to allow tests to construct a WifiInfo object + * in the desired state, without sacrificing WifiInfo's immutability. + * + * @hide + */ + // This builder was not made public to reduce confusion for external developers as there are + // no legitimate uses for this builder except for testing. + @SystemApi + @VisibleForTesting + public static final class Builder { + private final WifiInfo mWifiInfo = new WifiInfo(); + + /** + * Set the SSID, in the form of a raw byte array. + * @see WifiInfo#getSSID() + */ + @NonNull + public Builder setSsid(@NonNull byte[] ssid) { + mWifiInfo.setSSID(WifiSsid.createFromByteArray(ssid)); + return this; + } + + /** + * Set the BSSID. + * @see WifiInfo#getBSSID() + */ + @NonNull + public Builder setBssid(@NonNull String bssid) { + mWifiInfo.setBSSID(bssid); + return this; + } + + /** + * Set the RSSI, in dBm. + * @see WifiInfo#getRssi() + */ + @NonNull + public Builder setRssi(int rssi) { + mWifiInfo.setRssi(rssi); + return this; + } + + /** + * Set the network ID. + * @see WifiInfo#getNetworkId() + */ + @NonNull + public Builder setNetworkId(int networkId) { + mWifiInfo.setNetworkId(networkId); + return this; + } + + /** + * Build a WifiInfo object. + */ + @NonNull + public WifiInfo build() { + return mWifiInfo; + } + } + /** @hide */ public void setSSID(WifiSsid wifiSsid) { mWifiSsid = wifiSsid; -- cgit v1.2.3 From 812a8f1446239edc432e314a26cb565aece905bf Mon Sep 17 00:00:00 2001 From: David Su Date: Sat, 11 Jan 2020 16:22:00 -0800 Subject: Give SL4A access to @hide Wifi APIs Bug: 138801922 Test: compiles Change-Id: Icaa98f7b6d3835ab87eea9ede24fef360f52003a --- wifi/Android.bp | 1 + 1 file changed, 1 insertion(+) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 9739b2ae78f1..eda81fcc4763 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -51,6 +51,7 @@ test_access_hidden_api_whitelist = [ "//frameworks/opt/net/wifi/libs/WifiTrackerLib/tests", "//external/robolectric-shadows:__subpackages__", "//frameworks/base/packages/SettingsLib/tests/integ", + "//external/sl4a:__subpackages__", ] java_library { -- cgit v1.2.3 From 6164dcb571a39ca5ac6014200077626d66e85386 Mon Sep 17 00:00:00 2001 From: David Su Date: Wed, 18 Dec 2019 15:16:24 -0800 Subject: Convert FrameworksWifiApiTests mk to bp (Attempt 2) Generated using androidmk script. Coverage exclude filter does not work in Android.bp as auto-generated by the androidmk script. Fixed in subsequent commit. Bug: 146513037 Test: atest FrameworksWifiApiTests Test: built coverage target Change-Id: I6d25d8a4b8a60e257e8bbbd92801609c315f3a94 --- wifi/tests/Android.bp | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++ wifi/tests/Android.mk | 66 -------------------------------------------------- 2 files changed, 67 insertions(+), 66 deletions(-) create mode 100644 wifi/tests/Android.bp delete mode 100644 wifi/tests/Android.mk (limited to 'wifi') diff --git a/wifi/tests/Android.bp b/wifi/tests/Android.bp new file mode 100644 index 000000000000..141125461d9c --- /dev/null +++ b/wifi/tests/Android.bp @@ -0,0 +1,67 @@ +// Copyright (C) 2020 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. + +// Make test APK +// ============================================================ + +// This list is generated from the java source files in this module +// The list is a comma separated list of class names with * matching zero or more characters. +// Example: +// Input files: src/com/android/server/wifi/Test.java src/com/android/server/wifi/AnotherTest.java +// Generated exclude list: com.android.server.wifi.Test*,com.android.server.wifi.AnotherTest* + +// Filter all src files to just java files +local_java_files = ["__builtin_func:filter %.java <'LOCAL_SRC_FILES' unset>"] +// Transform java file names into full class names. +// This only works if the class name matches the file name and the directory structure +// matches the package. +local_classes = ["__builtin_func:subst / . __builtin_func:patsubst src/%.java % <'local_java_files' unset>"] +// Convert class name list to jacoco exclude list +// This appends a * to all classes and replace the space separators with commas. +// These patterns will match all classes in this module and their inner classes. +jacoco_exclude = ["__builtin_func:subst <'space' unset> <'comma' unset> __builtin_func:patsubst % %* <'local_classes' unset>"] + +jacoco_include = ["android.net.wifi.*"] + +android_test { + name: "FrameworksWifiApiTests", + + srcs: ["**/*.java"], + + jacoco: { + include_filter: jacoco_include, + exclude_filter: jacoco_exclude, + }, + + static_libs: [ + "androidx.test.rules", + "core-test-rules", + "guava", + "mockito-target-minus-junit4", + "net-tests-utils", + "frameworks-base-testutils", + "truth-prebuilt", + ], + + libs: [ + "android.test.runner", + "android.test.base", + ], + + platform_apis: true, + test_suites: [ + "device-tests", + "mts", + ], +} diff --git a/wifi/tests/Android.mk b/wifi/tests/Android.mk deleted file mode 100644 index d2c385b46eb1..000000000000 --- a/wifi/tests/Android.mk +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright (C) 2016 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. - -LOCAL_PATH:= $(call my-dir) - -# Make test APK -# ============================================================ -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := tests - -LOCAL_SRC_FILES := $(call all-subdir-java-files) - -# This list is generated from the java source files in this module -# The list is a comma separated list of class names with * matching zero or more characters. -# Example: -# Input files: src/com/android/server/wifi/Test.java src/com/android/server/wifi/AnotherTest.java -# Generated exclude list: com.android.server.wifi.Test*,com.android.server.wifi.AnotherTest* - -# Filter all src files to just java files -local_java_files := $(filter %.java,$(LOCAL_SRC_FILES)) -# Transform java file names into full class names. -# This only works if the class name matches the file name and the directory structure -# matches the package. -local_classes := $(subst /,.,$(patsubst src/%.java,%,$(local_java_files))) -# Convert class name list to jacoco exclude list -# This appends a * to all classes and replace the space separators with commas. -# These patterns will match all classes in this module and their inner classes. -jacoco_exclude := $(subst $(space),$(comma),$(patsubst %,%*,$(local_classes))) - -jacoco_include := android.net.wifi.* - -LOCAL_JACK_COVERAGE_INCLUDE_FILTER := $(jacoco_include) -LOCAL_JACK_COVERAGE_EXCLUDE_FILTER := $(jacoco_exclude) - -LOCAL_STATIC_JAVA_LIBRARIES := \ - androidx.test.rules \ - core-test-rules \ - guava \ - mockito-target-minus-junit4 \ - net-tests-utils \ - frameworks-base-testutils \ - truth-prebuilt \ - -LOCAL_JAVA_LIBRARIES := \ - android.test.runner \ - android.test.base \ - -LOCAL_PACKAGE_NAME := FrameworksWifiApiTests -LOCAL_PRIVATE_PLATFORM_APIS := true -LOCAL_COMPATIBILITY_SUITE := \ - device-tests \ - mts \ - -include $(BUILD_PACKAGE) -- cgit v1.2.3 From 842f76b95f34985da5a14c7010fa8e8229f6cc0b Mon Sep 17 00:00:00 2001 From: David Su Date: Wed, 18 Dec 2019 18:31:11 -0800 Subject: FrameworksWifiApiTests: build against framework-wifi (Attempt 2) Give Wifi API unit tests access to @hide APIs in framework-wifi. Bug: 146513037 Test: atest FrameworksWifiApiTests Test: m ANDROID_BUILDSPEC=vendor/google/build/app_build_spec.mk Change-Id: Id7f44a39f9ee97eeb60a3205c157099cba2f3d8b --- wifi/tests/Android.bp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/tests/Android.bp b/wifi/tests/Android.bp index 141125461d9c..861bc49c8456 100644 --- a/wifi/tests/Android.bp +++ b/wifi/tests/Android.bp @@ -37,6 +37,8 @@ jacoco_include = ["android.net.wifi.*"] android_test { name: "FrameworksWifiApiTests", + defaults: ["framework-wifi-test-defaults"], + srcs: ["**/*.java"], jacoco: { @@ -59,7 +61,6 @@ android_test { "android.test.base", ], - platform_apis: true, test_suites: [ "device-tests", "mts", -- cgit v1.2.3 From 3dde0c625512ae079eac2f7c7cfc055b34bf8870 Mon Sep 17 00:00:00 2001 From: David Su Date: Fri, 10 Jan 2020 19:33:37 -0800 Subject: Remove FrameworksWifiApiTests jacoco exclude_filter jacoco exclude_filter generation does not work in Android.bp. Remove it for now and add it back later. Bug: 147521214 Test: atest FrameworksWifiApiTests Change-Id: If725f0242d4064097b84d2394e94743e9a02feb3 --- wifi/tests/Android.bp | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) (limited to 'wifi') diff --git a/wifi/tests/Android.bp b/wifi/tests/Android.bp index 861bc49c8456..6a39959e8cfd 100644 --- a/wifi/tests/Android.bp +++ b/wifi/tests/Android.bp @@ -15,25 +15,6 @@ // Make test APK // ============================================================ -// This list is generated from the java source files in this module -// The list is a comma separated list of class names with * matching zero or more characters. -// Example: -// Input files: src/com/android/server/wifi/Test.java src/com/android/server/wifi/AnotherTest.java -// Generated exclude list: com.android.server.wifi.Test*,com.android.server.wifi.AnotherTest* - -// Filter all src files to just java files -local_java_files = ["__builtin_func:filter %.java <'LOCAL_SRC_FILES' unset>"] -// Transform java file names into full class names. -// This only works if the class name matches the file name and the directory structure -// matches the package. -local_classes = ["__builtin_func:subst / . __builtin_func:patsubst src/%.java % <'local_java_files' unset>"] -// Convert class name list to jacoco exclude list -// This appends a * to all classes and replace the space separators with commas. -// These patterns will match all classes in this module and their inner classes. -jacoco_exclude = ["__builtin_func:subst <'space' unset> <'comma' unset> __builtin_func:patsubst % %* <'local_classes' unset>"] - -jacoco_include = ["android.net.wifi.*"] - android_test { name: "FrameworksWifiApiTests", @@ -42,8 +23,9 @@ android_test { srcs: ["**/*.java"], jacoco: { - include_filter: jacoco_include, - exclude_filter: jacoco_exclude, + include_filter: ["android.net.wifi.*"], + // TODO(b/147521214) need to exclude test classes + exclude_filter: [], }, static_libs: [ -- cgit v1.2.3 From 7ff93c71745bef85583c142ed78375c6c07df8c1 Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Sun, 29 Dec 2019 15:01:59 -0800 Subject: Enable/disable auto-join for Suggestions Add API for set auto-join enable/disable for suggestion Bug: 139199957 Test: atest android.net.wifi Change-Id: Idbf9fa2b65499294dd0e6d918cc18428fa20b0ac --- .../android/net/wifi/WifiNetworkSuggestion.java | 55 ++++++++++++++++-- .../net/wifi/WifiNetworkSuggestionTest.java | 67 +++++++++++++++++----- 2 files changed, 104 insertions(+), 18 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java index c0e089090dc9..2fba5a3f4624 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java +++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java @@ -122,6 +122,12 @@ public final class WifiNetworkSuggestion implements Parcelable { * Whether the setCredentialSharedWithUser have been called. */ private boolean mIsSharedWithUserSet; + + /** + * Whether this network is initialized with auto-join enabled (the default) or not. + */ + private boolean mIsInitialAutoJoinEnabled; + /** * Pre-shared key for use with WAPI-PSK networks. */ @@ -148,6 +154,7 @@ public final class WifiNetworkSuggestion implements Parcelable { mIsMetered = false; mIsSharedWithUser = true; mIsSharedWithUserSet = false; + mIsInitialAutoJoinEnabled = true; mPriority = UNASSIGNED_PRIORITY; mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID; mWapiPskPassphrase = null; @@ -440,6 +447,27 @@ public final class WifiNetworkSuggestion implements Parcelable { return this; } + /** + * Specifies whether the suggestion is created with auto-join enabled or disabled. The + * user may modify the auto-join configuration of a suggestion directly once the device + * associates to the network. + *

    + * If auto-join is initialized as disabled the user may still be able to manually connect + * to the network. Therefore, disabling auto-join only makes sense if + * {@link #setCredentialSharedWithUser(boolean)} is set to true (the default) which + * itself implies a secure (non-open) network. + *

    + * If not set, defaults to true (i.e. auto-join is initialized as enabled). + * + * @param enabled true for initializing with auto-join enabled (the default), false to + * initializing with auto-join disabled. + * @return Instance of (@link {@link Builder} to enable chaining of the builder method. + */ + public @NonNull Builder setIsInitialAutoJoinEnabled(boolean enabled) { + mIsInitialAutoJoinEnabled = enabled; + return this; + } + private void setSecurityParamsInWifiConfiguration( @NonNull WifiConfiguration configuration) { if (!TextUtils.isEmpty(mWpa2PskPassphrase)) { // WPA-PSK network. @@ -587,7 +615,6 @@ public final class WifiNetworkSuggestion implements Parcelable { + "suggestion with Passpoint configuration"); } wifiConfiguration = buildWifiConfigurationForPasspoint(); - } else { if (mSsid == null) { throw new IllegalStateException("setSsid should be invoked for suggestion"); @@ -608,6 +635,12 @@ public final class WifiNetworkSuggestion implements Parcelable { } mIsSharedWithUser = false; } + + if (!mIsSharedWithUser && !mIsInitialAutoJoinEnabled) { + throw new IllegalStateException("Should have not a network with both " + + "setIsUserAllowedToManuallyConnect and " + + "setIsAutoJoinEnabled set to false"); + } } return new WifiNetworkSuggestion( @@ -615,7 +648,8 @@ public final class WifiNetworkSuggestion implements Parcelable { mPasspointConfiguration, mIsAppInteractionRequired, mIsUserInteractionRequired, - mIsSharedWithUser); + mIsSharedWithUser, + mIsInitialAutoJoinEnabled); } } @@ -642,6 +676,7 @@ public final class WifiNetworkSuggestion implements Parcelable { * @hide */ public final boolean isUserInteractionRequired; + /** * Whether app share credential with the user, allow user use provided credential to * connect network manually. @@ -649,6 +684,12 @@ public final class WifiNetworkSuggestion implements Parcelable { */ public final boolean isUserAllowedToManuallyConnect; + /** + * Whether the suggestion will be initialized as auto-joined or not. + * @hide + */ + public final boolean isInitialAutoJoinEnabled; + /** @hide */ public WifiNetworkSuggestion() { this.wifiConfiguration = null; @@ -656,6 +697,7 @@ public final class WifiNetworkSuggestion implements Parcelable { this.isAppInteractionRequired = false; this.isUserInteractionRequired = false; this.isUserAllowedToManuallyConnect = true; + this.isInitialAutoJoinEnabled = true; } /** @hide */ @@ -663,7 +705,8 @@ public final class WifiNetworkSuggestion implements Parcelable { @Nullable PasspointConfiguration passpointConfiguration, boolean isAppInteractionRequired, boolean isUserInteractionRequired, - boolean isUserAllowedToManuallyConnect) { + boolean isUserAllowedToManuallyConnect, + boolean isInitialAutoJoinEnabled) { checkNotNull(networkConfiguration); this.wifiConfiguration = networkConfiguration; this.passpointConfiguration = passpointConfiguration; @@ -671,6 +714,7 @@ public final class WifiNetworkSuggestion implements Parcelable { this.isAppInteractionRequired = isAppInteractionRequired; this.isUserInteractionRequired = isUserInteractionRequired; this.isUserAllowedToManuallyConnect = isUserAllowedToManuallyConnect; + this.isInitialAutoJoinEnabled = isInitialAutoJoinEnabled; } public static final @NonNull Creator CREATOR = @@ -682,7 +726,8 @@ public final class WifiNetworkSuggestion implements Parcelable { in.readParcelable(null), // PasspointConfiguration in.readBoolean(), // isAppInteractionRequired in.readBoolean(), // isUserInteractionRequired - in.readBoolean() // isSharedCredentialWithUser + in.readBoolean(), // isSharedCredentialWithUser + in.readBoolean() // isAutoJoinEnabled ); } @@ -704,6 +749,7 @@ public final class WifiNetworkSuggestion implements Parcelable { dest.writeBoolean(isAppInteractionRequired); dest.writeBoolean(isUserInteractionRequired); dest.writeBoolean(isUserAllowedToManuallyConnect); + dest.writeBoolean(isInitialAutoJoinEnabled); } @Override @@ -744,6 +790,7 @@ public final class WifiNetworkSuggestion implements Parcelable { .append(", isAppInteractionRequired=").append(isAppInteractionRequired) .append(", isUserInteractionRequired=").append(isUserInteractionRequired) .append(", isUserAllowedToManuallyConnect=").append(isUserAllowedToManuallyConnect) + .append(", isInitialAutoJoinEnabled=").append(isInitialAutoJoinEnabled) .append(" ]"); return sb.toString(); } diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java index ac915447f3c4..cb1b7747798d 100644 --- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java +++ b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java @@ -32,8 +32,6 @@ import org.junit.Test; */ @SmallTest public class WifiNetworkSuggestionTest { - private static final int TEST_UID = 45677; - private static final int TEST_UID_OTHER = 45673; private static final String TEST_SSID = "\"Test123\""; private static final String TEST_BSSID = "12:12:12:12:12:12"; private static final String TEST_SSID_1 = "\"Test1234\""; @@ -61,7 +59,8 @@ public class WifiNetworkSuggestionTest { assertEquals(WifiConfiguration.METERED_OVERRIDE_NONE, suggestion.wifiConfiguration.meteredOverride); assertEquals(-1, suggestion.wifiConfiguration.priority); - assertEquals(false, suggestion.isUserAllowedToManuallyConnect); + assertFalse(suggestion.isUserAllowedToManuallyConnect); + assertTrue(suggestion.isInitialAutoJoinEnabled); } /** @@ -90,7 +89,8 @@ public class WifiNetworkSuggestionTest { assertEquals(WifiConfiguration.METERED_OVERRIDE_NONE, suggestion.wifiConfiguration.meteredOverride); assertEquals(0, suggestion.wifiConfiguration.priority); - assertEquals(false, suggestion.isUserAllowedToManuallyConnect); + assertFalse(suggestion.isUserAllowedToManuallyConnect); + assertTrue(suggestion.isInitialAutoJoinEnabled); } /** @@ -105,6 +105,7 @@ public class WifiNetworkSuggestionTest { .setSsid(TEST_SSID) .setWpa2Passphrase(TEST_PRESHARED_KEY) .setIsUserInteractionRequired(true) + .setIsInitialAutoJoinEnabled(false) .setIsMetered(true) .build(); @@ -119,6 +120,7 @@ public class WifiNetworkSuggestionTest { suggestion.wifiConfiguration.meteredOverride); assertEquals(-1, suggestion.wifiConfiguration.priority); assertTrue(suggestion.isUserAllowedToManuallyConnect); + assertFalse(suggestion.isInitialAutoJoinEnabled); } /** @@ -140,6 +142,7 @@ public class WifiNetworkSuggestionTest { assertNull(suggestion.wifiConfiguration.preSharedKey); assertTrue(suggestion.wifiConfiguration.requirePMF); assertFalse(suggestion.isUserAllowedToManuallyConnect); + assertTrue(suggestion.isInitialAutoJoinEnabled); } /** @@ -152,6 +155,7 @@ public class WifiNetworkSuggestionTest { .setSsid(TEST_SSID) .setWpa3Passphrase(TEST_PRESHARED_KEY) .setCredentialSharedWithUser(true) + .setIsInitialAutoJoinEnabled(false) .build(); assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID); @@ -161,6 +165,7 @@ public class WifiNetworkSuggestionTest { suggestion.wifiConfiguration.preSharedKey); assertTrue(suggestion.wifiConfiguration.requirePMF); assertTrue(suggestion.isUserAllowedToManuallyConnect); + assertFalse(suggestion.isInitialAutoJoinEnabled); } @@ -191,6 +196,7 @@ public class WifiNetworkSuggestionTest { // allowedSuiteBCiphers are set according to the loaded certificate and cannot be tested // here. assertTrue(suggestion.isUserAllowedToManuallyConnect); + assertTrue(suggestion.isInitialAutoJoinEnabled); } /** @@ -526,7 +532,7 @@ public class WifiNetworkSuggestionTest { configuration.BSSID = TEST_BSSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion( - configuration, null, false, true, true); + configuration, null, false, true, true, false); Parcel parcelW = Parcel.obtain(); suggestion.writeToParcel(parcelW, 0); @@ -548,6 +554,8 @@ public class WifiNetworkSuggestionTest { parcelSuggestion.isAppInteractionRequired); assertEquals(suggestion.isUserInteractionRequired, parcelSuggestion.isUserInteractionRequired); + assertEquals(suggestion.isInitialAutoJoinEnabled, + parcelSuggestion.isInitialAutoJoinEnabled); } /** @@ -580,6 +588,8 @@ public class WifiNetworkSuggestionTest { parcelSuggestion.isAppInteractionRequired); assertEquals(suggestion.isUserInteractionRequired, parcelSuggestion.isUserInteractionRequired); + assertEquals(suggestion.isInitialAutoJoinEnabled, + parcelSuggestion.isInitialAutoJoinEnabled); } /** @@ -593,14 +603,14 @@ public class WifiNetworkSuggestionTest { configuration.BSSID = TEST_BSSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, null, true, false, true); + new WifiNetworkSuggestion(configuration, null, true, false, true, true); WifiConfiguration configuration1 = new WifiConfiguration(); configuration1.SSID = TEST_SSID; configuration1.BSSID = TEST_BSSID; configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); WifiNetworkSuggestion suggestion1 = - new WifiNetworkSuggestion(configuration1, null, false, true, true); + new WifiNetworkSuggestion(configuration1, null, false, true, true, false); assertEquals(suggestion, suggestion1); assertEquals(suggestion.hashCode(), suggestion1.hashCode()); @@ -616,13 +626,13 @@ public class WifiNetworkSuggestionTest { configuration.SSID = TEST_SSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, null, false, false, true); + new WifiNetworkSuggestion(configuration, null, false, false, true, false); WifiConfiguration configuration1 = new WifiConfiguration(); configuration1.SSID = TEST_SSID_1; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion1 = - new WifiNetworkSuggestion(configuration1, null, false, false, true); + new WifiNetworkSuggestion(configuration1, null, false, false, true, false); assertNotEquals(suggestion, suggestion1); } @@ -638,13 +648,13 @@ public class WifiNetworkSuggestionTest { configuration.BSSID = TEST_BSSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, null, false, false, true); + new WifiNetworkSuggestion(configuration, null, false, false, true, true); WifiConfiguration configuration1 = new WifiConfiguration(); configuration1.SSID = TEST_SSID; configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion1 = - new WifiNetworkSuggestion(configuration1, null, false, false, true); + new WifiNetworkSuggestion(configuration1, null, false, false, true, true); assertNotEquals(suggestion, suggestion1); } @@ -659,13 +669,13 @@ public class WifiNetworkSuggestionTest { configuration.SSID = TEST_SSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, null, false, false, true); + new WifiNetworkSuggestion(configuration, null, false, false, true, true); WifiConfiguration configuration1 = new WifiConfiguration(); configuration1.SSID = TEST_SSID; configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); WifiNetworkSuggestion suggestion1 = - new WifiNetworkSuggestion(configuration1, null, false, false, true); + new WifiNetworkSuggestion(configuration1, null, false, false, true, true); assertNotEquals(suggestion, suggestion1); } @@ -714,9 +724,38 @@ public class WifiNetworkSuggestionTest { */ @Test(expected = IllegalStateException.class) public void testSetIsUserAllowedToManuallyConnectToWithOpenNetwork() { - WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() + new WifiNetworkSuggestion.Builder() .setSsid(TEST_SSID) .setCredentialSharedWithUser(true) .build(); } + + /** + * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception + * when {@link WifiNetworkSuggestion.Builder#setIsInitialAutoJoinEnabled(boolean)} to + * false on a open network suggestion. + */ + @Test(expected = IllegalStateException.class) + public void testSetIsAutoJoinDisabledWithOpenNetwork() { + new WifiNetworkSuggestion.Builder() + .setSsid(TEST_SSID) + .setIsInitialAutoJoinEnabled(false) + .build(); + } + + /** + * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception + * when set both {@link WifiNetworkSuggestion.Builder#setIsInitialAutoJoinEnabled(boolean)} + * and {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} (boolean)} + * to false on a network suggestion. + */ + @Test(expected = IllegalStateException.class) + public void testSetIsAutoJoinDisabledWithSecureNetworkNotSharedWithUser() { + new WifiNetworkSuggestion.Builder() + .setSsid(TEST_SSID) + .setWpa2Passphrase(TEST_PRESHARED_KEY) + .setCredentialSharedWithUser(false) + .setIsInitialAutoJoinEnabled(false) + .build(); + } } -- cgit v1.2.3 From 94df39acd8efb0894216468ebf67512dc58d8325 Mon Sep 17 00:00:00 2001 From: Aaron Huang Date: Tue, 17 Dec 2019 00:33:18 +0800 Subject: Remove framework code that has moved to frameworks/libs/net Add srcs to framework and change import path. Remove the codes which are moved to frameworks/libs/net. Bug: 139268426 Bug: 135998869 Bug: 138306002 Bug: 143925787 Test: atest FrameworksNetTests atest FrameworksTelephonyTests atest ./frameworks/opt/net/wifi/tests/wifitests/runtests.sh Change-Id: Ieb8927f9af7f87a5ae038bd6c7daeb3d70117fef --- wifi/java/android/net/wifi/WifiConfiguration.java | 3 ++- wifi/tests/src/android/net/wifi/WifiConfigurationTest.java | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index f4c5b9168cd0..4dc064779d6b 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -29,6 +29,7 @@ import android.net.NetworkSpecifier; import android.net.ProxyInfo; import android.net.StaticIpConfiguration; import android.net.Uri; +import android.net.util.MacAddressUtils; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -1164,7 +1165,7 @@ public class WifiConfiguration implements Parcelable { * @return true if mac is good to use */ public static boolean isValidMacAddressForRandomization(MacAddress mac) { - return mac != null && !mac.isMulticastAddress() && mac.isLocallyAssigned() + return mac != null && !MacAddressUtils.isMulticastAddress(mac) && mac.isLocallyAssigned() && !MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS).equals(mac); } diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java index 8689a38c6b17..0ef75aa3eb5a 100644 --- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java @@ -27,6 +27,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import android.net.MacAddress; +import android.net.util.MacAddressUtils; import android.net.wifi.WifiConfiguration.KeyMgmt; import android.net.wifi.WifiConfiguration.NetworkSelectionStatus; import android.os.Parcel; @@ -63,7 +64,7 @@ public class WifiConfigurationTest { config.updateIdentifier = "1234"; config.fromWifiNetworkSpecifier = true; config.fromWifiNetworkSuggestion = true; - config.setRandomizedMacAddress(MacAddress.createRandomUnicastAddress()); + config.setRandomizedMacAddress(MacAddressUtils.createRandomUnicastAddress()); MacAddress macBeforeParcel = config.getRandomizedMacAddress(); Parcel parcelW = Parcel.obtain(); config.writeToParcel(parcelW, 0); @@ -169,7 +170,7 @@ public class WifiConfigurationTest { MacAddress defaultMac = MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS); assertEquals(defaultMac, config.getRandomizedMacAddress()); - MacAddress macToChangeInto = MacAddress.createRandomUnicastAddress(); + MacAddress macToChangeInto = MacAddressUtils.createRandomUnicastAddress(); config.setRandomizedMacAddress(macToChangeInto); MacAddress macAfterChange = config.getRandomizedMacAddress(); -- cgit v1.2.3 From 3587754f229efb8c07160b25c385a6ce3c7034cc Mon Sep 17 00:00:00 2001 From: Aaron Huang Date: Mon, 6 Jan 2020 20:22:17 +0800 Subject: Move DnsSdTxtRecord to net common static library DnsSdTxtRecord is moved to frameworks/libs/net for mainline support. Also change the import path using this class. Bug: 139268426 Bug: 135998869 Test: atest FrameworksNetTests ./frameworks/opt/net/wifi/tests/wifitests/runtests.sh Change-Id: I6118b313ce668707d598aa2eab9baee2f7622dbc --- wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java index 0de7ba6439eb..dad431c1ca2c 100644 --- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java +++ b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java @@ -17,7 +17,7 @@ package android.net.wifi.p2p.nsd; import android.compat.annotation.UnsupportedAppUsage; -import android.net.nsd.DnsSdTxtRecord; +import android.net.util.nsd.DnsSdTxtRecord; import android.os.Build; import android.text.TextUtils; -- cgit v1.2.3 From 537d8d9e2bcdc7361bf9a0c14b32d606b7d3881d Mon Sep 17 00:00:00 2001 From: David Su Date: Tue, 14 Jan 2020 16:47:19 -0800 Subject: framework-wifi: clean up AIDL exports Remove AIDL exports to not leak internal implementation as AIDL is not an official API of the Wifi module. Bug: 140299412 Test: device boots up and connects to wifi Change-Id: I52bb63a2ae9df2c2f9e9868a20c66418a420e3b6 --- wifi/Android.bp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 70c9befce66a..d14a726eed5d 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -113,6 +113,8 @@ droidstubs { ":framework-annotations", ":framework-wifi-updatable-sources", ], + // This is needed as IOnWifiActivityEnergyInfoListener.aidl in framework-wifi depends on + // WifiActivityEnergyInfo.aidl in framework-minus-apex aidl: { include_dirs: ["frameworks/base/core/java"], }, @@ -124,11 +126,6 @@ droidstubs { java_library { name: "framework-wifi-stubs", srcs: [":framework-wifi-stubs-srcs"], - aidl: { - export_include_dirs: [ - "java", - ], - }, sdk_version: "core_current", libs: ["android_system_stubs_current"], installable: false, -- cgit v1.2.3 From 31de34693ed8444ded6adf0350242229b279f70a Mon Sep 17 00:00:00 2001 From: "Nate(Qiang) Jiang" Date: Tue, 14 Jan 2020 15:54:14 -0800 Subject: Change Doc for getConnectionInfo When app doesn't have location permission or location mode disabled, FQDN and friendly name will not ba able to access. Bug: 147699220 Test: build Change-Id: If4000ba550ee58a17cbf77e4e28a9e6a592b6264 --- wifi/java/android/net/wifi/WifiInfo.java | 11 +++++++++++ wifi/java/android/net/wifi/WifiManager.java | 2 ++ 2 files changed, 13 insertions(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java index 62337cbf7e22..dc8fa65fd747 100644 --- a/wifi/java/android/net/wifi/WifiInfo.java +++ b/wifi/java/android/net/wifi/WifiInfo.java @@ -631,6 +631,11 @@ public class WifiInfo implements Parcelable { /** * Returns the Fully Qualified Domain Name of the network if it is a Passpoint network. + *

    + * The FQDN may be + * {@code null} if no network currently connected, currently connected network is not + * passpoint network or the caller has insufficient permissions to access the FQDN. + *

    */ public @Nullable String getPasspointFqdn() { return mFqdn; @@ -643,6 +648,12 @@ public class WifiInfo implements Parcelable { /** * Returns the Provider Friendly Name of the network if it is a Passpoint network. + *

    + * The Provider Friendly Name may be + * {@code null} if no network currently connected, currently connected network is not + * passpoint network or the caller has insufficient permissions to access the Provider Friendly + * Name. + *

    */ public @Nullable String getPasspointProviderFriendlyName() { return mProviderFriendlyName; diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 729ac14b8b73..c428f0cab3df 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -2602,6 +2602,8 @@ public class WifiManager { * the same permissions as {@link #getScanResults}. If such access is not allowed, * {@link WifiInfo#getSSID} will return {@link #UNKNOWN_SSID} and * {@link WifiInfo#getBSSID} will return {@code "02:00:00:00:00:00"}. + * {@link WifiInfo#getPasspointFqdn()} will return null. + * {@link WifiInfo#getPasspointProviderFriendlyName()} will return null. * * @return the Wi-Fi information, contained in {@link WifiInfo}. */ -- cgit v1.2.3 From d084a449ccfdc9b1eb4a328ffaa9bc7dbf862567 Mon Sep 17 00:00:00 2001 From: David Su Date: Wed, 15 Jan 2020 11:22:23 -0800 Subject: Expose WifiConfiguration.SuiteBCipher WifiConfiguration.SuiteBCipher is linked in documentation of public API WifiConfiguration.allowedSuiteBCiphers. Thus expose SuiteBCipher as a public API. Bug: 147711708 Test: compiles Change-Id: Ib913f92d61dce29da4660a3f2f08c8c17d939b71 --- wifi/java/android/net/wifi/WifiConfiguration.java | 1 - 1 file changed, 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index ee2b57535b50..f8dc9d808a2c 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -372,7 +372,6 @@ public class WifiConfiguration implements Parcelable { * ECDHE_ECDSA * ECDHE_RSA *
    - * @hide */ public static class SuiteBCipher { private SuiteBCipher() { } -- cgit v1.2.3 From eb2572959a6d89c14c9ba1de23a9ef561eb87e15 Mon Sep 17 00:00:00 2001 From: David Su Date: Sun, 5 Jan 2020 15:45:33 -0800 Subject: framework.jar - include framework-wifi-stubs instead of framework-wifi Stop exporting @hide APIs from framework-wifi to framework.jar by including framework-wifi-stubs instead. Bug: 140299412 Test: boots up and connects to Wifi Change-Id: If790ea3ac4e6587b28063eac59295cb875a8ce35 --- wifi/Android.bp | 1 - 1 file changed, 1 deletion(-) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 70c9befce66a..791da3051ca2 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -97,7 +97,6 @@ java_library { }, hostdex: true, // for hiddenapi check visibility: [ - "//frameworks/base", // TODO(b/140299412) remove once all dependencies are fixed "//frameworks/opt/net/wifi/service:__subpackages__", ] + test_access_hidden_api_whitelist, apex_available: [ -- cgit v1.2.3 From 03e42a6d68a8620df3dcb8cc89e729301249eaed Mon Sep 17 00:00:00 2001 From: David Su Date: Wed, 15 Jan 2020 20:50:43 +0000 Subject: Revert "framework-wifi: clean up AIDL exports" This reverts commit 537d8d9e2bcdc7361bf9a0c14b32d606b7d3881d. Reason for revert: Broke build Change-Id: Ia69c60050203b1124baf8d1304e837854a1f8bc9 --- wifi/Android.bp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index d14a726eed5d..70c9befce66a 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -113,8 +113,6 @@ droidstubs { ":framework-annotations", ":framework-wifi-updatable-sources", ], - // This is needed as IOnWifiActivityEnergyInfoListener.aidl in framework-wifi depends on - // WifiActivityEnergyInfo.aidl in framework-minus-apex aidl: { include_dirs: ["frameworks/base/core/java"], }, @@ -126,6 +124,11 @@ droidstubs { java_library { name: "framework-wifi-stubs", srcs: [":framework-wifi-stubs-srcs"], + aidl: { + export_include_dirs: [ + "java", + ], + }, sdk_version: "core_current", libs: ["android_system_stubs_current"], installable: false, -- cgit v1.2.3 From a0d404b1b81261090e72da3d938fb73a0d97baab Mon Sep 17 00:00:00 2001 From: Michael Plass Date: Tue, 14 Jan 2020 15:42:44 -0800 Subject: Remove some unneeded WifiConfiguration time stamps Removed mConnectChoiceTimestamp, creationTime, updateTime. Bug: 146460486 Test: atest FrameworksWifiApiTests Change-Id: Ic638a40b9d962bbeb7e193d61f3f510c96bc2680 --- wifi/java/android/net/wifi/WifiConfiguration.java | 52 ----------------------- 1 file changed, 52 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index f4c5b9168cd0..e65273842c93 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -852,18 +852,6 @@ public class WifiConfiguration implements Parcelable { @UnsupportedAppUsage public int numNoInternetAccessReports; - /** - * @hide - * For debug: date at which the config was last updated - */ - public String updateTime; - - /** - * @hide - * For debug: date at which the config was last updated - */ - public String creationTime; - /** * @hide * The WiFi configuration is considered to have no internet access for purpose of autojoining @@ -1484,12 +1472,6 @@ public class WifiConfiguration implements Parcelable { */ private String mConnectChoice; - /** - * The system timestamp when we records the connectChoice. This value is obtained from - * System.currentTimeMillis - */ - private long mConnectChoiceTimestamp = INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP; - /** * Used to cache the temporary candidate during the network selection procedure. It will be * kept updating once a new scan result has a higher score than current one @@ -1593,25 +1575,6 @@ public class WifiConfiguration implements Parcelable { mConnectChoice = newConnectChoice; } - /** - * get the timeStamp when user select a choice over this configuration - * @return returns when current connectChoice is set (time from System.currentTimeMillis) - * @hide - */ - public long getConnectChoiceTimestamp() { - return mConnectChoiceTimestamp; - } - - /** - * set the timeStamp when user select a choice over this configuration - * @param timeStamp, the timestamp set to connectChoiceTimestamp, expected timestamp should - * be obtained from System.currentTimeMillis - * @hide - */ - public void setConnectChoiceTimestamp(long timeStamp) { - mConnectChoiceTimestamp = timeStamp; - } - /** Get the current Quality network selection status as a String (for debugging). */ @NonNull public String getNetworkStatusString() { @@ -1841,7 +1804,6 @@ public class WifiConfiguration implements Parcelable { setCandidate(source.getCandidate()); setCandidateScore(source.getCandidateScore()); setConnectChoice(source.getConnectChoice()); - setConnectChoiceTimestamp(source.getConnectChoiceTimestamp()); setHasEverConnected(source.getHasEverConnected()); } @@ -1858,7 +1820,6 @@ public class WifiConfiguration implements Parcelable { if (getConnectChoice() != null) { dest.writeInt(CONNECT_CHOICE_EXISTS); dest.writeString(getConnectChoice()); - dest.writeLong(getConnectChoiceTimestamp()); } else { dest.writeInt(CONNECT_CHOICE_NOT_EXISTS); } @@ -1877,10 +1838,8 @@ public class WifiConfiguration implements Parcelable { setNetworkSelectionBSSID(in.readString()); if (in.readInt() == CONNECT_CHOICE_EXISTS) { setConnectChoice(in.readString()); - setConnectChoiceTimestamp(in.readLong()); } else { setConnectChoice(null); - setConnectChoiceTimestamp(INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP); } setHasEverConnected(in.readInt() != 0); } @@ -2103,9 +2062,6 @@ public class WifiConfiguration implements Parcelable { } if (mNetworkSelectionStatus.getConnectChoice() != null) { sbuf.append(" connect choice: ").append(mNetworkSelectionStatus.getConnectChoice()); - sbuf.append(" connect choice set time: ") - .append(logTimeOfDay( - mNetworkSelectionStatus.getConnectChoiceTimestamp())); } sbuf.append(" hasEverConnected: ") .append(mNetworkSelectionStatus.getHasEverConnected()).append("\n"); @@ -2117,12 +2073,6 @@ public class WifiConfiguration implements Parcelable { sbuf.append(" numNoInternetAccessReports "); sbuf.append(this.numNoInternetAccessReports).append("\n"); } - if (this.updateTime != null) { - sbuf.append(" update ").append(this.updateTime).append("\n"); - } - if (this.creationTime != null) { - sbuf.append(" creation ").append(this.creationTime).append("\n"); - } if (this.validatedInternetAccess) sbuf.append(" validatedInternetAccess"); if (this.ephemeral) sbuf.append(" ephemeral"); if (this.osu) sbuf.append(" osu"); @@ -2669,8 +2619,6 @@ public class WifiConfiguration implements Parcelable { allowAutojoin = source.allowAutojoin; numNoInternetAccessReports = source.numNoInternetAccessReports; noInternetAccessExpected = source.noInternetAccessExpected; - creationTime = source.creationTime; - updateTime = source.updateTime; shared = source.shared; recentFailure.setAssociationStatus(source.recentFailure.getAssociationStatus()); mRandomizedMacAddress = source.mRandomizedMacAddress; -- cgit v1.2.3 From 1763329d16cd997cfcfe1c9d1c190604d7dab270 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Wed, 15 Jan 2020 06:48:49 -0800 Subject: WifiManager: Add API to query STA + AP concurrency Use the existing feature flag |WIFI_FEATURE_AP_STA| to expose a @SystemApi. PS: This flag is currently unused. Will need to find a mechanism by which we can fill in this flag appropriately from HalDeviceManager. Bug: 141452146 Test: Compiles Change-Id: Idf3bab96686a8994cd3eea6bec8346db96161a03 --- wifi/java/android/net/wifi/WifiManager.java | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index a8a31eba303c..32cf9bb43036 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -2368,6 +2368,15 @@ public class WifiManager { return isFeatureSupported(WIFI_FEATURE_AWARE); } + /** + * Query whether the device supports Station (STA) + Access point (AP) concurrency or not. + * + * @return true if this device supports STA + AP concurrency, false otherwise. + */ + public boolean isStaApConcurrencySupported() { + return isFeatureSupported(WIFI_FEATURE_AP_STA); + } + /** * @deprecated Please use {@link android.content.pm.PackageManager#hasSystemFeature(String)} * with {@link android.content.pm.PackageManager#FEATURE_WIFI_RTT} and -- cgit v1.2.3 From b4e491a64c9804e70ff773ee82f1bfd8f7f22977 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Wed, 15 Jan 2020 11:20:02 -0800 Subject: wifi-service: Jar-Jar net util library Also, change tetheringInterfaceUtils to use the same jar-jar rules. Bug: 135998869 Test: Compiles Test: Number of compile errors when compiled against system_current reduces. Change-Id: Ib2fb2bf0556af3ce1519f213f7805620675d7db7 --- wifi/jarjar-rules.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'wifi') diff --git a/wifi/jarjar-rules.txt b/wifi/jarjar-rules.txt index 8f720407f4d7..60a38dd827fa 100644 --- a/wifi/jarjar-rules.txt +++ b/wifi/jarjar-rules.txt @@ -1,5 +1,6 @@ rule android.net.InterfaceConfigurationParcel* @0 rule android.net.InterfaceConfiguration* com.android.server.x.wifi.net.InterfaceConfiguration@1 +rule android.net.util.** com.android.server.x.wifi.net.util.@1 # We don't jar-jar the entire package because, we still use some classes (like # AsyncChannel in com.android.internal.util) from these packages which are not -- cgit v1.2.3 From c865b21d4b68af94fe28a8a09d4a934bd5aa3b1d Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 16 Jan 2020 02:43:21 +0000 Subject: Revert "framework.jar - include framework-wifi-stubs instead of framework-wifi" This reverts commit eb2572959a6d89c14c9ba1de23a9ef561eb87e15. Reason for revert: Broke build Change-Id: I694c84dec6ae47a6c86fa1036802cdd750490efc --- wifi/Android.bp | 1 + 1 file changed, 1 insertion(+) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 791da3051ca2..70c9befce66a 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -97,6 +97,7 @@ java_library { }, hostdex: true, // for hiddenapi check visibility: [ + "//frameworks/base", // TODO(b/140299412) remove once all dependencies are fixed "//frameworks/opt/net/wifi/service:__subpackages__", ] + test_access_hidden_api_whitelist, apex_available: [ -- cgit v1.2.3 From d26218b6d7ffb01b177642c1463ef77cd588f4ef Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Thu, 16 Jan 2020 16:36:40 +0000 Subject: Revert "wifi-service: Jar-Jar net util library" Reason for revert: b/147807058 Reverted Changes: I902b7b742: telephony: jar-jar net.util classes on the usage s... I90a9c537b: wifi-service: Link net util libraries Ic3b92ca63: libs(net/common): Fixes for wifi to include. Ib2fb2bf05: wifi-service: Jar-Jar net util library. Bug: 147807058 Change-Id: I6a0cf666be126f45b859e38446862654e056a009 --- wifi/jarjar-rules.txt | 1 - 1 file changed, 1 deletion(-) (limited to 'wifi') diff --git a/wifi/jarjar-rules.txt b/wifi/jarjar-rules.txt index 60a38dd827fa..8f720407f4d7 100644 --- a/wifi/jarjar-rules.txt +++ b/wifi/jarjar-rules.txt @@ -1,6 +1,5 @@ rule android.net.InterfaceConfigurationParcel* @0 rule android.net.InterfaceConfiguration* com.android.server.x.wifi.net.InterfaceConfiguration@1 -rule android.net.util.** com.android.server.x.wifi.net.util.@1 # We don't jar-jar the entire package because, we still use some classes (like # AsyncChannel in com.android.internal.util) from these packages which are not -- cgit v1.2.3 From 380322e7ffafc410887cb56abd518b6ba15bded9 Mon Sep 17 00:00:00 2001 From: xshu Date: Tue, 14 Jan 2020 17:54:31 -0800 Subject: Allow set MAC randomization setting for passpoint Add API to enable/disable MAC randomization per passpoint profile. Bug: 145209638 Test: atest android.net.wifi Change-Id: I1683ed4eb3c64c6643eb04919dc77aa8f0db0ec6 --- wifi/java/android/net/wifi/IWifiManager.aidl | 2 ++ wifi/java/android/net/wifi/WifiManager.java | 18 ++++++++++ .../net/wifi/hotspot2/PasspointConfiguration.java | 39 +++++++++++++++++++++- .../com/android/server/wifi/BaseWifiService.java | 5 +++ .../src/android/net/wifi/WifiManagerTest.java | 11 ++++++ .../wifi/hotspot2/PasspointConfigurationTest.java | 1 + 6 files changed, 75 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index f490766559de..67f166327b56 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -92,6 +92,8 @@ interface IWifiManager void allowAutojoinPasspoint(String fqdn, boolean enableAutoJoin); + void setMacRandomizationSettingPasspointEnabled(String fqdn, boolean enable); + boolean startScan(String packageName, String featureId); List getScanResults(String callingPackage, String callingFeatureId); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index a8a31eba303c..d5a521136a56 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -4231,6 +4231,24 @@ public class WifiManager { } } + /** + * Configure MAC randomization setting for a Passpoint profile. + * MAC randomization is enabled by default. + * + * @param fqdn the FQDN (fully qualified domain name) of the passpoint profile. + * @param enable true to enable MAC randomization, false to disable MAC randomization. + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) + public void setMacRandomizationSettingPasspointEnabled(@NonNull String fqdn, boolean enable) { + try { + mService.setMacRandomizationSettingPasspointEnabled(fqdn, enable); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Disable an ephemeral network. * diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java index 1822e84fdd57..7c335fc323f5 100644 --- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java +++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java @@ -430,6 +430,13 @@ public final class PasspointConfiguration implements Parcelable { */ private boolean mIsAutoJoinEnabled = true; + /** + * The mac randomization setting specifies whether a randomized or device MAC address will + * be used to connect to the passpoint network. If true, a randomized MAC will be used. + * Otherwise, the device MAC address will be used. + */ + private boolean mIsMacRandomizationEnabled = true; + /** * Configures the auto-association status of this Passpoint configuration. A value of true * indicates that the configuration will be considered for auto-connection, a value of false @@ -443,6 +450,18 @@ public final class PasspointConfiguration implements Parcelable { mIsAutoJoinEnabled = autoJoinEnabled; } + /** + * Configures the MAC randomization setting for this Passpoint configuration. + * If set to true, the framework will use a randomized MAC address to connect to this Passpoint + * network. Otherwise, the framework will use the device MAC address. + * + * @param enabled true to use randomized MAC address, false to use device MAC address. + * @hide + */ + public void setMacRandomizationEnabled(boolean enabled) { + mIsMacRandomizationEnabled = enabled; + } + /** * Indicates whether the Passpoint configuration may be auto-connected to by the framework. A * value of true indicates that auto-connection can happen, a value of false indicates that it @@ -458,6 +477,19 @@ public final class PasspointConfiguration implements Parcelable { return mIsAutoJoinEnabled; } + /** + * Indicates whether a randomized MAC address or device MAC address will be used for + * connections to this Passpoint network. If true, a randomized MAC address will be used. + * Otherwise, the device MAC address will be used. + * + * @return true for MAC randomization enabled. False for disabled. + * @hide + */ + @SystemApi + public boolean isMacRandomizationEnabled() { + return mIsMacRandomizationEnabled; + } + /** * Constructor for creating PasspointConfiguration with default values. */ @@ -501,6 +533,7 @@ public final class PasspointConfiguration implements Parcelable { mAaaServerTrustedNames = source.mAaaServerTrustedNames; mCarrierId = source.mCarrierId; mIsAutoJoinEnabled = source.mIsAutoJoinEnabled; + mIsMacRandomizationEnabled = source.mIsMacRandomizationEnabled; } @Override @@ -531,6 +564,7 @@ public final class PasspointConfiguration implements Parcelable { dest.writeBundle(bundle); dest.writeInt(mCarrierId); dest.writeBoolean(mIsAutoJoinEnabled); + dest.writeBoolean(mIsMacRandomizationEnabled); } @Override @@ -562,6 +596,7 @@ public final class PasspointConfiguration implements Parcelable { && mUsageLimitTimeLimitInMinutes == that.mUsageLimitTimeLimitInMinutes && mCarrierId == that.mCarrierId && mIsAutoJoinEnabled == that.mIsAutoJoinEnabled + && mIsMacRandomizationEnabled == that.mIsMacRandomizationEnabled && (mServiceFriendlyNames == null ? that.mServiceFriendlyNames == null : mServiceFriendlyNames.equals(that.mServiceFriendlyNames)); } @@ -572,7 +607,7 @@ public final class PasspointConfiguration implements Parcelable { mUpdateIdentifier, mCredentialPriority, mSubscriptionCreationTimeInMillis, mSubscriptionExpirationTimeInMillis, mUsageLimitUsageTimePeriodInMinutes, mUsageLimitStartTimeInMillis, mUsageLimitDataLimit, mUsageLimitTimeLimitInMinutes, - mServiceFriendlyNames, mCarrierId, mIsAutoJoinEnabled); + mServiceFriendlyNames, mCarrierId, mIsAutoJoinEnabled, mIsMacRandomizationEnabled); } @Override @@ -627,6 +662,7 @@ public final class PasspointConfiguration implements Parcelable { } builder.append("CarrierId:" + mCarrierId); builder.append("IsAutoJoinEnabled:" + mIsAutoJoinEnabled); + builder.append("mIsMacRandomizationEnabled:" + mIsMacRandomizationEnabled); return builder.toString(); } @@ -733,6 +769,7 @@ public final class PasspointConfiguration implements Parcelable { config.setServiceFriendlyNames(friendlyNamesMap); config.mCarrierId = in.readInt(); config.mIsAutoJoinEnabled = in.readBoolean(); + config.mIsMacRandomizationEnabled = in.readBoolean(); return config; } diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index 3c13562d6952..1cf3825d2397 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -186,6 +186,11 @@ public class BaseWifiService extends IWifiManager.Stub { throw new UnsupportedOperationException(); } + @Override + public void setMacRandomizationSettingPasspointEnabled(String fqdn, boolean enable) { + throw new UnsupportedOperationException(); + } + @Override public boolean startScan(String packageName, String featureId) { throw new UnsupportedOperationException(); diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 5bdc34402cc4..983ac8216124 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -1706,6 +1706,17 @@ public class WifiManagerTest { verify(mWifiService).allowAutojoinPasspoint(fqdn, true); } + /** + * Test behavior of + * {@link WifiManager#setMacRandomizationSettingPasspointEnabled(String, boolean)} + */ + @Test + public void testSetMacRandomizationSettingPasspointEnabled() throws Exception { + final String fqdn = "FullyQualifiedDomainName"; + mWifiManager.setMacRandomizationSettingPasspointEnabled(fqdn, true); + verify(mWifiService).setMacRandomizationSettingPasspointEnabled(fqdn, true); + } + /** * Test behavior of {@link WifiManager#disconnect()} diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java index 94054fdde8da..603e78b90ff2 100644 --- a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java @@ -172,6 +172,7 @@ public class PasspointConfigurationTest { assertFalse(config.validate()); assertFalse(config.validateForR2()); assertTrue(config.isAutoJoinEnabled()); + assertTrue(config.isMacRandomizationEnabled()); } /** -- cgit v1.2.3 From 546ce5e45eadc6053d41545315f1ea6ca9a00ad4 Mon Sep 17 00:00:00 2001 From: Chen Xu Date: Fri, 10 Jan 2020 08:38:31 -0800 Subject: modularize telephony-framework from framework.jar Bug: 140908357 Test: Build & Manaul Change-Id: Idd4cbdb84247b98072b6ebc00a37168fde6fbbaa --- wifi/Android.bp | 1 + 1 file changed, 1 insertion(+) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 70c9befce66a..4c9ee854536e 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -70,6 +70,7 @@ java_library { "framework-annotations-lib", "unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage "unsupportedappusage-annotation", // for dalvik.annotation.compat.UnsupportedAppUsage + "framework-telephony-stubs", ], srcs: [ ":framework-wifi-updatable-sources", -- cgit v1.2.3 From 02432980d0430daf6334271042ea317e427ead11 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Thu, 16 Jan 2020 09:18:09 -0800 Subject: wifi-service: Jar-Jar net util sources Bug: 135998869 Test: Compiles Test: Number of compile errors when compiled against system_current reduces. Change-Id: I67d2a435e8fd8c823b6cb1bf4becb01362dcc5e0 --- wifi/jarjar-rules.txt | 3 +++ 1 file changed, 3 insertions(+) (limited to 'wifi') diff --git a/wifi/jarjar-rules.txt b/wifi/jarjar-rules.txt index 8f720407f4d7..d377ee69cade 100644 --- a/wifi/jarjar-rules.txt +++ b/wifi/jarjar-rules.txt @@ -1,5 +1,7 @@ rule android.net.InterfaceConfigurationParcel* @0 rule android.net.InterfaceConfiguration* com.android.server.x.wifi.net.InterfaceConfiguration@1 +rule android.net.NetworkFactory* com.android.server.x.wifi.net.NetworkFactory@1 +rule android.net.util.NetUtils* com.android.server.x.wifi.net.util.NetUtils@1 # We don't jar-jar the entire package because, we still use some classes (like # AsyncChannel in com.android.internal.util) from these packages which are not @@ -32,6 +34,7 @@ rule android.sysprop.** com.android.server.x.wifi.sysprop.@1 rule android.content.pm.BaseParceledListSlice* android.x.net.wifi.util.BaseParceledListSlice@1 rule android.content.pm.ParceledListSlice* android.x.net.wifi.util.ParceledListSlice@1 rule android.net.shared.Inet4AddressUtils* android.x.net.wifi.util.Inet4AddressUtils@1 +rule android.net.util.MacAddressUtils* android.x.net.wifi.util.MacAddressUtils@1 rule android.os.HandlerExecutor* android.x.net.wifi.util.HandlerExecutor@1 rule android.telephony.Annotation* android.x.net.wifi.util.TelephonyAnnotation@1 rule com.android.internal.util.AsyncChannel* android.x.net.wifi.util.AsyncChannel@1 -- cgit v1.2.3 From 5cb2b67abac3af188ee1bdafa3602094a9f20b6d Mon Sep 17 00:00:00 2001 From: Kai Shi Date: Mon, 13 Jan 2020 15:43:00 -0800 Subject: Wifi: add APIs to set/get max supported link speed Add the following APIs: getMaxSupportedTxLinkSpeed() setMaxSupportedTxLinkSpeed() getMaxSupportedRxLinkSpeed() setMaxSupportedRxLinkSpeed() Bug: 147390882 Test: atest android.net.wifi Test: manual test with various APs Change-Id: I7f3268b2842783f99c0a43d8b4996d0a7dd46c6e --- wifi/java/android/net/wifi/WifiInfo.java | 56 +++++++++++++++++++++++ wifi/tests/src/android/net/wifi/WifiInfoTest.java | 25 ++++++++++ 2 files changed, 81 insertions(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java index 51b15afec3ab..a207cbd72569 100644 --- a/wifi/java/android/net/wifi/WifiInfo.java +++ b/wifi/java/android/net/wifi/WifiInfo.java @@ -123,11 +123,21 @@ public class WifiInfo implements Parcelable { */ private int mTxLinkSpeed; + /** + * Max supported Tx(transmit) link speed in Mbps + */ + private int mMaxSupportedTxLinkSpeed; + /** * Rx(receive) Link speed in Mbps */ private int mRxLinkSpeed; + /** + * Max supported Rx(receive) link speed in Mbps + */ + private int mMaxSupportedRxLinkSpeed; + /** * Frequency in MHz */ @@ -303,6 +313,8 @@ public class WifiInfo implements Parcelable { setLinkSpeed(LINK_SPEED_UNKNOWN); setTxLinkSpeedMbps(LINK_SPEED_UNKNOWN); setRxLinkSpeedMbps(LINK_SPEED_UNKNOWN); + setMaxSupportedTxLinkSpeedMbps(LINK_SPEED_UNKNOWN); + setMaxSupportedRxLinkSpeedMbps(LINK_SPEED_UNKNOWN); setFrequency(-1); setMeteredHint(false); setEphemeral(false); @@ -356,6 +368,8 @@ public class WifiInfo implements Parcelable { mRxSuccessRate = source.mRxSuccessRate; score = source.score; mWifiStandard = source.mWifiStandard; + mMaxSupportedTxLinkSpeed = source.mMaxSupportedTxLinkSpeed; + mMaxSupportedRxLinkSpeed = source.mMaxSupportedRxLinkSpeed; } } @@ -551,6 +565,15 @@ public class WifiInfo implements Parcelable { return mTxLinkSpeed; } + /** + * Returns the maximum supported transmit link speed in Mbps + * @return the max supported tx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is + * unknown. @see #LINK_SPEED_UNKNOWN + */ + public int getMaxSupportedTxLinkSpeedMbps() { + return mMaxSupportedTxLinkSpeed; + } + /** * Update the last transmitted packet bit rate in Mbps. * @hide @@ -559,6 +582,14 @@ public class WifiInfo implements Parcelable { mTxLinkSpeed = txLinkSpeed; } + /** + * Set the maximum supported transmit link speed in Mbps + * @hide + */ + public void setMaxSupportedTxLinkSpeedMbps(int maxSupportedTxLinkSpeed) { + mMaxSupportedTxLinkSpeed = maxSupportedTxLinkSpeed; + } + /** * Returns the current receive link speed in Mbps. * @return the Rx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is unknown. @@ -569,6 +600,15 @@ public class WifiInfo implements Parcelable { return mRxLinkSpeed; } + /** + * Returns the maximum supported receive link speed in Mbps + * @return the max supported Rx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is + * unknown. @see #LINK_SPEED_UNKNOWN + */ + public int getMaxSupportedRxLinkSpeedMbps() { + return mMaxSupportedRxLinkSpeed; + } + /** * Update the last received packet bit rate in Mbps. * @hide @@ -577,6 +617,14 @@ public class WifiInfo implements Parcelable { mRxLinkSpeed = rxLinkSpeed; } + /** + * Set the maximum supported receive link speed in Mbps + * @hide + */ + public void setMaxSupportedRxLinkSpeedMbps(int maxSupportedRxLinkSpeed) { + mMaxSupportedRxLinkSpeed = maxSupportedRxLinkSpeed; + } + /** * Returns the current frequency in {@link #FREQUENCY_UNITS}. * @return the frequency. @@ -853,7 +901,11 @@ public class WifiInfo implements Parcelable { .append(", RSSI: ").append(mRssi) .append(", Link speed: ").append(mLinkSpeed).append(LINK_SPEED_UNITS) .append(", Tx Link speed: ").append(mTxLinkSpeed).append(LINK_SPEED_UNITS) + .append(", Max Supported Tx Link speed: ") + .append(mMaxSupportedTxLinkSpeed).append(LINK_SPEED_UNITS) .append(", Rx Link speed: ").append(mRxLinkSpeed).append(LINK_SPEED_UNITS) + .append(", Max Supported Rx Link speed: ") + .append(mMaxSupportedRxLinkSpeed).append(LINK_SPEED_UNITS) .append(", Frequency: ").append(mFrequency).append(FREQUENCY_UNITS) .append(", Net ID: ").append(mNetworkId) .append(", Metered hint: ").append(mMeteredHint) @@ -906,6 +958,8 @@ public class WifiInfo implements Parcelable { dest.writeString(mFqdn); dest.writeString(mProviderFriendlyName); dest.writeInt(mWifiStandard); + dest.writeInt(mMaxSupportedTxLinkSpeed); + dest.writeInt(mMaxSupportedRxLinkSpeed); } /** Implement the Parcelable interface {@hide} */ @@ -948,6 +1002,8 @@ public class WifiInfo implements Parcelable { info.mFqdn = in.readString(); info.mProviderFriendlyName = in.readString(); info.mWifiStandard = in.readInt(); + info.mMaxSupportedTxLinkSpeed = in.readInt(); + info.mMaxSupportedRxLinkSpeed = in.readInt(); return info; } diff --git a/wifi/tests/src/android/net/wifi/WifiInfoTest.java b/wifi/tests/src/android/net/wifi/WifiInfoTest.java index f7612341d4b3..af85ce05f23b 100644 --- a/wifi/tests/src/android/net/wifi/WifiInfoTest.java +++ b/wifi/tests/src/android/net/wifi/WifiInfoTest.java @@ -39,6 +39,8 @@ public class WifiInfoTest { private static final String TEST_FQDN = "test.com"; private static final String TEST_PROVIDER_NAME = "test"; private static final int TEST_WIFI_STANDARD = ScanResult.WIFI_STANDARD_11AC; + private static final int TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS = 866; + private static final int TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS = 1200; /** * Verify parcel write/read with WifiInfo. @@ -56,6 +58,8 @@ public class WifiInfoTest { writeWifiInfo.setProviderFriendlyName(TEST_PROVIDER_NAME); writeWifiInfo.setAppPackageName(TEST_PACKAGE_NAME); writeWifiInfo.setWifiStandard(TEST_WIFI_STANDARD); + writeWifiInfo.setMaxSupportedTxLinkSpeedMbps(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS); + writeWifiInfo.setMaxSupportedRxLinkSpeedMbps(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS); Parcel parcel = Parcel.obtain(); writeWifiInfo.writeToParcel(parcel, 0); @@ -75,5 +79,26 @@ public class WifiInfoTest { assertEquals(TEST_FQDN, readWifiInfo.getPasspointFqdn()); assertEquals(TEST_PROVIDER_NAME, readWifiInfo.getPasspointProviderFriendlyName()); assertEquals(TEST_WIFI_STANDARD, readWifiInfo.getWifiStandard()); + assertEquals(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS, + readWifiInfo.getMaxSupportedTxLinkSpeedMbps()); + assertEquals(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS, + readWifiInfo.getMaxSupportedRxLinkSpeedMbps()); + } + + /** + * Verify values after reset() + */ + @Test + public void testWifiInfoResetValue() throws Exception { + WifiInfo wifiInfo = new WifiInfo(); + wifiInfo.reset(); + assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getMaxSupportedTxLinkSpeedMbps()); + assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getMaxSupportedRxLinkSpeedMbps()); + assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getTxLinkSpeedMbps()); + assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getRxLinkSpeedMbps()); + assertEquals(WifiInfo.INVALID_RSSI, wifiInfo.getRssi()); + assertEquals(WifiManager.UNKNOWN_SSID, wifiInfo.getSSID()); + assertEquals(null, wifiInfo.getBSSID()); + assertEquals(-1, wifiInfo.getNetworkId()); } } -- cgit v1.2.3 From 6c82ddd6881ae5a2bf7348a6dd2a80661a6e9c62 Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 16 Jan 2020 20:53:04 -0800 Subject: Jarjar DnsSdTxtRecord into framework-wifi DnsSdTxtRecord is @hide, thus need to statically link it into framework-wifi and rename it to prevent duplicate classes on the classpath. Bug: 135998869 Test: boots up and connects to wifi Change-Id: I018a8c2e8b124b11077db631e643c751a73394c5 --- wifi/jarjar-rules.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'wifi') diff --git a/wifi/jarjar-rules.txt b/wifi/jarjar-rules.txt index d377ee69cade..950361c1b244 100644 --- a/wifi/jarjar-rules.txt +++ b/wifi/jarjar-rules.txt @@ -35,6 +35,7 @@ rule android.content.pm.BaseParceledListSlice* android.x.net.wifi.util.BaseParce rule android.content.pm.ParceledListSlice* android.x.net.wifi.util.ParceledListSlice@1 rule android.net.shared.Inet4AddressUtils* android.x.net.wifi.util.Inet4AddressUtils@1 rule android.net.util.MacAddressUtils* android.x.net.wifi.util.MacAddressUtils@1 +rule android.net.util.nsd.DnsSdTxtRecord* android.x.net.wifi.util.nsd.DnsSdTxtRecord@1 rule android.os.HandlerExecutor* android.x.net.wifi.util.HandlerExecutor@1 rule android.telephony.Annotation* android.x.net.wifi.util.TelephonyAnnotation@1 rule com.android.internal.util.AsyncChannel* android.x.net.wifi.util.AsyncChannel@1 -- cgit v1.2.3 From ec6f8ce6fdde7a16e9d5cb2af93fb9b635909f3e Mon Sep 17 00:00:00 2001 From: Mingguang Xu Date: Fri, 20 Dec 2019 16:11:07 -0800 Subject: Extension API: Create System APIs to allow OEM module to override WiFi scorer in AOSP Create WiFi scorer interface and score change callback interface in WifiManager; Define register and unregister methods for WiFi scorer. Test: atest android.net.wifi Bug: 135573686, 122133502, 136312816, 135572156 Change-Id: Ib51d877a463d1f69b31b9743917ea1b3590a30f7 Signed-off-by: Mingguang Xu --- .../android/net/wifi/IScoreChangeCallback.aidl | 29 ++++ .../net/wifi/IWifiConnectedNetworkScorer.aidl | 33 ++++ wifi/java/android/net/wifi/IWifiManager.aidl | 5 + wifi/java/android/net/wifi/WifiManager.java | 182 +++++++++++++++++++++ .../com/android/server/wifi/BaseWifiService.java | 12 ++ .../src/android/net/wifi/WifiManagerTest.java | 61 +++++++ 6 files changed, 322 insertions(+) create mode 100644 wifi/java/android/net/wifi/IScoreChangeCallback.aidl create mode 100644 wifi/java/android/net/wifi/IWifiConnectedNetworkScorer.aidl (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IScoreChangeCallback.aidl b/wifi/java/android/net/wifi/IScoreChangeCallback.aidl new file mode 100644 index 000000000000..fd236107bc6e --- /dev/null +++ b/wifi/java/android/net/wifi/IScoreChangeCallback.aidl @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2020 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 network score callback. + * + * @hide + */ +oneway interface IScoreChangeCallback +{ + void onStatusChange(int sessionId, boolean exiting); + + void onTriggerUpdateOfWifiUsabilityStats(int sessionId); +} diff --git a/wifi/java/android/net/wifi/IWifiConnectedNetworkScorer.aidl b/wifi/java/android/net/wifi/IWifiConnectedNetworkScorer.aidl new file mode 100644 index 000000000000..d9a3b0109a09 --- /dev/null +++ b/wifi/java/android/net/wifi/IWifiConnectedNetworkScorer.aidl @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2020 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.IScoreChangeCallback; + +/** + * Interface for Wi-Fi connected network scorer. + * + * @hide + */ +oneway interface IWifiConnectedNetworkScorer +{ + void start(int sessionId); + + void stop(int sessionId); + + void setScoreChangeCallback(IScoreChangeCallback cbImpl); +} diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index f490766559de..04fc4770da38 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -35,6 +35,7 @@ import android.net.wifi.ISoftApCallback; import android.net.wifi.ISuggestionConnectionStatusListener; import android.net.wifi.ITrafficStateCallback; import android.net.wifi.ITxPacketCountListener; +import android.net.wifi.IWifiConnectedNetworkScorer; import android.net.wifi.ScanResult; import android.net.wifi.SoftApConfiguration; import android.net.wifi.WifiConfiguration; @@ -252,4 +253,8 @@ interface IWifiManager int calculateSignalLevel(int rssi); List getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(in List scanResults); + + boolean setWifiConnectedNetworkScorer(in IBinder binder, in IWifiConnectedNetworkScorer scorer); + + void clearWifiConnectedNetworkScorer(); } diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index a8a31eba303c..faee9c663550 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -5777,4 +5777,186 @@ public class WifiManager { return new SparseArray<>(); } } + + /** + * Callback interface for framework to receive network status changes and trigger of updating + * {@link WifiUsabilityStatsEntry}. + * + * @hide + */ + @SystemApi + public interface ScoreChangeCallback { + /** + * Called by applications to indicate network status. + * + * @param sessionId The ID to indicate current Wi-Fi network connection obtained from + * {@link WifiConnectedNetworkScorer#start(int)}. + * @param isUsable The bit to indicate whether current Wi-Fi network is usable or not. + * Populated by connected network scorer in applications. + */ + void onStatusChange(int sessionId, boolean isUsable); + + /** + * Called by applications to trigger an update of {@link WifiUsabilityStatsEntry}. + * To receive update applications need to add WifiUsabilityStatsEntry listener. See + * {@link addOnWifiUsabilityStatsListener(Executor, OnWifiUsabilityStatsListener)}. + * + * @param sessionId The ID to indicate current Wi-Fi network connection obtained from + * {@link WifiConnectedNetworkScorer#start(int)}. + */ + void onTriggerUpdateOfWifiUsabilityStats(int sessionId); + } + + /** + * Callback proxy for {@link ScoreChangeCallback} objects. + * + * @hide + */ + private class ScoreChangeCallbackProxy implements ScoreChangeCallback { + private final IScoreChangeCallback mScoreChangeCallback; + + private ScoreChangeCallbackProxy(IScoreChangeCallback callback) { + mScoreChangeCallback = callback; + } + + @Override + public void onStatusChange(int sessionId, boolean isUsable) { + try { + mScoreChangeCallback.onStatusChange(sessionId, isUsable); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + @Override + public void onTriggerUpdateOfWifiUsabilityStats(int sessionId) { + try { + mScoreChangeCallback.onTriggerUpdateOfWifiUsabilityStats(sessionId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + } + + /** + * Interface for Wi-Fi connected network scorer. Should be implemented by applications and set + * when calling + * {@link WifiManager#setWifiConnectedNetworkScorer(Executor, WifiConnectedNetworkScorer)}. + * + * @hide + */ + @SystemApi + public interface WifiConnectedNetworkScorer { + /** + * Called by framework to indicate the start of a network connection. + * @param sessionId The ID to indicate current Wi-Fi network connection. + */ + void start(int sessionId); + + /** + * Called by framework to indicate the end of a network connection. + * @param sessionId The ID to indicate current Wi-Fi network connection obtained from + * {@link WifiConnectedNetworkScorer#start(int)}. + */ + void stop(int sessionId); + + /** + * Framework sets callback for score change events after application sets its scorer. + * @param cbImpl The instance for {@link WifiManager#ScoreChangeCallback}. Should be + * implemented and instantiated by framework. + */ + void setScoreChangeCallback(@NonNull ScoreChangeCallback cbImpl); + } + + /** + * Callback proxy for {@link WifiConnectedNetworkScorer} objects. + * + * @hide + */ + private class WifiConnectedNetworkScorerProxy extends IWifiConnectedNetworkScorer.Stub { + private Executor mExecutor; + private WifiConnectedNetworkScorer mScorer; + + WifiConnectedNetworkScorerProxy(Executor executor, WifiConnectedNetworkScorer scorer) { + mExecutor = executor; + mScorer = scorer; + } + + @Override + public void start(int sessionId) { + if (mVerboseLoggingEnabled) { + Log.v(TAG, "WifiConnectedNetworkScorer: " + "start: sessionId=" + sessionId); + } + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mScorer.start(sessionId)); + } + + @Override + public void stop(int sessionId) { + if (mVerboseLoggingEnabled) { + Log.v(TAG, "WifiConnectedNetworkScorer: " + "stop: sessionId=" + sessionId); + } + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mScorer.stop(sessionId)); + } + + @Override + public void setScoreChangeCallback(IScoreChangeCallback cbImpl) { + if (mVerboseLoggingEnabled) { + Log.v(TAG, "WifiConnectedNetworkScorer: " + + "setScoreChangeCallback: cbImpl=" + cbImpl); + } + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mScorer.setScoreChangeCallback( + new ScoreChangeCallbackProxy(cbImpl))); + } + } + + /** + * Set a callback for Wi-Fi connected network scorer. See {@link WifiConnectedNetworkScorer}. + * Only a single scorer can be set. Caller will be invoked periodically by framework to inform + * client about start and stop of Wi-Fi connection. Caller can clear a previously set scorer + * using {@link clearWifiConnectedNetworkScorer()}. + * + * @param executor The executor on which callback will be invoked. + * @param scorer Scorer for Wi-Fi network implemented by application. + * @return true Scorer is set successfully. + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) + public boolean setWifiConnectedNetworkScorer(@NonNull @CallbackExecutor Executor executor, + @NonNull WifiConnectedNetworkScorer scorer) { + if (executor == null) throw new IllegalArgumentException("executor cannot be null"); + if (scorer == null) throw new IllegalArgumentException("scorer cannot be null"); + if (mVerboseLoggingEnabled) { + Log.v(TAG, "setWifiConnectedNetworkScorer: scorer=" + scorer); + } + try { + return mService.setWifiConnectedNetworkScorer(new Binder(), + new WifiConnectedNetworkScorerProxy(executor, scorer)); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Allow caller to clear a previously set scorer. After calling this method, + * client will no longer receive information about start and stop of Wi-Fi connection. + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) + public void clearWifiConnectedNetworkScorer() { + if (mVerboseLoggingEnabled) { + Log.v(TAG, "clearWifiConnectedNetworkScorer"); + } + try { + mService.clearWifiConnectedNetworkScorer(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } } diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index 3c13562d6952..69af719bab52 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -32,6 +32,7 @@ import android.net.wifi.ISoftApCallback; import android.net.wifi.ISuggestionConnectionStatusListener; import android.net.wifi.ITrafficStateCallback; import android.net.wifi.ITxPacketCountListener; +import android.net.wifi.IWifiConnectedNetworkScorer; import android.net.wifi.IWifiManager; import android.net.wifi.ScanResult; import android.net.wifi.SoftApConfiguration; @@ -595,4 +596,15 @@ public class BaseWifiService extends IWifiManager.Stub { List scanResults) { throw new UnsupportedOperationException(); } + + @Override + public boolean setWifiConnectedNetworkScorer(IBinder binder, + IWifiConnectedNetworkScorer scorer) { + throw new UnsupportedOperationException(); + } + + @Override + public void clearWifiConnectedNetworkScorer() { + throw new UnsupportedOperationException(); + } } diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 5bdc34402cc4..58cfba848375 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -82,6 +82,7 @@ import android.net.wifi.WifiManager.ScanResultsCallback; import android.net.wifi.WifiManager.SoftApCallback; import android.net.wifi.WifiManager.SuggestionConnectionStatusListener; import android.net.wifi.WifiManager.TrafficStateCallback; +import android.net.wifi.WifiManager.WifiConnectedNetworkScorer; import android.os.Binder; import android.os.Build; import android.os.Handler; @@ -138,6 +139,7 @@ public class WifiManagerTest { @Mock Executor mExecutor; @Mock Executor mAnotherExecutor; @Mock ActivityManager mActivityManager; + @Mock WifiConnectedNetworkScorer mWifiConnectedNetworkScorer; private Handler mHandler; private TestLooper mLooper; @@ -2219,4 +2221,63 @@ public class WifiManagerTest { assertEquals(testResults, mWifiManager .getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(new ArrayList<>())); } + + /** + * Verify the call to setWifiConnectedNetworkScorer goes to WifiServiceImpl. + */ + @Test + public void setWifiConnectedNetworkScorerGoesToWifiServiceImpl() throws Exception { + mExecutor = new SynchronousExecutor(); + mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer); + verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class), + any(IWifiConnectedNetworkScorer.Stub.class)); + } + + /** + * Verify the call to clearWifiConnectedNetworkScorer goes to WifiServiceImpl. + */ + @Test + public void clearWifiConnectedNetworkScorerGoesToWifiServiceImpl() throws Exception { + mExecutor = new SynchronousExecutor(); + mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer); + verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class), + any(IWifiConnectedNetworkScorer.Stub.class)); + + mWifiManager.clearWifiConnectedNetworkScorer(); + verify(mWifiService).clearWifiConnectedNetworkScorer(); + } + + /** + * Verify that Wi-Fi connected scorer receives score change callback after registeration. + */ + @Test + public void verifyScorerReceiveScoreChangeCallbackAfterRegistration() throws Exception { + mExecutor = new SynchronousExecutor(); + mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer); + ArgumentCaptor scorerCaptor = + ArgumentCaptor.forClass(IWifiConnectedNetworkScorer.Stub.class); + verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class), + scorerCaptor.capture()); + scorerCaptor.getValue().setScoreChangeCallback(any()); + mLooper.dispatchAll(); + verify(mWifiConnectedNetworkScorer).setScoreChangeCallback(any()); + } + + /** + * Verify that Wi-Fi connected scorer receives session ID when start/stop methods are called. + */ + @Test + public void verifyScorerReceiveSessionIdWhenStartStopIsCalled() throws Exception { + mExecutor = new SynchronousExecutor(); + mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer); + ArgumentCaptor callbackCaptor = + ArgumentCaptor.forClass(IWifiConnectedNetworkScorer.Stub.class); + verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class), + callbackCaptor.capture()); + callbackCaptor.getValue().start(0); + callbackCaptor.getValue().stop(10); + mLooper.dispatchAll(); + verify(mWifiConnectedNetworkScorer).start(0); + verify(mWifiConnectedNetworkScorer).stop(10); + } } -- cgit v1.2.3 From 64232b7571b8f9e94d2537d7e1030508402c010c Mon Sep 17 00:00:00 2001 From: lesl Date: Mon, 13 Jan 2020 15:20:23 +0800 Subject: SoftAp: Public SoftApConfiguration to replace WifiConfiguration Bug: 142752869 Test: atest frameworks/base/wifi/tests/ Change-Id: I82be10b8083162b6cf179e12a2a93b1eb669547a --- .../java/android/net/wifi/SoftApConfiguration.java | 47 +++++++++++++++++----- 1 file changed, 36 insertions(+), 11 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java index a77d30a18817..1da9aad7cc39 100644 --- a/wifi/java/android/net/wifi/SoftApConfiguration.java +++ b/wifi/java/android/net/wifi/SoftApConfiguration.java @@ -54,13 +54,12 @@ import java.util.concurrent.Executor; * Instances of this class are immutable; use {@link SoftApConfiguration.Builder} and its methods to * create a new instance. * - * @hide */ -@SystemApi public final class SoftApConfiguration implements Parcelable { @VisibleForTesting static final int PSK_MIN_LEN = 8; + @VisibleForTesting static final int PSK_MAX_LEN = 63; @@ -207,22 +206,24 @@ public final class SoftApConfiguration implements Parcelable { private final int mShutdownTimeoutMillis; /** - * Security types we support. + * THe definition of security type OPEN. */ - /** @hide */ - @SystemApi public static final int SECURITY_TYPE_OPEN = 0; - /** @hide */ - @SystemApi + + /** + * The definition of security type WPA2-PSK. + */ public static final int SECURITY_TYPE_WPA2_PSK = 1; - /** @hide */ - @SystemApi + /** + * The definition of security type WPA3-SAE Transition mode. + */ public static final int SECURITY_TYPE_WPA3_SAE_TRANSITION = 2; - /** @hide */ - @SystemApi + /** + * The definition of security type WPA3-SAE. + */ public static final int SECURITY_TYPE_WPA3_SAE = 3; /** @hide */ @@ -383,7 +384,10 @@ public final class SoftApConfiguration implements Parcelable { /** * Returns {@link BandType} set to be the band for the AP. * {@link Builder#setBand(@BandType int)}. + * + * @hide */ + @SystemApi public @BandType int getBand() { return mBand; } @@ -391,7 +395,10 @@ public final class SoftApConfiguration implements Parcelable { /** * Returns Integer set to be the channel for the AP. * {@link Builder#setChannel(int)}. + * + * @hide */ + @SystemApi public int getChannel() { return mChannel; } @@ -408,7 +415,10 @@ public final class SoftApConfiguration implements Parcelable { /** * Returns the maximum number of clients that can associate to the AP. * {@link Builder#setMaxNumberOfClients(int)}. + * + * @hide */ + @SystemApi public int getMaxNumberOfClients() { return mMaxNumberOfClients; } @@ -417,7 +427,10 @@ public final class SoftApConfiguration implements Parcelable { * Returns the shutdown timeout in milliseconds. * The Soft AP will shutdown when there are no devices associated to it for * the timeout duration. See {@link Builder#setShutdownTimeoutMillis(int)}. + * + * @hide */ + @SystemApi public int getShutdownTimeoutMillis() { return mShutdownTimeoutMillis; } @@ -426,7 +439,10 @@ public final class SoftApConfiguration implements Parcelable { * Returns a flag indicating whether clients need to be pre-approved by the user. * (true: authorization required) or not (false: not required). * {@link Builder#enableClientControlByUser(Boolean)}. + * + * @hide */ + @SystemApi public boolean isClientControlByUserEnabled() { return mClientControlByUser; } @@ -435,8 +451,11 @@ public final class SoftApConfiguration implements Parcelable { * Returns List of clients which aren't allowed to associate to the AP. * * Clients are configured using {@link Builder#setClientList(List, List)} + * + * @hide */ @NonNull + @SystemApi public List getBlockedClientList() { return mBlockedClientList; } @@ -444,8 +463,11 @@ public final class SoftApConfiguration implements Parcelable { /** * List of clients which are allowed to associate to the AP. * Clients are configured using {@link Builder#setClientList(List, List)} + * + * @hide */ @NonNull + @SystemApi public List getAllowedClientList() { return mAllowedClientList; } @@ -456,7 +478,10 @@ public final class SoftApConfiguration implements Parcelable { * * All fields are optional. By default, SSID and BSSID are automatically chosen by the * framework, and an open network is created. + * + * @hide */ + @SystemApi public static final class Builder { private String mSsid; private MacAddress mBssid; -- cgit v1.2.3 From 115873a18baa395fa100eeb62e4060a657fa3303 Mon Sep 17 00:00:00 2001 From: lesl Date: Wed, 15 Jan 2020 14:51:26 +0800 Subject: softap: Update LOHS API usage Use SoftApConfiguration to replace WifiConfiguration 1. Deprecate public old getWifiConfiguration API. 2. Add new API getSoftApConfiguration in LocalOnlyHotspotReservation The new security type SAE and SAE Transition mode support in Soft Ap, Return null config when LOHS enable and security type is SAE or SAE Transition mode. Bug: 138801922 Bug: 142752869 Test: atest frameworks/base/wifi/tests/ Test: atest android.net.wifi.cts.WifiManagerTest#testStartLocalOnlyHotspotSingleRequestByApps Test: atest android.net.wifi.cts.WifiManagerTest#testStartLocalOnlyHotspotSuccess Test: atest android.net.wifi.cts.WifiManagerTest#testStartLocalOnlyHotspotWithConfig Change-Id: I32fbceff03b3821dde4f05356abb7f1645b90127 --- .../net/wifi/ILocalOnlyHotspotCallback.aidl | 4 +- wifi/java/android/net/wifi/WifiManager.java | 68 +++++++++-- .../src/android/net/wifi/WifiManagerTest.java | 133 +++++++++++++++++---- 3 files changed, 172 insertions(+), 33 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl b/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl index b83b594c8cb9..b567f29660a7 100644 --- a/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl +++ b/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl @@ -16,7 +16,7 @@ package android.net.wifi; -import android.net.wifi.WifiConfiguration; +import android.net.wifi.SoftApConfiguration; /** * Communicates LOHS status back to the application process. @@ -24,7 +24,7 @@ import android.net.wifi.WifiConfiguration; * @hide */ oneway interface ILocalOnlyHotspotCallback { - void onHotspotStarted(in WifiConfiguration config); + void onHotspotStarted(in SoftApConfiguration config); void onHotspotStopped(); void onHotspotFailed(int reason); } diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 95401032219d..c371825d9c76 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -2971,7 +2971,7 @@ public class WifiManager { * Each application can make a single active call to this method. The {@link * LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} callback supplies the * requestor with a {@link LocalOnlyHotspotReservation} that contains a - * {@link WifiConfiguration} with the SSID, security type and credentials needed to connect + * {@link SoftApConfiguration} with the SSID, security type and credentials needed to connect * to the hotspot. Communicating this information is up to the application. *

    * If the LocalOnlyHotspot cannot be created, the {@link LocalOnlyHotspotCallback#onFailed(int)} @@ -3136,7 +3136,7 @@ public class WifiManager { * Allow callers (Settings UI) to watch LocalOnlyHotspot state changes. Callers will * receive a {@link LocalOnlyHotspotSubscription} object as a parameter of the * {@link LocalOnlyHotspotObserver#onRegistered(LocalOnlyHotspotSubscription)}. The registered - * callers will receive the {@link LocalOnlyHotspotObserver#onStarted(WifiConfiguration)} and + * callers will receive the {@link LocalOnlyHotspotObserver#onStarted(SoftApConfiguration)} and * {@link LocalOnlyHotspotObserver#onStopped()} callbacks. *

    * Applications should have the @@ -3711,13 +3711,13 @@ public class WifiManager { } /** - * LocalOnlyHotspotReservation that contains the {@link WifiConfiguration} for the active + * LocalOnlyHotspotReservation that contains the {@link SoftApConfiguration} for the active * LocalOnlyHotspot request. *

    * Applications requesting LocalOnlyHotspot for sharing will receive an instance of the * LocalOnlyHotspotReservation in the * {@link LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} call. This - * reservation contains the relevant {@link WifiConfiguration}. + * reservation contains the relevant {@link SoftApConfiguration}. * When an application is done with the LocalOnlyHotspot, they should call {@link * LocalOnlyHotspotReservation#close()}. Once this happens, the application will not receive * any further callbacks. If the LocalOnlyHotspot is stopped due to a @@ -3727,20 +3727,70 @@ public class WifiManager { public class LocalOnlyHotspotReservation implements AutoCloseable { private final CloseGuard mCloseGuard = new CloseGuard(); - private final WifiConfiguration mConfig; + private final SoftApConfiguration mConfig; private boolean mClosed = false; /** @hide */ @VisibleForTesting - public LocalOnlyHotspotReservation(WifiConfiguration config) { + public LocalOnlyHotspotReservation(SoftApConfiguration config) { mConfig = config; mCloseGuard.open("close"); } + /** + * Returns the {@link WifiConfiguration} of the current Local Only Hotspot (LOHS). + * May be null if hotspot enabled and security type is not + * {@link WifiConfiguration.KeyMgmt.None} or {@link WifiConfiguration.KeyMgmt.WPA2_PSK}. + * + * @deprecated Use {@link getSoftApConfiguration()} to get the LOHS configuration. + */ + @Deprecated + @Nullable public WifiConfiguration getWifiConfiguration() { + return convertToWifiConfiguration(mConfig); + } + + /** + * Returns the {@link SoftapConfiguration} of the current Local Only Hotspot (LOHS). + */ + @NonNull + public SoftApConfiguration getSoftApConfiguration() { return mConfig; } + /** + * Convert to WifiConfiguration from SoftApConfuration. + * + * Copy to the filed which is public and used by SoftAp. + */ + private WifiConfiguration convertToWifiConfiguration(SoftApConfiguration softApConfig) { + if (softApConfig == null) return null; + + WifiConfiguration wifiConfig = new WifiConfiguration(); + wifiConfig.networkId = WifiConfiguration.LOCAL_ONLY_NETWORK_ID; + wifiConfig.SSID = softApConfig.getSsid(); + if (softApConfig.getBssid() != null) { + wifiConfig.BSSID = softApConfig.getBssid().toString(); + } + wifiConfig.preSharedKey = softApConfig.getPassphrase(); + wifiConfig.hiddenSSID = softApConfig.isHiddenSsid(); + int authType = softApConfig.getSecurityType(); + switch (authType) { + case SoftApConfiguration.SECURITY_TYPE_OPEN: + authType = WifiConfiguration.KeyMgmt.NONE; + wifiConfig.allowedKeyManagement.set(authType); + break; + case SoftApConfiguration.SECURITY_TYPE_WPA2_PSK: + authType = WifiConfiguration.KeyMgmt.WPA2_PSK; + wifiConfig.allowedKeyManagement.set(authType); + break; + default: + wifiConfig = null; + break; + } + return wifiConfig; + } + @Override public void close() { try { @@ -3835,7 +3885,7 @@ public class WifiManager { } @Override - public void onHotspotStarted(WifiConfiguration config) { + public void onHotspotStarted(SoftApConfiguration config) { WifiManager manager = mWifiManager.get(); if (manager == null) return; @@ -3927,7 +3977,7 @@ public class WifiManager { /** * LocalOnlyHotspot started with the supplied config. */ - public void onStarted(WifiConfiguration config) {}; + public void onStarted(SoftApConfiguration config) {}; /** * LocalOnlyHotspot stopped. @@ -3967,7 +4017,7 @@ public class WifiManager { } @Override - public void onHotspotStarted(WifiConfiguration config) { + public void onHotspotStarted(SoftApConfiguration config) { WifiManager manager = mWifiManager.get(); if (manager == null) return; diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 5bdc34402cc4..d59cfe4a68aa 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -105,6 +105,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.Executor; /** @@ -146,6 +147,50 @@ public class WifiManagerTest { private ScanResultsCallback mScanResultsCallback; private WifiActivityEnergyInfo mWifiActivityEnergyInfo; + /** + * Util function to check public field which used for softap in WifiConfiguration + * same as the value in SoftApConfiguration. + * + */ + private boolean compareWifiAndSoftApConfiguration( + SoftApConfiguration softApConfig, WifiConfiguration wifiConfig) { + if (!Objects.equals(wifiConfig.SSID, softApConfig.getSsid())) { + return false; + } + if (!Objects.equals(wifiConfig.BSSID, softApConfig.getBssid())) { + return false; + } + if (!Objects.equals(wifiConfig.preSharedKey, softApConfig.getPassphrase())) { + return false; + } + + if (wifiConfig.hiddenSSID != softApConfig.isHiddenSsid()) { + return false; + } + switch (softApConfig.getSecurityType()) { + case SoftApConfiguration.SECURITY_TYPE_OPEN: + if (wifiConfig.getAuthType() != WifiConfiguration.KeyMgmt.NONE) { + return false; + } + break; + case SoftApConfiguration.SECURITY_TYPE_WPA2_PSK: + if (wifiConfig.getAuthType() != WifiConfiguration.KeyMgmt.WPA2_PSK) { + return false; + } + break; + default: + return false; + } + return true; + } + + private SoftApConfiguration generatorTestSoftApConfig() { + return new SoftApConfiguration.Builder() + .setSsid("TestSSID") + .setPassphrase("TestPassphrase", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) + .build(); + } + @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); @@ -210,12 +255,12 @@ public class WifiManagerTest { */ @Test public void testStartTetheredHotspotCallsServiceWithSoftApConfig() throws Exception { - SoftApConfiguration mSoftApConfig = new SoftApConfiguration.Builder().build(); - when(mWifiService.startTetheredHotspot(eq(mSoftApConfig))).thenReturn(true); - assertTrue(mWifiManager.startTetheredHotspot(mSoftApConfig)); + SoftApConfiguration softApConfig = generatorTestSoftApConfig(); + when(mWifiService.startTetheredHotspot(eq(softApConfig))).thenReturn(true); + assertTrue(mWifiManager.startTetheredHotspot(softApConfig)); - when(mWifiService.startTetheredHotspot(eq(mSoftApConfig))).thenReturn(false); - assertFalse(mWifiManager.startTetheredHotspot(mSoftApConfig)); + when(mWifiService.startTetheredHotspot(eq(softApConfig))).thenReturn(false); + assertFalse(mWifiManager.startTetheredHotspot(softApConfig)); } /** @@ -237,14 +282,18 @@ public class WifiManagerTest { */ @Test public void testCreationAndCloseOfLocalOnlyHotspotReservation() throws Exception { + SoftApConfiguration softApConfig = generatorTestSoftApConfig(); TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); - callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(mApConfig)); + callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(softApConfig)); + + assertEquals(softApConfig, callback.mRes.getSoftApConfiguration()); + WifiConfiguration wifiConfig = callback.mRes.getWifiConfiguration(); + assertTrue(compareWifiAndSoftApConfiguration(softApConfig, wifiConfig)); - assertEquals(mApConfig, callback.mRes.getWifiConfiguration()); callback.mRes.close(); verify(mWifiService).stopLocalOnlyHotspot(); } @@ -255,15 +304,18 @@ public class WifiManagerTest { @Test public void testLocalOnlyHotspotReservationCallsStopProperlyInTryWithResources() throws Exception { + SoftApConfiguration softApConfig = generatorTestSoftApConfig(); TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); - callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(mApConfig)); + callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(softApConfig)); try (WifiManager.LocalOnlyHotspotReservation res = callback.mRes) { - assertEquals(mApConfig, res.getWifiConfiguration()); + assertEquals(softApConfig, res.getSoftApConfiguration()); + WifiConfiguration wifiConfig = callback.mRes.getWifiConfiguration(); + assertTrue(compareWifiAndSoftApConfiguration(softApConfig, wifiConfig)); } verify(mWifiService).stopLocalOnlyHotspot(); @@ -313,6 +365,7 @@ public class WifiManagerTest { */ @Test public void testLocalOnlyHotspotCallback() { + SoftApConfiguration softApConfig = generatorTestSoftApConfig(); TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); assertFalse(callback.mOnStartedCalled); assertFalse(callback.mOnStoppedCalled); @@ -321,7 +374,7 @@ public class WifiManagerTest { // test onStarted WifiManager.LocalOnlyHotspotReservation res = - mWifiManager.new LocalOnlyHotspotReservation(mApConfig); + mWifiManager.new LocalOnlyHotspotReservation(softApConfig); callback.onStarted(res); assertEquals(res, callback.mRes); assertTrue(callback.mOnStartedCalled); @@ -347,7 +400,7 @@ public class WifiManagerTest { public boolean mOnRegistered = false; public boolean mOnStartedCalled = false; public boolean mOnStoppedCalled = false; - public WifiConfiguration mConfig = null; + public SoftApConfiguration mConfig = null; public LocalOnlyHotspotSubscription mSub = null; public long mCallingThreadId = -1; @@ -359,7 +412,7 @@ public class WifiManagerTest { } @Override - public void onStarted(WifiConfiguration config) { + public void onStarted(SoftApConfiguration config) { mOnStartedCalled = true; mConfig = config; mCallingThreadId = Thread.currentThread().getId(); @@ -378,6 +431,7 @@ public class WifiManagerTest { @Test public void testLocalOnlyHotspotObserver() { TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver(); + SoftApConfiguration softApConfig = generatorTestSoftApConfig(); assertFalse(observer.mOnRegistered); assertFalse(observer.mOnStartedCalled); assertFalse(observer.mOnStoppedCalled); @@ -393,18 +447,18 @@ public class WifiManagerTest { assertEquals(null, observer.mConfig); assertEquals(sub, observer.mSub); - observer.onStarted(mApConfig); + observer.onStarted(softApConfig); assertTrue(observer.mOnRegistered); assertTrue(observer.mOnStartedCalled); assertFalse(observer.mOnStoppedCalled); - assertEquals(mApConfig, observer.mConfig); + assertEquals(softApConfig, observer.mConfig); assertEquals(sub, observer.mSub); observer.onStopped(); assertTrue(observer.mOnRegistered); assertTrue(observer.mOnStartedCalled); assertTrue(observer.mOnStoppedCalled); - assertEquals(mApConfig, observer.mConfig); + assertEquals(softApConfig, observer.mConfig); assertEquals(sub, observer.mSub); } @@ -486,6 +540,39 @@ public class WifiManagerTest { */ @Test public void testOnStartedIsCalledWithReservation() throws Exception { + SoftApConfiguration softApConfig = generatorTestSoftApConfig(); + TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); + TestLooper callbackLooper = new TestLooper(); + Handler callbackHandler = new Handler(callbackLooper.getLooper()); + ArgumentCaptor internalCallback = + ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); + when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(), + nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED); + mWifiManager.startLocalOnlyHotspot(callback, callbackHandler); + callbackLooper.dispatchAll(); + mLooper.dispatchAll(); + assertFalse(callback.mOnStartedCalled); + assertEquals(null, callback.mRes); + // now trigger the callback + internalCallback.getValue().onHotspotStarted(softApConfig); + mLooper.dispatchAll(); + callbackLooper.dispatchAll(); + assertTrue(callback.mOnStartedCalled); + assertEquals(softApConfig, callback.mRes.getSoftApConfiguration()); + WifiConfiguration wifiConfig = callback.mRes.getWifiConfiguration(); + assertTrue(compareWifiAndSoftApConfiguration(softApConfig, wifiConfig)); + } + + /** + * Verify the LOHS onStarted callback is triggered when WifiManager receives a HOTSPOT_STARTED + * message from WifiServiceImpl when softap enabled with SAE security type. + */ + @Test + public void testOnStartedIsCalledWithReservationAndSaeSoftApConfig() throws Exception { + SoftApConfiguration softApConfig = new SoftApConfiguration.Builder() + .setSsid("TestSSID") + .setPassphrase("TestPassphrase", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE) + .build(); TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); TestLooper callbackLooper = new TestLooper(); Handler callbackHandler = new Handler(callbackLooper.getLooper()); @@ -499,11 +586,12 @@ public class WifiManagerTest { assertFalse(callback.mOnStartedCalled); assertEquals(null, callback.mRes); // now trigger the callback - internalCallback.getValue().onHotspotStarted(mApConfig); + internalCallback.getValue().onHotspotStarted(softApConfig); mLooper.dispatchAll(); callbackLooper.dispatchAll(); assertTrue(callback.mOnStartedCalled); - assertEquals(mApConfig, callback.mRes.getWifiConfiguration()); + assertEquals(softApConfig, callback.mRes.getSoftApConfiguration()); + assertEquals(null, callback.mRes.getWifiConfiguration()); } /** @@ -1035,6 +1123,7 @@ public class WifiManagerTest { */ @Test public void testObserverOnStartedIsCalledWithWifiConfig() throws Exception { + SoftApConfiguration softApConfig = generatorTestSoftApConfig(); TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver(); TestLooper observerLooper = new TestLooper(); Handler observerHandler = new Handler(observerLooper.getLooper()); @@ -1046,11 +1135,11 @@ public class WifiManagerTest { mLooper.dispatchAll(); assertFalse(observer.mOnStartedCalled); // now trigger the callback - internalCallback.getValue().onHotspotStarted(mApConfig); + internalCallback.getValue().onHotspotStarted(softApConfig); mLooper.dispatchAll(); observerLooper.dispatchAll(); assertTrue(observer.mOnStartedCalled); - assertEquals(mApConfig, observer.mConfig); + assertEquals(softApConfig, observer.mConfig); } /** @@ -1246,7 +1335,7 @@ public class WifiManagerTest { */ @Test public void testSetSoftApConfigurationSuccessReturnsTrue() throws Exception { - SoftApConfiguration apConfig = new SoftApConfiguration.Builder().build(); + SoftApConfiguration apConfig = generatorTestSoftApConfig(); when(mWifiService.setSoftApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME))) .thenReturn(true); @@ -1258,7 +1347,7 @@ public class WifiManagerTest { */ @Test public void testSetSoftApConfigurationFailureReturnsFalse() throws Exception { - SoftApConfiguration apConfig = new SoftApConfiguration.Builder().build(); + SoftApConfiguration apConfig = generatorTestSoftApConfig(); when(mWifiService.setSoftApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME))) .thenReturn(false); @@ -1273,7 +1362,7 @@ public class WifiManagerTest { doThrow(new SecurityException()).when(mWifiService).setSoftApConfiguration(any(), any()); try { - mWifiManager.setSoftApConfiguration(new SoftApConfiguration.Builder().build()); + mWifiManager.setSoftApConfiguration(generatorTestSoftApConfig()); fail("setWifiApConfiguration should rethrow Exceptions from WifiService"); } catch (SecurityException e) { } } -- cgit v1.2.3 From f272d502061b49dade7b60bb3754a4260c613951 Mon Sep 17 00:00:00 2001 From: lesl Date: Fri, 17 Jan 2020 19:48:49 +0800 Subject: wifi: Fix java doc error, use @code instead of @link Root cause: The @link is referencing the hidden method will build break Bug: 142752869 Test: make docs frameworks/base/wifi/ Change-Id: I8101fcfc5fd022d3216b300ce054645bcd878a07 --- wifi/java/android/net/wifi/SoftApConfiguration.java | 11 +++++------ wifi/java/android/net/wifi/WifiManager.java | 7 ++++--- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java index 1da9aad7cc39..49fb5a365b89 100644 --- a/wifi/java/android/net/wifi/SoftApConfiguration.java +++ b/wifi/java/android/net/wifi/SoftApConfiguration.java @@ -36,7 +36,6 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Objects; -import java.util.concurrent.Executor; /** * Configuration for a soft access point (a.k.a. Soft AP, SAP, Hotspot). @@ -45,10 +44,10 @@ import java.util.concurrent.Executor; * framework how it should configure a hotspot. * * System apps can use this to configure a tethered hotspot using - * {@link WifiManager#startTetheredHotspot(SoftApConfiguration)} and - * {@link WifiManager#setSoftApConfiguration(SoftApConfiguration)} + * {@code WifiManager#startTetheredHotspot(SoftApConfiguration)} and + * {@code WifiManager#setSoftApConfiguration(SoftApConfiguration)} * or local-only hotspot using - * {@link WifiManager#startLocalOnlyHotspot(SoftApConfiguration, Executor, + * {@code WifiManager#startLocalOnlyHotspot(SoftApConfiguration, Executor, * WifiManager.LocalOnlyHotspotCallback)}. * * Instances of this class are immutable; use {@link SoftApConfiguration.Builder} and its methods to @@ -347,7 +346,7 @@ public final class SoftApConfiguration implements Parcelable { /** * Return String set to be the SSID for the AP. - * {@link #setSsid(String)}. + * {@link Builder#setSsid(String)}. */ @Nullable public String getSsid() { @@ -365,7 +364,7 @@ public final class SoftApConfiguration implements Parcelable { /** * Returns String set to be passphrase for current AP. - * {@link #setPassphrase(String, @SecurityType int)}. + * {@link Builder#setPassphrase(String, int)}. */ @Nullable public String getPassphrase() { diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index c371825d9c76..783acc319694 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -3740,9 +3740,10 @@ public class WifiManager { /** * Returns the {@link WifiConfiguration} of the current Local Only Hotspot (LOHS). * May be null if hotspot enabled and security type is not - * {@link WifiConfiguration.KeyMgmt.None} or {@link WifiConfiguration.KeyMgmt.WPA2_PSK}. + * {@code WifiConfiguration.KeyMgmt.None} or {@code WifiConfiguration.KeyMgmt.WPA2_PSK}. * - * @deprecated Use {@link getSoftApConfiguration()} to get the LOHS configuration. + * @deprecated Use {@code WifiManager#getSoftApConfiguration()} to get the + * LOHS configuration. */ @Deprecated @Nullable @@ -3751,7 +3752,7 @@ public class WifiManager { } /** - * Returns the {@link SoftapConfiguration} of the current Local Only Hotspot (LOHS). + * Returns the {@link SoftApConfiguration} of the current Local Only Hotspot (LOHS). */ @NonNull public SoftApConfiguration getSoftApConfiguration() { -- cgit v1.2.3 From cd80e83a2b9b4871d26b70001321d7b7347eb6a5 Mon Sep 17 00:00:00 2001 From: Ahmed ElArabawy Date: Wed, 15 Jan 2020 17:19:16 -0800 Subject: Wifi: Add a system api to query for device phy capabilities This commit adds the API to query for the device phy capabilities. Bug: 143543900 Bug: 134688244 Bug: 144576344 Test: atest com.android.wifi.server Change-Id: I8bff0fb45faaa39a7cd4dd19fe4591ac2e7af3d5 --- .../net/wifi/wificond/DeviceWiphyCapabilities.java | 160 +++++++++++++++++++++ .../android/net/wifi/wificond/WifiCondManager.java | 16 +++ .../wifi/wificond/DeviceWiphyCapabilitiesTest.java | 59 ++++++++ .../net/wifi/wificond/WifiCondManagerTest.java | 21 ++- 4 files changed, 255 insertions(+), 1 deletion(-) create mode 100644 wifi/java/android/net/wifi/wificond/DeviceWiphyCapabilities.java create mode 100644 wifi/tests/src/android/net/wifi/wificond/DeviceWiphyCapabilitiesTest.java (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/wificond/DeviceWiphyCapabilities.java b/wifi/java/android/net/wifi/wificond/DeviceWiphyCapabilities.java new file mode 100644 index 000000000000..de1c7600f8ef --- /dev/null +++ b/wifi/java/android/net/wifi/wificond/DeviceWiphyCapabilities.java @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2020 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.wificond; + +import android.annotation.NonNull; +import android.annotation.SystemApi; +import android.net.wifi.ScanResult; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Log; + +import java.util.Objects; + +/** + * DeviceWiphyCapabilities for wificond + * + * @hide + */ +@SystemApi +public final class DeviceWiphyCapabilities implements Parcelable { + private static final String TAG = "DeviceWiphyCapabilities"; + + private boolean m80211nSupported; + private boolean m80211acSupported; + private boolean m80211axSupported; + + /** public constructor */ + public DeviceWiphyCapabilities() { + m80211nSupported = false; + m80211acSupported = false; + m80211axSupported = false; + } + + /** + * Get the IEEE 802.11 standard support + * + * @param standard the IEEE 802.11 standard to check on its support. + * valid values from {@link ScanResult}'s {@code WIFI_STANDARD_} + * @return {@code true} if supported, {@code false} otherwise. + */ + public boolean isWifiStandardSupported(int standard) { + switch (standard) { + case ScanResult.WIFI_STANDARD_LEGACY: + return true; + case ScanResult.WIFI_STANDARD_11N: + return m80211nSupported; + case ScanResult.WIFI_STANDARD_11AC: + return m80211acSupported; + case ScanResult.WIFI_STANDARD_11AX: + return m80211axSupported; + default: + Log.e(TAG, "isWifiStandardSupported called with invalid standard: " + standard); + return false; + } + } + + /** + * Set the IEEE 802.11 standard support + * + * @param standard the IEEE 802.11 standard to set its support. + * valid values from {@link ScanResult}'s {@code WIFI_STANDARD_} + * @param support {@code true} if supported, {@code false} otherwise. + */ + public void setWifiStandardSupport(int standard, boolean support) { + switch (standard) { + case ScanResult.WIFI_STANDARD_11N: + m80211nSupported = support; + break; + case ScanResult.WIFI_STANDARD_11AC: + m80211acSupported = support; + break; + case ScanResult.WIFI_STANDARD_11AX: + m80211axSupported = support; + break; + default: + Log.e(TAG, "setWifiStandardSupport called with invalid standard: " + standard); + } + } + + /** override comparator */ + @Override + public boolean equals(Object rhs) { + if (this == rhs) return true; + if (!(rhs instanceof DeviceWiphyCapabilities)) { + return false; + } + DeviceWiphyCapabilities capa = (DeviceWiphyCapabilities) rhs; + + return m80211nSupported == capa.m80211nSupported + && m80211acSupported == capa.m80211acSupported + && m80211axSupported == capa.m80211axSupported; + } + + /** override hash code */ + @Override + public int hashCode() { + return Objects.hash(m80211nSupported, m80211acSupported, m80211axSupported); + } + + /** implement Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** + * implement Parcelable interface + * |flags| is ignored. + */ + @Override + public void writeToParcel(@NonNull Parcel out, int flags) { + out.writeBoolean(m80211nSupported); + out.writeBoolean(m80211acSupported); + out.writeBoolean(m80211axSupported); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("m80211nSupported:").append(m80211nSupported ? "Yes" : "No"); + sb.append("m80211acSupported:").append(m80211acSupported ? "Yes" : "No"); + sb.append("m80211axSupported:").append(m80211axSupported ? "Yes" : "No"); + return sb.toString(); + } + + /** implement Parcelable interface */ + public static final @NonNull Parcelable.Creator CREATOR = + new Parcelable.Creator() { + /** + * Caller is responsible for providing a valid parcel. + */ + @Override + public DeviceWiphyCapabilities createFromParcel(Parcel in) { + DeviceWiphyCapabilities capabilities = new DeviceWiphyCapabilities(); + capabilities.m80211nSupported = in.readBoolean(); + capabilities.m80211acSupported = in.readBoolean(); + capabilities.m80211axSupported = in.readBoolean(); + return capabilities; + } + + @Override + public DeviceWiphyCapabilities[] newArray(int size) { + return new DeviceWiphyCapabilities[size]; + } + }; +} diff --git a/wifi/java/android/net/wifi/wificond/WifiCondManager.java b/wifi/java/android/net/wifi/wificond/WifiCondManager.java index f70bdac25c33..4847640b1418 100644 --- a/wifi/java/android/net/wifi/wificond/WifiCondManager.java +++ b/wifi/java/android/net/wifi/wificond/WifiCondManager.java @@ -1051,6 +1051,22 @@ public class WifiCondManager { return mApInterfaces.get(ifaceName); } + /** + * Get the device phy capabilities for a given interface + */ + @Nullable public DeviceWiphyCapabilities getDeviceWiphyCapabilities(@NonNull String ifaceName) { + if (mWificond == null) { + Log.e(TAG, "Can not query for device wiphy capabilities at this time"); + return null; + } + + try { + return mWificond.getDeviceWiphyCapabilities(ifaceName); + } catch (RemoteException e) { + return null; + } + } + /** * Register the provided callback handler for SoftAp events. Note that the Soft AP itself is * configured using {@link #setupInterfaceForSoftApMode(String)}. diff --git a/wifi/tests/src/android/net/wifi/wificond/DeviceWiphyCapabilitiesTest.java b/wifi/tests/src/android/net/wifi/wificond/DeviceWiphyCapabilitiesTest.java new file mode 100644 index 000000000000..1479acfe8e20 --- /dev/null +++ b/wifi/tests/src/android/net/wifi/wificond/DeviceWiphyCapabilitiesTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2020 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.wificond; + +import static org.junit.Assert.assertEquals; + +import android.net.wifi.ScanResult; +import android.os.Parcel; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link android.net.wifi.wificond.DeviceWiphyCapabilities}. + */ +@SmallTest +public class DeviceWiphyCapabilitiesTest { + @Before + public void setUp() {} + + /** + * DeviceWiphyCapabilities object can be serialized and deserialized, while keeping the + * values unchanged. + */ + @Test + public void canSerializeAndDeserialize() { + DeviceWiphyCapabilities capa = new DeviceWiphyCapabilities(); + + capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, true); + capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, true); + capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AX, false); + + Parcel parcel = Parcel.obtain(); + capa.writeToParcel(parcel, 0); + // Rewind the pointer to the head of the parcel. + parcel.setDataPosition(0); + DeviceWiphyCapabilities capaDeserialized = + DeviceWiphyCapabilities.CREATOR.createFromParcel(parcel); + + assertEquals(capa, capaDeserialized); + assertEquals(capa.hashCode(), capaDeserialized.hashCode()); + } +} diff --git a/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java b/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java index f3867c1c3fdf..619c95efb173 100644 --- a/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java +++ b/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java @@ -38,6 +38,7 @@ import static org.mockito.Mockito.when; import android.app.AlarmManager; import android.app.test.TestAlarmManager; import android.content.Context; +import android.net.wifi.ScanResult; import android.net.wifi.SoftApInfo; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiScanner; @@ -397,7 +398,6 @@ public class WifiCondManagerTest { verify(mWifiScannerImpl).unsubscribeScanEvents(); } - /** * Verifies that tearDownInterfaces() returns false when wificond is not started. */ @@ -1036,6 +1036,25 @@ public class WifiCondManagerTest { verify(mSendMgmtFrameCallback).onFailure(WifiCondManager.SEND_MGMT_FRAME_ERROR_TIMEOUT); } + /** + * Tests getDeviceWiphyCapabililties + */ + @Test + public void testGetDeviceWiphyCapabilities() throws Exception { + DeviceWiphyCapabilities capaExpected = new DeviceWiphyCapabilities(); + + capaExpected.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, true); + capaExpected.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, true); + capaExpected.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AX, false); + + when(mWificond.getDeviceWiphyCapabilities(TEST_INTERFACE_NAME)) + .thenReturn(capaExpected); + + DeviceWiphyCapabilities capaActual = + mWificondControl.getDeviceWiphyCapabilities(TEST_INTERFACE_NAME); + assertEquals(capaExpected, capaActual); + } + // Create a ArgumentMatcher which captures a SingleScanSettings parameter and checks if it // matches the provided frequency set and ssid set. private class ScanMatcher implements ArgumentMatcher { -- cgit v1.2.3 From a4d9a65ff5765d20a3d7601546e8039e68f244f6 Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 16 Jan 2020 18:18:24 -0800 Subject: WifiNetworkSpecifier: get context reflectively Temporarily use reflection to get the context in order to allow framework-wifi to build against @SystemApi stubs. Will remove reflective call once refactor is complete to allow WifiNetworkSpecifier to get the context using formal APIs. Bug: 144102365 Test: Ran CTS Verifier NetworkRequest tests, verified package name in adb logs. Change-Id: Ib507b449f81e9ce88cdb9190e9f8390eb25819b7 --- .../android/net/wifi/WifiNetworkSpecifier.java | 23 ++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java index 07afd7fb6714..444e1ef041e8 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java +++ b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java @@ -20,7 +20,7 @@ import static com.android.internal.util.Preconditions.checkNotNull; import android.annotation.NonNull; import android.annotation.Nullable; -import android.app.ActivityThread; +import android.app.Application; import android.net.MacAddress; import android.net.MatchAllNetworkSpecifier; import android.net.NetworkRequest; @@ -30,8 +30,11 @@ import android.os.Parcelable; import android.os.PatternMatcher; import android.os.Process; import android.text.TextUtils; +import android.util.Log; import android.util.Pair; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.nio.charset.CharsetEncoder; import java.nio.charset.StandardCharsets; import java.util.Objects; @@ -41,6 +44,7 @@ import java.util.Objects; * {@link WifiNetworkSpecifier.Builder} class to create an instance. */ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parcelable { + private static final String TAG = "WifiNetworkSpecifier"; /** * Builder used to create {@link WifiNetworkSpecifier} objects. @@ -436,7 +440,22 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc mBssidPatternMatcher, buildWifiConfiguration(), Process.myUid(), - ActivityThread.currentApplication().getApplicationContext().getOpPackageName()); + getCurrentApplicationReflectively().getApplicationContext().getOpPackageName()); + } + + // TODO(b/144102365): Remove once refactor is complete + private static Application getCurrentApplicationReflectively() { + try { + // reflection for static method android.app.ActivityThread#currentApplication() + Class klass = Class.forName("android.app.ActivityThread"); + Method currentApplicationMethod = klass.getDeclaredMethod("currentApplication"); + Object result = currentApplicationMethod.invoke(null); + return (Application) result; + } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException + | InvocationTargetException e) { + Log.e(TAG, "Failed to call ActivityThread#currentApplication() reflectively!", e); + throw new RuntimeException(e); + } } } -- cgit v1.2.3 From cff9addae58094947671adfa2fd2ab64e93f3bb2 Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 16 Jan 2020 18:05:00 -0800 Subject: Build framework-wifi against core_current & framework-system-stubs At this point framework-wifi will not depend on any @hide APIs. Bug: 140299412 Test: boots up and connects to Wifi Change-Id: I2d2aa89cde318ceaa58aee295b0a5355fc2885eb --- wifi/Android.bp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 4c9ee854536e..76ccc68908d1 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -58,19 +58,20 @@ test_access_hidden_api_whitelist = [ // classes before they are renamed. java_library { name: "framework-wifi-pre-jarjar", - // TODO(b/140299412) should be core_current once we build against framework-system-stubs - sdk_version: "core_platform", + // TODO(b/146757305): sdk_version should be "module_lib_current" + sdk_version: "core_current", static_libs: [ "framework-wifi-util-lib", "android.hardware.wifi-V1.0-java-constants", ], libs: [ - // TODO(b/140299412) should be framework-system-stubs once we fix all @hide dependencies - "framework-minus-apex", "framework-annotations-lib", "unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage "unsupportedappusage-annotation", // for dalvik.annotation.compat.UnsupportedAppUsage "framework-telephony-stubs", + // TODO(b/146757305): should be unnecessary once + // sdk_version="module_lib_current" + "android_system_stubs_current", ], srcs: [ ":framework-wifi-updatable-sources", @@ -80,13 +81,21 @@ java_library { "//frameworks/opt/net/wifi/service", "//frameworks/opt/net/wifi/tests/wifitests", ], + + // TODO(b/146757305): should be unnecessary once + // sdk_version="module_lib_current" + aidl: { + include_dirs: [ + "frameworks/base/core/java", + ], + }, } // post-jarjar version of framework-wifi java_library { name: "framework-wifi", - // TODO(b/140299412) should be core_current once we build against framework-system-stubs - sdk_version: "core_platform", + // TODO(b/146757305): sdk_version should be "module_lib_current" + sdk_version: "core_current", static_libs: [ "framework-wifi-pre-jarjar", ], -- cgit v1.2.3 From c6513592004e4ac68c07e6fb97965e9ef133e54d Mon Sep 17 00:00:00 2001 From: David Su Date: Wed, 15 Jan 2020 22:55:20 +0000 Subject: framework-wifi: clean up AIDL exports (Attempt 2) Remove AIDL exports to not leak internal implementation as AIDL is not an official API of the Wifi module. Previous attempt broke the build. Bug: 147757606 Change-Id: I2edeeccf83b9460881c5d4ccc6bd5d6e3befa700 Test: compiles --- wifi/Android.bp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 76ccc68908d1..2f9979453f38 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -123,6 +123,8 @@ droidstubs { ":framework-annotations", ":framework-wifi-updatable-sources", ], + // This is needed as IOnWifiActivityEnergyInfoListener.aidl in framework-wifi depends on + // WifiActivityEnergyInfo.aidl in framework-minus-apex aidl: { include_dirs: ["frameworks/base/core/java"], }, @@ -134,11 +136,6 @@ droidstubs { java_library { name: "framework-wifi-stubs", srcs: [":framework-wifi-stubs-srcs"], - aidl: { - export_include_dirs: [ - "java", - ], - }, sdk_version: "core_current", libs: ["android_system_stubs_current"], installable: false, -- cgit v1.2.3 From b6eee5d7ae28e572a0f9e3728838940e7c26d7f5 Mon Sep 17 00:00:00 2001 From: Arsalan Khan Date: Fri, 17 Jan 2020 19:45:22 +0000 Subject: Revert "Build framework-wifi against core_current & framework-sy..." Revert submission 10057725 Reason for revert: Reverted Changes: Ib507b449f: WifiNetworkSpecifier: get context reflectively I2d2aa89cd: Build framework-wifi against core_current & framew... Change-Id: I9b33ac97eaabc4326301d96d092224c4bb7f2714 --- wifi/Android.bp | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 76ccc68908d1..4c9ee854536e 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -58,20 +58,19 @@ test_access_hidden_api_whitelist = [ // classes before they are renamed. java_library { name: "framework-wifi-pre-jarjar", - // TODO(b/146757305): sdk_version should be "module_lib_current" - sdk_version: "core_current", + // TODO(b/140299412) should be core_current once we build against framework-system-stubs + sdk_version: "core_platform", static_libs: [ "framework-wifi-util-lib", "android.hardware.wifi-V1.0-java-constants", ], libs: [ + // TODO(b/140299412) should be framework-system-stubs once we fix all @hide dependencies + "framework-minus-apex", "framework-annotations-lib", "unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage "unsupportedappusage-annotation", // for dalvik.annotation.compat.UnsupportedAppUsage "framework-telephony-stubs", - // TODO(b/146757305): should be unnecessary once - // sdk_version="module_lib_current" - "android_system_stubs_current", ], srcs: [ ":framework-wifi-updatable-sources", @@ -81,21 +80,13 @@ java_library { "//frameworks/opt/net/wifi/service", "//frameworks/opt/net/wifi/tests/wifitests", ], - - // TODO(b/146757305): should be unnecessary once - // sdk_version="module_lib_current" - aidl: { - include_dirs: [ - "frameworks/base/core/java", - ], - }, } // post-jarjar version of framework-wifi java_library { name: "framework-wifi", - // TODO(b/146757305): sdk_version should be "module_lib_current" - sdk_version: "core_current", + // TODO(b/140299412) should be core_current once we build against framework-system-stubs + sdk_version: "core_platform", static_libs: [ "framework-wifi-pre-jarjar", ], -- cgit v1.2.3 From 2a96126e2e16528a462b152420ab9ebc69645e0d Mon Sep 17 00:00:00 2001 From: David Su Date: Fri, 17 Jan 2020 13:45:30 -0800 Subject: Expose WifiNetworkSuggestion.getWifi/PasspointConfiguration() These @SystemApis are needed by Settings. Also modified no-arg constructor for WifiNetworkSuggestion to conform to the @NonNull guarantees of getWifiConfiguration(). Bug: 138801922 Test: atest FrameworksWifiApiTests Change-Id: I5ce60ba376e6976bdcb5a651c991c44579bfef3f --- .../android/net/wifi/WifiNetworkSuggestion.java | 25 +++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java index 2fba5a3f4624..306e13133287 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java +++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java @@ -657,12 +657,14 @@ public final class WifiNetworkSuggestion implements Parcelable { * Network configuration for the provided network. * @hide */ + @NonNull public final WifiConfiguration wifiConfiguration; /** * Passpoint configuration for the provided network. * @hide */ + @Nullable public final PasspointConfiguration passpointConfiguration; /** @@ -692,7 +694,7 @@ public final class WifiNetworkSuggestion implements Parcelable { /** @hide */ public WifiNetworkSuggestion() { - this.wifiConfiguration = null; + this.wifiConfiguration = new WifiConfiguration(); this.passpointConfiguration = null; this.isAppInteractionRequired = false; this.isUserInteractionRequired = false; @@ -794,4 +796,25 @@ public final class WifiNetworkSuggestion implements Parcelable { .append(" ]"); return sb.toString(); } + + /** + * Get the {@link WifiConfiguration} associated with this Suggestion. + * @hide + */ + @SystemApi + @NonNull + public WifiConfiguration getWifiConfiguration() { + return wifiConfiguration; + } + + /** + * Get the {@link PasspointConfiguration} associated with this Suggestion, or null if this + * Suggestion is not for a Passpoint network. + * @hide + */ + @SystemApi + @Nullable + public PasspointConfiguration getPasspointConfiguration() { + return passpointConfiguration; + } } -- cgit v1.2.3 From 298cd36e58ff9acf7d35975c8ad68772cea8891d Mon Sep 17 00:00:00 2001 From: David Su Date: Fri, 17 Jan 2020 19:02:49 +0000 Subject: framework.jar - include framework-wifi-stubs instead of framework-wifi (Attempt 2) Stop exporting @hide APIs from framework-wifi to framework.jar by including framework-wifi-stubs instead. At this point no code is allowed to call @hide APIs defined in framework-wifi unless they have an explicit exemption. Attempt 1 broke the build, trying again. Bug: 140299412 Change-Id: I3eecb0a5f6b1c0be85d684d190465d591994d99f Test: boots up and connects to Wifi --- wifi/Android.bp | 1 - 1 file changed, 1 deletion(-) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 5ef892d005ac..95cce5e7b371 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -98,7 +98,6 @@ java_library { }, hostdex: true, // for hiddenapi check visibility: [ - "//frameworks/base", // TODO(b/140299412) remove once all dependencies are fixed "//frameworks/opt/net/wifi/service:__subpackages__", ] + test_access_hidden_api_whitelist, apex_available: [ -- cgit v1.2.3 From 8d4ef86d72a6d8e61af2eabd9c5dc399410fd007 Mon Sep 17 00:00:00 2001 From: "Nate(Qiang) Jiang" Date: Fri, 17 Jan 2020 15:37:10 -0800 Subject: set SharedWithUser and IsAutoJoinEnabled both to false is not allowed Fix the issue that passpoint suggestion can set both to false. Bug: 139199957 Test: atest android.net.wifi Change-Id: I44ef0116efeb04220b3f710664aecab614ae849c --- wifi/java/android/net/wifi/WifiNetworkSuggestion.java | 12 +++++------- .../src/android/net/wifi/WifiNetworkSuggestionTest.java | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 7 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java index 2fba5a3f4624..7ecad9ee1031 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java +++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java @@ -635,14 +635,12 @@ public final class WifiNetworkSuggestion implements Parcelable { } mIsSharedWithUser = false; } - - if (!mIsSharedWithUser && !mIsInitialAutoJoinEnabled) { - throw new IllegalStateException("Should have not a network with both " - + "setIsUserAllowedToManuallyConnect and " - + "setIsAutoJoinEnabled set to false"); - } } - + if (!mIsSharedWithUser && !mIsInitialAutoJoinEnabled) { + throw new IllegalStateException("Should have not a network with both " + + "setCredentialSharedWithUser and " + + "setIsAutoJoinEnabled set to false"); + } return new WifiNetworkSuggestion( wifiConfiguration, mPasspointConfiguration, diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java index cb1b7747798d..e778b9ad47a3 100644 --- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java +++ b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java @@ -758,4 +758,20 @@ public class WifiNetworkSuggestionTest { .setIsInitialAutoJoinEnabled(false) .build(); } + + /** + * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception + * when set both {@link WifiNetworkSuggestion.Builder#setIsInitialAutoJoinEnabled(boolean)} + * and {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} (boolean)} + * to false on a passpoint suggestion. + */ + @Test(expected = IllegalStateException.class) + public void testSetIsAutoJoinDisabledWithSecureNetworkNotSharedWithUserForPasspoint() { + PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig(); + new WifiNetworkSuggestion.Builder() + .setPasspointConfig(passpointConfiguration) + .setCredentialSharedWithUser(false) + .setIsInitialAutoJoinEnabled(false) + .build(); + } } -- cgit v1.2.3 From 439175f1b93090c2f44292a508d9d37828fca085 Mon Sep 17 00:00:00 2001 From: David Su Date: Fri, 17 Jan 2020 21:16:31 +0000 Subject: Build framework-wifi against core_current & framework-system-stubs (Attempt 2) At this point framework-wifi will not depend on any @hide APIs. Previous attempt broke git_master/apps target. Bug: 140299412 Change-Id: Idf4c1d22f96c01ae9c117742dcfe83929ab545ae Test: boots up and connects to Wifi --- wifi/Android.bp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 5ef892d005ac..2f9979453f38 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -58,19 +58,20 @@ test_access_hidden_api_whitelist = [ // classes before they are renamed. java_library { name: "framework-wifi-pre-jarjar", - // TODO(b/140299412) should be core_current once we build against framework-system-stubs - sdk_version: "core_platform", + // TODO(b/146757305): sdk_version should be "module_lib_current" + sdk_version: "core_current", static_libs: [ "framework-wifi-util-lib", "android.hardware.wifi-V1.0-java-constants", ], libs: [ - // TODO(b/140299412) should be framework-system-stubs once we fix all @hide dependencies - "framework-minus-apex", "framework-annotations-lib", "unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage "unsupportedappusage-annotation", // for dalvik.annotation.compat.UnsupportedAppUsage "framework-telephony-stubs", + // TODO(b/146757305): should be unnecessary once + // sdk_version="module_lib_current" + "android_system_stubs_current", ], srcs: [ ":framework-wifi-updatable-sources", @@ -80,13 +81,21 @@ java_library { "//frameworks/opt/net/wifi/service", "//frameworks/opt/net/wifi/tests/wifitests", ], + + // TODO(b/146757305): should be unnecessary once + // sdk_version="module_lib_current" + aidl: { + include_dirs: [ + "frameworks/base/core/java", + ], + }, } // post-jarjar version of framework-wifi java_library { name: "framework-wifi", - // TODO(b/140299412) should be core_current once we build against framework-system-stubs - sdk_version: "core_platform", + // TODO(b/146757305): sdk_version should be "module_lib_current" + sdk_version: "core_current", static_libs: [ "framework-wifi-pre-jarjar", ], -- cgit v1.2.3 From 32f3943b8d812319b936e7acb6cd95616ea0b4fc Mon Sep 17 00:00:00 2001 From: David Su Date: Fri, 17 Jan 2020 17:14:02 -0800 Subject: Fully qualify android.net.wifi.ScanResult Somehow the AIDL compiler is confusing android.net.wifi.ScanResult with android.bluetooth.le.ScanResult. For some reason fully qualifying ScanResult instead of having a single import at the top fixes the problem. Bug: 147918827 Test: m ANDROID_BUILDSPEC=vendor/google/build/app_build_spec.mk Change-Id: I93b9006cb1741ba0d723ffaa8b2a84ff96c7312e --- wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl | 3 +-- wifi/java/android/net/wifi/IWifiManager.aidl | 9 ++++----- 2 files changed, 5 insertions(+), 7 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl b/wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl index d14ec57ea07a..51d74f0fcfa9 100644 --- a/wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl +++ b/wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl @@ -17,7 +17,6 @@ package android.net.wifi; import android.net.wifi.INetworkRequestUserSelectionCallback; -import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; /** @@ -31,7 +30,7 @@ oneway interface INetworkRequestMatchCallback void onAbort(); - void onMatch(in List scanResults); + void onMatch(in List scanResults); void onUserSelectionConnectSuccess(in WifiConfiguration wificonfiguration); diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 5a98ac86e783..54091a6f4a67 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -36,7 +36,6 @@ import android.net.wifi.ISuggestionConnectionStatusListener; import android.net.wifi.ITrafficStateCallback; import android.net.wifi.ITxPacketCountListener; import android.net.wifi.IWifiConnectedNetworkScorer; -import android.net.wifi.ScanResult; import android.net.wifi.SoftApConfiguration; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; @@ -61,9 +60,9 @@ interface IWifiManager ParceledListSlice getPrivilegedConfiguredNetworks(String packageName, String featureId); - Map getAllMatchingFqdnsForScanResults(in List scanResult); + Map getAllMatchingFqdnsForScanResults(in List scanResult); - Map getMatchingOsuProviders(in List scanResult); + Map getMatchingOsuProviders(in List scanResult); Map getMatchingPasspointConfigsForOsuProviders(in List osuProviders); @@ -97,7 +96,7 @@ interface IWifiManager boolean startScan(String packageName, String featureId); - List getScanResults(String callingPackage, String callingFeatureId); + List getScanResults(String callingPackage, String callingFeatureId); boolean disconnect(String packageName); @@ -254,7 +253,7 @@ interface IWifiManager int calculateSignalLevel(int rssi); - List getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(in List scanResults); + List getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(in List scanResults); boolean setWifiConnectedNetworkScorer(in IBinder binder, in IWifiConnectedNetworkScorer scorer); -- cgit v1.2.3 From 4572b7bf6fa035db0b5da4d1c05a95eccdc44459 Mon Sep 17 00:00:00 2001 From: "Nate(Qiang) Jiang" Date: Mon, 13 Jan 2020 16:33:42 -0800 Subject: Deprecate WifiManager passpoint API's We prefer app to use suggestion API to add passpoint network. Bug: 142424092 Test: atest android.net.wifi Change-Id: I030efc2eeecef16ce7d5650136f168a44fad864e --- wifi/java/android/net/wifi/WifiManager.java | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index ec3de43ee85a..bf973aba64ac 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1948,6 +1948,15 @@ public class WifiManager { * @param config The Passpoint configuration to be added * @throws IllegalArgumentException if configuration is invalid or Passpoint is not enabled on * the device. + * + * Deprecated for general app usage - except DO/PO apps. + * See {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)} to + * create a passpoint suggestion. + * See {@link #addNetworkSuggestions(List)}, {@link #removeNetworkSuggestions(List)} for new + * API to add Wi-Fi networks for consideration when auto-connecting to wifi. + * Compatibility Note: For applications targeting + * {@link android.os.Build.VERSION_CODES#R} or above, except for system of DO/PO apps, this API + * will throw {@link IllegalArgumentException} */ public void addOrUpdatePasspointConfiguration(PasspointConfiguration config) { try { -- cgit v1.2.3 From 8996b2d67710175c6a89a4546870a19f2c4134ec Mon Sep 17 00:00:00 2001 From: "Nate(Qiang) Jiang" Date: Wed, 15 Jan 2020 15:06:54 -0800 Subject: Add set untrusted API for networkSuggestion Bug: 147766061 Test: atest android.net.wifi Change-Id: I122643b07447d9514390fd0654bba77ed4dc4a0f --- wifi/java/android/net/wifi/WifiConfiguration.java | 4 +- wifi/java/android/net/wifi/WifiManager.java | 9 +++ .../android/net/wifi/WifiNetworkSuggestion.java | 58 ++++++++++++++++-- .../net/wifi/WifiNetworkSuggestionTest.java | 69 ++++++++++++++++++---- 4 files changed, 124 insertions(+), 16 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index b2fbb401dde5..e84369fb7ba1 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -938,8 +938,10 @@ public class WifiConfiguration implements Parcelable { } /** - * Indicate whther the network is trusted or not. Networks are considered trusted + * Indicate whether the network is trusted or not. Networks are considered trusted * if the user explicitly allowed this network connection. + * This bit can be used by suggestion network, see + * {@link WifiNetworkSuggestion.Builder#setUnTrusted(boolean)} * @hide */ public boolean trusted; diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 1b74cba6a83e..ca886a6ee4af 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -193,6 +193,14 @@ public class WifiManager { */ public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID = 5; + /** + * Reason code if one or more of the network suggestions added is not allowed. + * + * This error may be caused by suggestion is using SIM-based encryption method, but calling app + * is not carrier privileged. + */ + public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_NOT_ALLOWED = 6; + /** @hide */ @IntDef(prefix = { "STATUS_NETWORK_SUGGESTIONS_" }, value = { STATUS_NETWORK_SUGGESTIONS_SUCCESS, @@ -201,6 +209,7 @@ public class WifiManager { STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE, STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_EXCEEDS_MAX_PER_APP, STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID, + STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_NOT_ALLOWED, }) @Retention(RetentionPolicy.SOURCE) public @interface NetworkSuggestionsStatusCode {} diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java index 7ecad9ee1031..0cf0c22d8dc2 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java +++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java @@ -139,6 +139,11 @@ public final class WifiNetworkSuggestion implements Parcelable { */ private @Nullable WifiEnterpriseConfig mWapiEnterpriseConfig; + /** + * Whether this network will be brought up as untrusted (TRUSTED capability bit removed). + */ + private boolean mIsNetworkUntrusted; + public Builder() { mSsid = null; mBssid = null; @@ -159,6 +164,7 @@ public final class WifiNetworkSuggestion implements Parcelable { mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID; mWapiPskPassphrase = null; mWapiEnterpriseConfig = null; + mIsNetworkUntrusted = false; } /** @@ -468,6 +474,27 @@ public final class WifiNetworkSuggestion implements Parcelable { return this; } + /** + * Specifies whether the system will bring up the network (if selected) as untrusted. An + * untrusted network has its {@link android.net.NetworkCapabilities#NET_CAPABILITY_TRUSTED} + * capability removed. The Wi-Fi network selection process may use this information to + * influence priority of the suggested network for Wi-Fi network selection (most likely to + * reduce it). The connectivity service may use this information to influence the overall + * network configuration of the device. + *

    + *

  • An untrusted network's credentials may not be shared with the user using + * {@link #setCredentialSharedWithUser(boolean)}.
  • + *
  • If not set, defaults to false (i.e. network is trusted).
  • + * + * @param isUntrusted Boolean indicating whether the network should be brought up untrusted + * (if true) or trusted (if false). + * @return Instance of {@link Builder} to enable chaining of the builder method. + */ + public @NonNull Builder setUntrusted(boolean isUntrusted) { + mIsNetworkUntrusted = isUntrusted; + return this; + } + private void setSecurityParamsInWifiConfiguration( @NonNull WifiConfiguration configuration) { if (!TextUtils.isEmpty(mWpa2PskPassphrase)) { // WPA-PSK network. @@ -546,6 +573,7 @@ public final class WifiNetworkSuggestion implements Parcelable { wifiConfiguration.meteredOverride = mIsMetered ? WifiConfiguration.METERED_OVERRIDE_METERED : WifiConfiguration.METERED_OVERRIDE_NONE; + wifiConfiguration.trusted = !mIsNetworkUntrusted; mPasspointConfiguration.setCarrierId(mCarrierId); return wifiConfiguration; } @@ -641,13 +669,22 @@ public final class WifiNetworkSuggestion implements Parcelable { + "setCredentialSharedWithUser and " + "setIsAutoJoinEnabled set to false"); } + if (mIsNetworkUntrusted) { + if (mIsSharedWithUserSet && mIsSharedWithUser) { + throw new IllegalStateException("Should not be both" + + "setCredentialSharedWithUser and +" + + "setIsNetworkAsUntrusted to true"); + } + mIsSharedWithUser = false; + } return new WifiNetworkSuggestion( wifiConfiguration, mPasspointConfiguration, mIsAppInteractionRequired, mIsUserInteractionRequired, mIsSharedWithUser, - mIsInitialAutoJoinEnabled); + mIsInitialAutoJoinEnabled, + mIsNetworkUntrusted); } } @@ -688,6 +725,13 @@ public final class WifiNetworkSuggestion implements Parcelable { */ public final boolean isInitialAutoJoinEnabled; + /** + * Whether this network will be brought up as untrusted (TRUSTED capability bit removed). + * @hide + */ + public final boolean isNetworkUntrusted; + + /** @hide */ public WifiNetworkSuggestion() { this.wifiConfiguration = null; @@ -696,6 +740,7 @@ public final class WifiNetworkSuggestion implements Parcelable { this.isUserInteractionRequired = false; this.isUserAllowedToManuallyConnect = true; this.isInitialAutoJoinEnabled = true; + this.isNetworkUntrusted = false; } /** @hide */ @@ -704,7 +749,8 @@ public final class WifiNetworkSuggestion implements Parcelable { boolean isAppInteractionRequired, boolean isUserInteractionRequired, boolean isUserAllowedToManuallyConnect, - boolean isInitialAutoJoinEnabled) { + boolean isInitialAutoJoinEnabled, + boolean isNetworkUntrusted) { checkNotNull(networkConfiguration); this.wifiConfiguration = networkConfiguration; this.passpointConfiguration = passpointConfiguration; @@ -713,6 +759,7 @@ public final class WifiNetworkSuggestion implements Parcelable { this.isUserInteractionRequired = isUserInteractionRequired; this.isUserAllowedToManuallyConnect = isUserAllowedToManuallyConnect; this.isInitialAutoJoinEnabled = isInitialAutoJoinEnabled; + this.isNetworkUntrusted = isNetworkUntrusted; } public static final @NonNull Creator CREATOR = @@ -725,7 +772,8 @@ public final class WifiNetworkSuggestion implements Parcelable { in.readBoolean(), // isAppInteractionRequired in.readBoolean(), // isUserInteractionRequired in.readBoolean(), // isSharedCredentialWithUser - in.readBoolean() // isAutoJoinEnabled + in.readBoolean(), // isAutoJoinEnabled + in.readBoolean() ); } @@ -748,6 +796,7 @@ public final class WifiNetworkSuggestion implements Parcelable { dest.writeBoolean(isUserInteractionRequired); dest.writeBoolean(isUserAllowedToManuallyConnect); dest.writeBoolean(isInitialAutoJoinEnabled); + dest.writeBoolean(isNetworkUntrusted); } @Override @@ -787,8 +836,9 @@ public final class WifiNetworkSuggestion implements Parcelable { .append(", FQDN=").append(wifiConfiguration.FQDN) .append(", isAppInteractionRequired=").append(isAppInteractionRequired) .append(", isUserInteractionRequired=").append(isUserInteractionRequired) - .append(", isUserAllowedToManuallyConnect=").append(isUserAllowedToManuallyConnect) + .append(", isCredentialSharedWithUser=").append(isUserAllowedToManuallyConnect) .append(", isInitialAutoJoinEnabled=").append(isInitialAutoJoinEnabled) + .append(", isUnTrusted=").append(isNetworkUntrusted) .append(" ]"); return sb.toString(); } diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java index e778b9ad47a3..15accc337429 100644 --- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java +++ b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java @@ -532,7 +532,7 @@ public class WifiNetworkSuggestionTest { configuration.BSSID = TEST_BSSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion( - configuration, null, false, true, true, false); + configuration, null, false, true, true, true, false); Parcel parcelW = Parcel.obtain(); suggestion.writeToParcel(parcelW, 0); @@ -603,14 +603,14 @@ public class WifiNetworkSuggestionTest { configuration.BSSID = TEST_BSSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, null, true, false, true, true); + new WifiNetworkSuggestion(configuration, null, true, false, true, true, false); WifiConfiguration configuration1 = new WifiConfiguration(); configuration1.SSID = TEST_SSID; configuration1.BSSID = TEST_BSSID; configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); WifiNetworkSuggestion suggestion1 = - new WifiNetworkSuggestion(configuration1, null, false, true, true, false); + new WifiNetworkSuggestion(configuration1, null, false, true, true, true, false); assertEquals(suggestion, suggestion1); assertEquals(suggestion.hashCode(), suggestion1.hashCode()); @@ -626,13 +626,13 @@ public class WifiNetworkSuggestionTest { configuration.SSID = TEST_SSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, null, false, false, true, false); + new WifiNetworkSuggestion(configuration, null, false, false, true, true, false); WifiConfiguration configuration1 = new WifiConfiguration(); configuration1.SSID = TEST_SSID_1; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion1 = - new WifiNetworkSuggestion(configuration1, null, false, false, true, false); + new WifiNetworkSuggestion(configuration1, null, false, false, true, true, false); assertNotEquals(suggestion, suggestion1); } @@ -648,13 +648,13 @@ public class WifiNetworkSuggestionTest { configuration.BSSID = TEST_BSSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, null, false, false, true, true); + new WifiNetworkSuggestion(configuration, null, false, false, true, true, false); WifiConfiguration configuration1 = new WifiConfiguration(); configuration1.SSID = TEST_SSID; configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion1 = - new WifiNetworkSuggestion(configuration1, null, false, false, true, true); + new WifiNetworkSuggestion(configuration1, null, false, false, true, true, false); assertNotEquals(suggestion, suggestion1); } @@ -669,13 +669,13 @@ public class WifiNetworkSuggestionTest { configuration.SSID = TEST_SSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, null, false, false, true, true); + new WifiNetworkSuggestion(configuration, null, false, false, true, true, false); WifiConfiguration configuration1 = new WifiConfiguration(); configuration1.SSID = TEST_SSID; configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); WifiNetworkSuggestion suggestion1 = - new WifiNetworkSuggestion(configuration1, null, false, false, true, true); + new WifiNetworkSuggestion(configuration1, null, false, false, true, true, false); assertNotEquals(suggestion, suggestion1); } @@ -723,8 +723,8 @@ public class WifiNetworkSuggestionTest { * true on a open network suggestion. */ @Test(expected = IllegalStateException.class) - public void testSetIsUserAllowedToManuallyConnectToWithOpenNetwork() { - new WifiNetworkSuggestion.Builder() + public void testSetCredentialSharedWithUserWithOpenNetwork() { + WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() .setSsid(TEST_SSID) .setCredentialSharedWithUser(true) .build(); @@ -759,6 +759,53 @@ public class WifiNetworkSuggestionTest { .build(); } + /** + * Validate {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} set the + * correct value to the WifiConfiguration. + */ + @Test + public void testSetIsNetworkAsUntrusted() { + WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() + .setSsid(TEST_SSID) + .setWpa2Passphrase(TEST_PRESHARED_KEY) + .setUntrusted(true) + .build(); + assertTrue(suggestion.isNetworkUntrusted); + assertFalse(suggestion.isUserAllowedToManuallyConnect); + } + + /** + * Validate {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} set the + * correct value to the WifiConfiguration. + * Also the {@link WifiNetworkSuggestion#isUserAllowedToManuallyConnect} should be false; + */ + @Test + public void testSetIsNetworkAsUntrustedOnPasspointNetwork() { + PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig(); + WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() + .setPasspointConfig(passpointConfiguration) + .setUntrusted(true) + .build(); + assertTrue(suggestion.isNetworkUntrusted); + assertFalse(suggestion.isUserAllowedToManuallyConnect); + } + + /** + * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception + * when set {@link WifiNetworkSuggestion.Builder#setUntrusted(boolean)} to true and + * set {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} to true + * together. + */ + @Test(expected = IllegalStateException.class) + public void testSetCredentialSharedWithUserWithSetIsNetworkAsUntrusted() { + new WifiNetworkSuggestion.Builder() + .setSsid(TEST_SSID) + .setWpa2Passphrase(TEST_PRESHARED_KEY) + .setCredentialSharedWithUser(true) + .setUntrusted(true) + .build(); + } + /** * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception * when set both {@link WifiNetworkSuggestion.Builder#setIsInitialAutoJoinEnabled(boolean)} -- cgit v1.2.3 From 9b3f07652735ee0ee54701486f76c1e321110794 Mon Sep 17 00:00:00 2001 From: Ahmed ElArabawy Date: Fri, 10 Jan 2020 12:28:19 -0800 Subject: Wifi: Add a public API to query for supported wifi standards This commit adds a public API to query for the supported wifi standards. Bug: 143543900 Bug: 134688244 Bug: 144576344 Test: atest com.android.wifi.server Change-Id: I57ac90c7d3473a71435bfb96b19d983ae433082a --- wifi/java/android/net/wifi/IWifiManager.aidl | 2 ++ wifi/java/android/net/wifi/WifiManager.java | 14 ++++++++++++++ wifi/java/com/android/server/wifi/BaseWifiService.java | 5 +++++ wifi/tests/src/android/net/wifi/WifiManagerTest.java | 11 +++++++++++ 4 files changed, 32 insertions(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 5a98ac86e783..dafb4de62f3c 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -117,6 +117,8 @@ interface IWifiManager boolean is6GHzBandSupported(); + boolean isWifiStandardSupported(int standard); + boolean needs5GHzToAnyApBandConversion(); DhcpInfo getDhcpInfo(); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 1b74cba6a83e..30f0fb5234bd 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -2490,6 +2490,20 @@ public class WifiManager { } } + /** + * Check if the chipset supports a certain Wi-Fi standard. + * @param standard the IEEE 802.11 standard to check on. + * valid values from {@link ScanResult}'s {@code WIFI_STANDARD_} + * @return {@code true} if supported, {@code false} otherwise. + */ + public boolean isWifiStandardSupported(@ScanResult.WifiStandard int standard) { + try { + return mService.isWifiStandardSupported(standard); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Interface for Wi-Fi activity energy info listener. Should be implemented by applications and * set when calling {@link WifiManager#getWifiActivityEnergyInfoAsync}. diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index 08822e2762f6..56fa6e23a852 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -253,6 +253,11 @@ public class BaseWifiService extends IWifiManager.Stub { throw new UnsupportedOperationException(); } + @Override + public boolean isWifiStandardSupported(int standard) { + throw new UnsupportedOperationException(); + } + @Override public boolean needs5GHzToAnyApBandConversion() { throw new UnsupportedOperationException(); diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 738c6337ee98..f369203e05ab 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -1958,6 +1958,17 @@ public class WifiManagerTest { verify(mWifiService).is6GHzBandSupported(); } + /** + * Test behavior of {@link WifiManager#isWifiStandardSupported()} + */ + @Test + public void testIsWifiStandardSupported() throws Exception { + int standard = ScanResult.WIFI_STANDARD_11AX; + when(mWifiService.isWifiStandardSupported(standard)).thenReturn(true); + assertTrue(mWifiManager.isWifiStandardSupported(standard)); + verify(mWifiService).isWifiStandardSupported(standard); + } + /** * Test behavior of {@link WifiManager#getDhcpInfo()} */ -- cgit v1.2.3 From ac37493993afb462aee7205a98f720c3a4ba6414 Mon Sep 17 00:00:00 2001 From: lesl Date: Fri, 17 Jan 2020 19:56:16 +0800 Subject: softap: Add util function toWifiConfiguration in SoftApConfiguration. Bug: 142752869 Test: atest frameworks/base/wifi/tests Change-Id: I61ef8bfe4fc5e273249944b302782a4c5f909924 --- .../java/android/net/wifi/SoftApConfiguration.java | 55 ++++++++++++++++++++++ wifi/java/android/net/wifi/WifiManager.java | 47 ++++-------------- .../android/net/wifi/SoftApConfigurationTest.java | 40 +++++++++++++++- 3 files changed, 104 insertions(+), 38 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java index 49fb5a365b89..c02f8c3a8cd1 100644 --- a/wifi/java/android/net/wifi/SoftApConfiguration.java +++ b/wifi/java/android/net/wifi/SoftApConfiguration.java @@ -24,6 +24,7 @@ import android.net.MacAddress; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; +import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; @@ -56,6 +57,8 @@ import java.util.Objects; */ public final class SoftApConfiguration implements Parcelable { + private static final String TAG = "SoftApConfiguration"; + @VisibleForTesting static final int PSK_MIN_LEN = 8; @@ -471,6 +474,58 @@ public final class SoftApConfiguration implements Parcelable { return mAllowedClientList; } + /** + * Returns a {@link WifiConfiguration} representation of this {@link SoftApConfiguration}. + * Note that SoftApConfiguration may contain configuration which is cannot be represented + * by the legacy WifiConfiguration, in such cases a null will be returned. + * + *
  • SoftAp band in {@link WifiConfiguration.apBand} only supports + * 2GHz, 5GHz, 2GHz+5GHz bands, so conversion is limited to these bands.
  • + * + *
  • SoftAp security type in {@link WifiConfiguration.KeyMgmt} only supports + * NONE, WPA2_PSK, so conversion is limited to these security type.
  • + * @hide + */ + @Nullable + @SystemApi + public WifiConfiguration toWifiConfiguration() { + WifiConfiguration wifiConfig = new WifiConfiguration(); + wifiConfig.SSID = mSsid; + if (mBssid != null) { + wifiConfig.BSSID = mBssid.toString(); + } + wifiConfig.preSharedKey = mPassphrase; + wifiConfig.hiddenSSID = mHiddenSsid; + wifiConfig.apChannel = mChannel; + switch (mSecurityType) { + case SECURITY_TYPE_OPEN: + wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); + break; + case SECURITY_TYPE_WPA2_PSK: + wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA2_PSK); + break; + default: + Log.e(TAG, "Convert fail, unsupported security type :" + mSecurityType); + return null; + } + + switch (mBand) { + case BAND_2GHZ: + wifiConfig.apBand = WifiConfiguration.AP_BAND_2GHZ; + break; + case BAND_5GHZ: + wifiConfig.apBand = WifiConfiguration.AP_BAND_5GHZ; + break; + case BAND_ANY: + wifiConfig.apBand = WifiConfiguration.AP_BAND_ANY; + break; + default: + Log.e(TAG, "Convert fail, unsupported band setting :" + mBand); + return null; + } + return wifiConfig; + } + /** * Builds a {@link SoftApConfiguration}, which allows an app to configure various aspects of a * Soft AP. diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 64e61357df65..96b50989d477 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -3223,9 +3223,13 @@ public class WifiManager { * Gets the Wi-Fi AP Configuration. * @return AP details in WifiConfiguration * + * Note that AP detail may contain configuration which is cannot be represented + * by the legacy WifiConfiguration, in such cases a null will be returned. + * * @deprecated This API is deprecated. Use {@link #getSoftApConfiguration()} instead. * @hide */ + @Nullable @SystemApi @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) @Deprecated @@ -3727,13 +3731,15 @@ public class WifiManager { public class LocalOnlyHotspotReservation implements AutoCloseable { private final CloseGuard mCloseGuard = new CloseGuard(); - private final SoftApConfiguration mConfig; + private final SoftApConfiguration mSoftApConfig; + private final WifiConfiguration mWifiConfig; private boolean mClosed = false; /** @hide */ @VisibleForTesting public LocalOnlyHotspotReservation(SoftApConfiguration config) { - mConfig = config; + mSoftApConfig = config; + mWifiConfig = config.toWifiConfiguration(); mCloseGuard.open("close"); } @@ -3748,7 +3754,7 @@ public class WifiManager { @Deprecated @Nullable public WifiConfiguration getWifiConfiguration() { - return convertToWifiConfiguration(mConfig); + return mWifiConfig; } /** @@ -3756,40 +3762,7 @@ public class WifiManager { */ @NonNull public SoftApConfiguration getSoftApConfiguration() { - return mConfig; - } - - /** - * Convert to WifiConfiguration from SoftApConfuration. - * - * Copy to the filed which is public and used by SoftAp. - */ - private WifiConfiguration convertToWifiConfiguration(SoftApConfiguration softApConfig) { - if (softApConfig == null) return null; - - WifiConfiguration wifiConfig = new WifiConfiguration(); - wifiConfig.networkId = WifiConfiguration.LOCAL_ONLY_NETWORK_ID; - wifiConfig.SSID = softApConfig.getSsid(); - if (softApConfig.getBssid() != null) { - wifiConfig.BSSID = softApConfig.getBssid().toString(); - } - wifiConfig.preSharedKey = softApConfig.getPassphrase(); - wifiConfig.hiddenSSID = softApConfig.isHiddenSsid(); - int authType = softApConfig.getSecurityType(); - switch (authType) { - case SoftApConfiguration.SECURITY_TYPE_OPEN: - authType = WifiConfiguration.KeyMgmt.NONE; - wifiConfig.allowedKeyManagement.set(authType); - break; - case SoftApConfiguration.SECURITY_TYPE_WPA2_PSK: - authType = WifiConfiguration.KeyMgmt.WPA2_PSK; - wifiConfig.allowedKeyManagement.set(authType); - break; - default: - wifiConfig = null; - break; - } - return wifiConfig; + return mSoftApConfig; } @Override diff --git a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java index 6884a4ede27a..2efdd97543a9 100644 --- a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java @@ -18,6 +18,8 @@ package android.net.wifi; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertNull; + import android.net.MacAddress; import android.os.Parcel; @@ -251,7 +253,7 @@ public class SoftApConfigurationTest { } @Test(expected = IllegalArgumentException.class) - public void testsetClientListExceptionWhenExistMacAddressInBothList() { + public void testSetClientListExceptionWhenExistMacAddressInBothList() { final MacAddress testMacAddress_1 = MacAddress.fromString("22:33:44:55:66:77"); final MacAddress testMacAddress_2 = MacAddress.fromString("aa:bb:cc:dd:ee:ff"); ArrayList testAllowedClientList = new ArrayList<>(); @@ -262,4 +264,40 @@ public class SoftApConfigurationTest { SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder(); configBuilder.setClientList(testBlockedClientList, testAllowedClientList); } + + @Test + public void testToWifiConfigurationWithUnsupportedParameter() { + SoftApConfiguration sae_config = new SoftApConfiguration.Builder() + .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE) + .build(); + + assertNull(sae_config.toWifiConfiguration()); + SoftApConfiguration band_6g_config = new SoftApConfiguration.Builder() + .setBand(SoftApConfiguration.BAND_6GHZ) + .build(); + + assertNull(band_6g_config.toWifiConfiguration()); + SoftApConfiguration sae_transition_config = new SoftApConfiguration.Builder() + .setPassphrase("secretsecret", + SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION) + .build(); + + assertNull(sae_transition_config.toWifiConfiguration()); + } + + @Test + public void testToWifiConfigurationWithSupportedParameter() { + SoftApConfiguration softApConfig = new SoftApConfiguration.Builder() + .setPassphrase("secretsecret", + SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) + .setChannel(149, SoftApConfiguration.BAND_5GHZ) + .setHiddenSsid(true) + .build(); + WifiConfiguration wifiConfig = softApConfig.toWifiConfiguration(); + assertThat(wifiConfig.getAuthType()).isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK); + assertThat(wifiConfig.preSharedKey).isEqualTo("secretsecret"); + assertThat(wifiConfig.apBand).isEqualTo(WifiConfiguration.AP_BAND_5GHZ); + assertThat(wifiConfig.apChannel).isEqualTo(149); + assertThat(wifiConfig.hiddenSSID).isEqualTo(true); + } } -- cgit v1.2.3 From 8e5ca5cd7e5a560df027dbc6c5b8fbb446dfc907 Mon Sep 17 00:00:00 2001 From: Xiao Ma Date: Fri, 17 Jan 2020 14:33:52 +0900 Subject: Make Information Elements (IE) of a scan result available as a public API. Bug: 137835398 Test: atest FrameworksWifiTests Test: attach to upstream hotspot device by selecting the sanned ssid from wifi settings, then check the OUI, vendor specific type fileds of IEs from the logcat. Change-Id: If3b9906c75033f51bd35fcf054154125719ea958 --- wifi/java/android/net/wifi/ScanResult.aidl | 2 +- wifi/java/android/net/wifi/ScanResult.java | 79 +++++++++++++++++++++++++----- 2 files changed, 68 insertions(+), 13 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/ScanResult.aidl b/wifi/java/android/net/wifi/ScanResult.aidl index bb66722e4a13..b30689ca5d16 100644 --- a/wifi/java/android/net/wifi/ScanResult.aidl +++ b/wifi/java/android/net/wifi/ScanResult.aidl @@ -16,4 +16,4 @@ package android.net.wifi; -parcelable ScanResult; +@JavaOnlyStableParcelable parcelable ScanResult; diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java index 341330587614..3fda6cda92f5 100644 --- a/wifi/java/android/net/wifi/ScanResult.java +++ b/wifi/java/android/net/wifi/ScanResult.java @@ -17,6 +17,7 @@ package android.net.wifi; import android.annotation.IntDef; +import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; @@ -27,8 +28,10 @@ import com.android.internal.annotations.VisibleForTesting; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Objects; @@ -576,67 +579,120 @@ public class ScanResult implements Parcelable { @UnsupportedAppUsage public List anqpLines; - /** information elements from beacon - * @hide + /** + * information elements from beacon. */ public static class InformationElement { + /** @hide */ @UnsupportedAppUsage public static final int EID_SSID = 0; + /** @hide */ @UnsupportedAppUsage public static final int EID_SUPPORTED_RATES = 1; + /** @hide */ @UnsupportedAppUsage public static final int EID_TIM = 5; + /** @hide */ @UnsupportedAppUsage public static final int EID_BSS_LOAD = 11; + /** @hide */ @UnsupportedAppUsage public static final int EID_ERP = 42; + /** @hide */ public static final int EID_HT_CAPABILITIES = 45; + /** @hide */ @UnsupportedAppUsage public static final int EID_RSN = 48; + /** @hide */ @UnsupportedAppUsage public static final int EID_EXTENDED_SUPPORTED_RATES = 50; + /** @hide */ @UnsupportedAppUsage public static final int EID_HT_OPERATION = 61; + /** @hide */ @UnsupportedAppUsage public static final int EID_INTERWORKING = 107; + /** @hide */ @UnsupportedAppUsage public static final int EID_ROAMING_CONSORTIUM = 111; + /** @hide */ @UnsupportedAppUsage public static final int EID_EXTENDED_CAPS = 127; + /** @hide */ public static final int EID_VHT_CAPABILITIES = 191; + /** @hide */ @UnsupportedAppUsage public static final int EID_VHT_OPERATION = 192; + /** @hide */ @UnsupportedAppUsage public static final int EID_VSA = 221; + /** @hide */ public static final int EID_EXTENSION_PRESENT = 255; - /** - * Extension IDs - */ + // Extension IDs + /** @hide */ public static final int EID_EXT_HE_CAPABILITIES = 35; + /** @hide */ public static final int EID_EXT_HE_OPERATION = 36; + /** @hide */ @UnsupportedAppUsage public int id; + /** @hide */ public int idExt; + + /** @hide */ @UnsupportedAppUsage public byte[] bytes; + /** @hide */ public InformationElement() { } - public InformationElement(InformationElement rhs) { + public InformationElement(@NonNull InformationElement rhs) { this.id = rhs.id; this.idExt = rhs.idExt; this.bytes = rhs.bytes.clone(); } + + /** + * The element ID of the information element. Defined in the IEEE 802.11-2016 spec + * Table 9-77. + */ + public int getId() { + return id; + } + + /** + * The element ID Extension of the information element. Defined in the IEEE 802.11-2016 spec + * Table 9-77. + */ + public int getIdExt() { + return idExt; + } + + /** + * Get the specific content of the information element. + */ + @NonNull + public ByteBuffer getBytes() { + return ByteBuffer.wrap(bytes).asReadOnlyBuffer(); + } } - /** information elements found in the beacon + /** + * information elements found in the beacon. * @hide */ @UnsupportedAppUsage public InformationElement[] informationElements; + /** + * Get all information elements found in the beacon. + */ + @NonNull + public List getInformationElements() { + return Collections.unmodifiableList(Arrays.asList(informationElements)); + } /** ANQP response elements. * @hide @@ -762,8 +818,8 @@ public class ScanResult implements Parcelable { this.wifiSsid = wifiSsid; } - /** copy constructor {@hide} */ - public ScanResult(ScanResult source) { + /** copy constructor */ + public ScanResult(@NonNull ScanResult source) { if (source != null) { wifiSsid = source.wifiSsid; SSID = source.SSID; @@ -929,9 +985,8 @@ public class ScanResult implements Parcelable { } } - /** Implement the Parcelable interface {@hide} */ - @UnsupportedAppUsage - public static final @android.annotation.NonNull Creator CREATOR = + /** Implement the Parcelable interface */ + public static final @NonNull Creator CREATOR = new Creator() { public ScanResult createFromParcel(Parcel in) { WifiSsid wifiSsid = null; -- cgit v1.2.3 From a7079f81aab007e849e135d54d83a85deb2cc918 Mon Sep 17 00:00:00 2001 From: Ahmed ElArabawy Date: Sat, 18 Jan 2020 23:30:34 -0800 Subject: Wifi: Add device wiphy capability parameters This commit adds the following parameters to DeviceWiphyCapabilities: 1. Support of 160MHz / 80+80MHz channel width 2. Max number of Tx/Rx spatial streams. Bug: 144576344 Test: atest com.android.wifi.server Change-Id: Iad4ce736968d23d5abb43c8948d34fe03dcbcb01 --- .../net/wifi/wificond/DeviceWiphyCapabilities.java | 116 ++++++++++++++++++++- .../wifi/wificond/DeviceWiphyCapabilitiesTest.java | 29 ++++++ .../net/wifi/wificond/WifiCondManagerTest.java | 4 + 3 files changed, 147 insertions(+), 2 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/wificond/DeviceWiphyCapabilities.java b/wifi/java/android/net/wifi/wificond/DeviceWiphyCapabilities.java index de1c7600f8ef..13ae3b322841 100644 --- a/wifi/java/android/net/wifi/wificond/DeviceWiphyCapabilities.java +++ b/wifi/java/android/net/wifi/wificond/DeviceWiphyCapabilities.java @@ -37,12 +37,21 @@ public final class DeviceWiphyCapabilities implements Parcelable { private boolean m80211nSupported; private boolean m80211acSupported; private boolean m80211axSupported; + private boolean mChannelWidth160MhzSupported; + private boolean mChannelWidth80p80MhzSupported; + private int mMaxNumberTxSpatialStreams; + private int mMaxNumberRxSpatialStreams; + /** public constructor */ public DeviceWiphyCapabilities() { m80211nSupported = false; m80211acSupported = false; m80211axSupported = false; + mChannelWidth160MhzSupported = false; + mChannelWidth80p80MhzSupported = false; + mMaxNumberTxSpatialStreams = 1; + mMaxNumberRxSpatialStreams = 1; } /** @@ -91,6 +100,88 @@ public final class DeviceWiphyCapabilities implements Parcelable { } } + /** + * Get the support for channel bandwidth + * + * @param chWidth valid values from {@link ScanResult}'s {@code CHANNEL_WIDTH_} + * + * @return {@code true} if supported, {@code false} otherwise. + */ + public boolean isChannelWidthSupported(int chWidth) { + switch (chWidth) { + case ScanResult.CHANNEL_WIDTH_20MHZ: + return true; + case ScanResult.CHANNEL_WIDTH_40MHZ: + return (m80211nSupported || m80211acSupported || m80211axSupported); + case ScanResult.CHANNEL_WIDTH_80MHZ: + return (m80211acSupported || m80211axSupported); + case ScanResult.CHANNEL_WIDTH_160MHZ: + return mChannelWidth160MhzSupported; + case ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ: + return mChannelWidth80p80MhzSupported; + default: + Log.e(TAG, "isChannelWidthSupported called with invalid channel width: " + chWidth); + } + return false; + } + + /** + * Set support for channel bandwidth + * + * @param chWidth valid values are {@link ScanResult#CHANNEL_WIDTH_160MHZ} and + * {@link ScanResult#CHANNEL_WIDTH_80MHZ_PLUS_MHZ} + * @param support {@code true} if supported, {@code false} otherwise. + */ + public void setChannelWidthSupported(int chWidth, boolean support) { + switch (chWidth) { + case ScanResult.CHANNEL_WIDTH_160MHZ: + mChannelWidth160MhzSupported = support; + break; + case ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ: + mChannelWidth80p80MhzSupported = support; + break; + default: + Log.e(TAG, "setChannelWidthSupported called with Invalid channel width: " + + chWidth); + } + } + + /** + * Get maximum number of transmit spatial streams + * + * @return number of spatial streams + */ + public int getMaxNumberTxSpatialStreams() { + return mMaxNumberTxSpatialStreams; + } + + /** + * Set maximum number of transmit spatial streams + * + * @param streams number of spatial streams + */ + public void setMaxNumberTxSpatialStreams(int streams) { + mMaxNumberTxSpatialStreams = streams; + } + + /** + * Get maximum number of receive spatial streams + * + * @return number of streams + */ + public int getMaxNumberRxSpatialStreams() { + return mMaxNumberRxSpatialStreams; + } + + /** + * Set maximum number of receive spatial streams + * + * @param streams number of streams + */ + public void setMaxNumberRxSpatialStreams(int streams) { + mMaxNumberRxSpatialStreams = streams; + } + /** override comparator */ @Override public boolean equals(Object rhs) { @@ -102,13 +193,19 @@ public final class DeviceWiphyCapabilities implements Parcelable { return m80211nSupported == capa.m80211nSupported && m80211acSupported == capa.m80211acSupported - && m80211axSupported == capa.m80211axSupported; + && m80211axSupported == capa.m80211axSupported + && mChannelWidth160MhzSupported == capa.mChannelWidth160MhzSupported + && mChannelWidth80p80MhzSupported == capa.mChannelWidth80p80MhzSupported + && mMaxNumberTxSpatialStreams == capa.mMaxNumberTxSpatialStreams + && mMaxNumberRxSpatialStreams == capa.mMaxNumberRxSpatialStreams; } /** override hash code */ @Override public int hashCode() { - return Objects.hash(m80211nSupported, m80211acSupported, m80211axSupported); + return Objects.hash(m80211nSupported, m80211acSupported, m80211axSupported, + mChannelWidth160MhzSupported, mChannelWidth80p80MhzSupported, + mMaxNumberTxSpatialStreams, mMaxNumberRxSpatialStreams); } /** implement Parcelable interface */ @@ -126,6 +223,10 @@ public final class DeviceWiphyCapabilities implements Parcelable { out.writeBoolean(m80211nSupported); out.writeBoolean(m80211acSupported); out.writeBoolean(m80211axSupported); + out.writeBoolean(mChannelWidth160MhzSupported); + out.writeBoolean(mChannelWidth80p80MhzSupported); + out.writeInt(mMaxNumberTxSpatialStreams); + out.writeInt(mMaxNumberRxSpatialStreams); } @Override @@ -134,6 +235,13 @@ public final class DeviceWiphyCapabilities implements Parcelable { sb.append("m80211nSupported:").append(m80211nSupported ? "Yes" : "No"); sb.append("m80211acSupported:").append(m80211acSupported ? "Yes" : "No"); sb.append("m80211axSupported:").append(m80211axSupported ? "Yes" : "No"); + sb.append("mChannelWidth160MhzSupported: ") + .append(mChannelWidth160MhzSupported ? "Yes" : "No"); + sb.append("mChannelWidth80p80MhzSupported: ") + .append(mChannelWidth80p80MhzSupported ? "Yes" : "No"); + sb.append("mMaxNumberTxSpatialStreams: ").append(mMaxNumberTxSpatialStreams); + sb.append("mMaxNumberRxSpatialStreams: ").append(mMaxNumberRxSpatialStreams); + return sb.toString(); } @@ -149,6 +257,10 @@ public final class DeviceWiphyCapabilities implements Parcelable { capabilities.m80211nSupported = in.readBoolean(); capabilities.m80211acSupported = in.readBoolean(); capabilities.m80211axSupported = in.readBoolean(); + capabilities.mChannelWidth160MhzSupported = in.readBoolean(); + capabilities.mChannelWidth80p80MhzSupported = in.readBoolean(); + capabilities.mMaxNumberTxSpatialStreams = in.readInt(); + capabilities.mMaxNumberRxSpatialStreams = in.readInt(); return capabilities; } diff --git a/wifi/tests/src/android/net/wifi/wificond/DeviceWiphyCapabilitiesTest.java b/wifi/tests/src/android/net/wifi/wificond/DeviceWiphyCapabilitiesTest.java index 1479acfe8e20..8e3627acd4ed 100644 --- a/wifi/tests/src/android/net/wifi/wificond/DeviceWiphyCapabilitiesTest.java +++ b/wifi/tests/src/android/net/wifi/wificond/DeviceWiphyCapabilitiesTest.java @@ -45,6 +45,10 @@ public class DeviceWiphyCapabilitiesTest { capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, true); capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, true); capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AX, false); + capa.setChannelWidthSupported(ScanResult.CHANNEL_WIDTH_160MHZ, true); + capa.setChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ, false); + capa.setMaxNumberTxSpatialStreams(2); + capa.setMaxNumberRxSpatialStreams(1); Parcel parcel = Parcel.obtain(); capa.writeToParcel(parcel, 0); @@ -56,4 +60,29 @@ public class DeviceWiphyCapabilitiesTest { assertEquals(capa, capaDeserialized); assertEquals(capa.hashCode(), capaDeserialized.hashCode()); } + + /** + * Test mapping wifi standard support into channel width support + */ + @Test + public void testMappingWifiStandardIntoChannelWidthSupport() { + DeviceWiphyCapabilities capa = new DeviceWiphyCapabilities(); + + capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, false); + capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, false); + capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AX, false); + assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_20MHZ)); + assertEquals(false, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_40MHZ)); + assertEquals(false, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ)); + + capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, true); + assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_20MHZ)); + assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_40MHZ)); + assertEquals(false, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ)); + + capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, true); + assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_20MHZ)); + assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_40MHZ)); + assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ)); + } } diff --git a/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java b/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java index 619c95efb173..f262268d7179 100644 --- a/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java +++ b/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java @@ -1046,6 +1046,10 @@ public class WifiCondManagerTest { capaExpected.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, true); capaExpected.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, true); capaExpected.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AX, false); + capaExpected.setChannelWidthSupported(ScanResult.CHANNEL_WIDTH_160MHZ, true); + capaExpected.setChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ, false); + capaExpected.setMaxNumberTxSpatialStreams(2); + capaExpected.setMaxNumberRxSpatialStreams(1); when(mWificond.getDeviceWiphyCapabilities(TEST_INTERFACE_NAME)) .thenReturn(capaExpected); -- cgit v1.2.3 From e72c18698087a17ab52904a73de5a38b7aec8c5c Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Mon, 20 Jan 2020 13:25:19 +0800 Subject: p2p: add new API to indicate Content Protection support status Bug: 147929113 Test: atest FrameworksWifiApiTests Change-Id: I88b48b4a0a0bd5c80b920104bcb15dfd89ba1763 --- wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java | 25 ++++++++++++++++++++++ .../android/net/wifi/p2p/WifiP2pWfdInfoTest.java | 6 +++++- 2 files changed, 30 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java index a4115027b6c1..5484d248429f 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java @@ -61,6 +61,9 @@ public final class WifiP2pWfdInfo implements Parcelable { * {@link #mDeviceInfo} & {@link #DEVICE_TYPE} is one of {@link #DEVICE_TYPE_WFD_SOURCE}, * {@link #DEVICE_TYPE_PRIMARY_SINK}, {@link #DEVICE_TYPE_SECONDARY_SINK} or * {@link #DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK}. + * + * The bit definition is listed in 5.1.2 WFD Device Information Subelement in + * Wi-Fi Display Technical Specification. */ private static final int DEVICE_TYPE = 1 << 1 | 1 << 0; private static final int COUPLED_SINK_SUPPORT_AT_SOURCE = 1 << 2; @@ -69,6 +72,8 @@ public final class WifiP2pWfdInfo implements Parcelable { private static final int SESSION_AVAILABLE_BIT2 = 1 << 5; private static final int SESSION_AVAILABLE = SESSION_AVAILABLE_BIT2 | SESSION_AVAILABLE_BIT1; + /* The support of Content Protection using the HDCP system 2.0/2.1. */ + private static final int CONTENT_PROTECTION_SUPPORT = 1 << 8; private int mCtrlPort; @@ -146,6 +151,26 @@ public final class WifiP2pWfdInfo implements Parcelable { } } + /** + * @return true if Content Protection using the HDCP system 2.0/2.1 is supported. + */ + public boolean isContentProtectionSupported() { + return (mDeviceInfo & CONTENT_PROTECTION_SUPPORT) != 0; + } + + /** + * Sets whether Content Protection using the HDCP system 2.0/2.1 is supported. + * + * @param enabled true to indicate that Content Protection is supported, false otherwise. + */ + public void setContentProtectionSupported(boolean enabled) { + if (enabled) { + mDeviceInfo |= CONTENT_PROTECTION_SUPPORT; + } else { + mDeviceInfo &= ~CONTENT_PROTECTION_SUPPORT; + } + } + /** Returns the TCP port at which the WFD Device listens for RTSP messages. */ public int getControlPort() { return mCtrlPort; diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java index cea73efc88d0..15a0aacf6e5b 100644 --- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java +++ b/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java @@ -45,6 +45,7 @@ public class WifiP2pWfdInfoTest { // initialize device info flags. mSourceInfo.setDeviceType(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE); mSourceInfo.setSessionAvailable(true); + mSourceInfo.setContentProtectionSupported(true); } /** @@ -63,13 +64,16 @@ public class WifiP2pWfdInfoTest { info.setSessionAvailable(true); assertTrue(info.isSessionAvailable()); + info.setContentProtectionSupported(true); + assertTrue(info.isContentProtectionSupported()); + info.setControlPort(TEST_CTRL_PORT); assertEquals(TEST_CTRL_PORT, info.getControlPort()); info.setMaxThroughput(TEST_MAX_TPUT); assertEquals(TEST_MAX_TPUT, info.getMaxThroughput()); - assertEquals("0010270f0400", info.getDeviceInfoHex()); + assertEquals("0110270f0400", info.getDeviceInfoHex()); } /** -- cgit v1.2.3 From f93897581dd0cf832088762e7d5e52f4b27f3601 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Tue, 21 Jan 2020 07:09:08 -0800 Subject: WifiScanner: Deprecate gscan API's Bug: 71855918 Test: Compiles Change-Id: Ibf5c4b012af74914f997866fa24608a854dd9868 --- wifi/java/android/net/wifi/WifiScanner.java | 32 ++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index 4f602fac7a36..18533ef5b117 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -291,28 +291,46 @@ public class WifiScanner { @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public final List hiddenNetworks = new ArrayList<>(); - /** period of background scan; in millisecond, 0 => single shot scan */ + /** + * period of background scan; in millisecond, 0 => single shot scan + * @deprecated Background scan support is removed. + */ + @Deprecated public int periodInMs; - /** must have a valid REPORT_EVENT value */ + /** + * must have a valid REPORT_EVENT value + * @deprecated Background scan support is removed. + */ + @Deprecated public int reportEvents; - /** defines number of bssids to cache from each scan */ + /** + * defines number of bssids to cache from each scan + * @deprecated Background scan support is removed. + */ + @Deprecated public int numBssidsPerScan; /** * defines number of scans to cache; use it with REPORT_EVENT_AFTER_BUFFER_FULL * to wake up at fixed interval + * @deprecated Background scan support is removed. */ + @Deprecated public int maxScansToCache; /** * if maxPeriodInMs is non zero or different than period, then this bucket is * a truncated binary exponential backoff bucket and the scan period will grow * exponentially as per formula: actual_period(N) = period * (2 ^ (N/stepCount)) * to maxPeriodInMs + * @deprecated Background scan support is removed. */ + @Deprecated public int maxPeriodInMs; /** * for truncated binary exponential back off bucket, number of scans to perform * for a given period + * @deprecated Background scan support is removed. */ + @Deprecated public int stepCount; /** * Flag to indicate if the scan settings are targeted for PNO scan. @@ -788,7 +806,9 @@ public class WifiScanner { /** * Framework co-ordinates scans across multiple apps; so it may not give exactly the * same period requested. If period of a scan is changed; it is reported by this event. + * @deprecated Background scan support is removed. */ + @Deprecated public void onPeriodChanged(int periodInMs); /** * reports results retrieved from background scan and single shot scans @@ -891,7 +911,9 @@ public class WifiScanner { * @param listener specifies the object to report events to. This object is also treated as a * key for this scan, and must also be specified to cancel the scan. Multiple * scans should also not share this object. + * @deprecated Background scan support is removed. */ + @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startBackgroundScan(ScanSettings settings, ScanListener listener, WorkSource workSource) { @@ -911,7 +933,9 @@ public class WifiScanner { * stop an ongoing wifi scan * @param listener specifies which scan to cancel; must be same object as passed in {@link * #startBackgroundScan} + * @deprecated Background scan support is removed. */ + @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void stopBackgroundScan(ScanListener listener) { Objects.requireNonNull(listener, "listener cannot be null"); @@ -927,7 +951,9 @@ public class WifiScanner { /** * reports currently available scan results on appropriate listeners * @return true if all scan results were reported correctly + * @deprecated Background scan support is removed. */ + @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean getScanResults() { validateChannel(); -- cgit v1.2.3 From e4d7f7d8ccd1f6f403af8aaedd584276b6e7f761 Mon Sep 17 00:00:00 2001 From: "Nate(Qiang) Jiang" Date: Tue, 21 Jan 2020 12:37:03 -0800 Subject: Add error code for app adding invalid suggestions If one or more of the suggestions added is invalid, will reject all. Bug: 147907699 Test: atest android.net.wifi Change-Id: I2f6c83a811539c682861c4d6e622c52f583d9832 --- wifi/java/android/net/wifi/WifiManager.java | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index c35303da9056..208ce9c37b23 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -201,6 +201,13 @@ public class WifiManager { */ public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_NOT_ALLOWED = 6; + /** + * Reason code if one or more of the network suggestions added is invalid. + * + * Please user {@link WifiNetworkSuggestion.Builder} to create network suggestions. + */ + public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_INVALID = 7; + /** @hide */ @IntDef(prefix = { "STATUS_NETWORK_SUGGESTIONS_" }, value = { STATUS_NETWORK_SUGGESTIONS_SUCCESS, @@ -210,6 +217,7 @@ public class WifiManager { STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_EXCEEDS_MAX_PER_APP, STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID, STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_NOT_ALLOWED, + STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_INVALID, }) @Retention(RetentionPolicy.SOURCE) public @interface NetworkSuggestionsStatusCode {} -- cgit v1.2.3 From 6dcd7688737432bf6f2a2f5657983af07c56ff54 Mon Sep 17 00:00:00 2001 From: David Su Date: Tue, 21 Jan 2020 11:23:00 -0800 Subject: Export Wifi Parcelables AIDLs from framework.jar Add Wifi public/@SystemApi Parcelable AIDLs to framework.jar AIDL exports so that they can be referenced outside the Wifi module. Create a new folder "aidl-export" to separate the AIDLs we want to export to allow external callers to reference in their AIDL. Private AIDLs remain in the "java" folder. Bug: 140299412 Test: compiles Change-Id: I4e0dc1119bf2b49865c9b5cdf23c571528228902 --- wifi/Android.bp | 17 ++++++++++++++++- wifi/aidl-export/android/net/wifi/ScanResult.aidl | 19 +++++++++++++++++++ .../android/net/wifi/SoftApCapability.aidl | 19 +++++++++++++++++++ .../android/net/wifi/SoftApConfiguration.aidl | 19 +++++++++++++++++++ wifi/aidl-export/android/net/wifi/SoftApInfo.aidl | 20 ++++++++++++++++++++ wifi/aidl-export/android/net/wifi/WifiClient.aidl | 19 +++++++++++++++++++ .../android/net/wifi/WifiConfiguration.aidl | 19 +++++++++++++++++++ .../android/net/wifi/WifiEnterpriseConfig.aidl | 19 +++++++++++++++++++ wifi/aidl-export/android/net/wifi/WifiInfo.aidl | 19 +++++++++++++++++++ .../net/wifi/WifiNetworkConnectionStatistics.aidl | 19 +++++++++++++++++++ .../android/net/wifi/WifiNetworkSuggestion.aidl | 19 +++++++++++++++++++ .../android/net/wifi/WifiUsabilityStatsEntry.aidl | 19 +++++++++++++++++++ wifi/aidl-export/android/net/wifi/WpsInfo.aidl | 19 +++++++++++++++++++ .../android/net/wifi/aware/Characteristics.aidl | 19 +++++++++++++++++++ .../android/net/wifi/aware/PublishConfig.aidl | 19 +++++++++++++++++++ .../android/net/wifi/aware/SubscribeConfig.aidl | 19 +++++++++++++++++++ .../android/net/wifi/hotspot2/OsuProvider.aidl | 19 +++++++++++++++++++ .../net/wifi/hotspot2/PasspointConfiguration.aidl | 19 +++++++++++++++++++ .../android/net/wifi/hotspot2/pps/Credential.aidl | 19 +++++++++++++++++++ .../android/net/wifi/hotspot2/pps/HomeSp.aidl | 19 +++++++++++++++++++ .../android/net/wifi/p2p/WifiP2pConfig.aidl | 19 +++++++++++++++++++ .../android/net/wifi/p2p/WifiP2pDevice.aidl | 19 +++++++++++++++++++ .../android/net/wifi/p2p/WifiP2pDeviceList.aidl | 19 +++++++++++++++++++ .../android/net/wifi/p2p/WifiP2pGroup.aidl | 19 +++++++++++++++++++ .../android/net/wifi/p2p/WifiP2pInfo.aidl | 19 +++++++++++++++++++ .../android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl | 19 +++++++++++++++++++ .../net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl | 19 +++++++++++++++++++ .../android/net/wifi/rtt/RangingRequest.aidl | 19 +++++++++++++++++++ .../android/net/wifi/rtt/RangingResult.aidl | 19 +++++++++++++++++++ .../android/net/wifi/rtt/ResponderConfig.aidl | 19 +++++++++++++++++++ wifi/java/android/net/wifi/ScanResult.aidl | 19 ------------------- wifi/java/android/net/wifi/SoftApCapability.aidl | 19 ------------------- wifi/java/android/net/wifi/SoftApConfiguration.aidl | 19 ------------------- wifi/java/android/net/wifi/SoftApInfo.aidl | 20 -------------------- wifi/java/android/net/wifi/WifiClient.aidl | 19 ------------------- wifi/java/android/net/wifi/WifiConfiguration.aidl | 19 ------------------- wifi/java/android/net/wifi/WifiEnterpriseConfig.aidl | 19 ------------------- wifi/java/android/net/wifi/WifiInfo.aidl | 19 ------------------- .../net/wifi/WifiNetworkConnectionStatistics.aidl | 19 ------------------- .../java/android/net/wifi/WifiNetworkSuggestion.aidl | 19 ------------------- .../android/net/wifi/WifiUsabilityStatsEntry.aidl | 19 ------------------- wifi/java/android/net/wifi/WpsInfo.aidl | 19 ------------------- .../java/android/net/wifi/aware/Characteristics.aidl | 19 ------------------- wifi/java/android/net/wifi/aware/PublishConfig.aidl | 19 ------------------- .../java/android/net/wifi/aware/SubscribeConfig.aidl | 19 ------------------- wifi/java/android/net/wifi/hotspot2/OsuProvider.aidl | 19 ------------------- .../net/wifi/hotspot2/PasspointConfiguration.aidl | 19 ------------------- .../android/net/wifi/hotspot2/pps/Credential.aidl | 19 ------------------- wifi/java/android/net/wifi/hotspot2/pps/HomeSp.aidl | 19 ------------------- wifi/java/android/net/wifi/p2p/WifiP2pConfig.aidl | 19 ------------------- wifi/java/android/net/wifi/p2p/WifiP2pDevice.aidl | 19 ------------------- .../java/android/net/wifi/p2p/WifiP2pDeviceList.aidl | 19 ------------------- wifi/java/android/net/wifi/p2p/WifiP2pGroup.aidl | 19 ------------------- wifi/java/android/net/wifi/p2p/WifiP2pInfo.aidl | 19 ------------------- .../android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl | 19 ------------------- .../net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl | 19 ------------------- wifi/java/android/net/wifi/rtt/RangingRequest.aidl | 19 ------------------- wifi/java/android/net/wifi/rtt/RangingResult.aidl | 19 ------------------- wifi/java/android/net/wifi/rtt/ResponderConfig.aidl | 19 ------------------- 59 files changed, 568 insertions(+), 553 deletions(-) create mode 100644 wifi/aidl-export/android/net/wifi/ScanResult.aidl create mode 100644 wifi/aidl-export/android/net/wifi/SoftApCapability.aidl create mode 100644 wifi/aidl-export/android/net/wifi/SoftApConfiguration.aidl create mode 100644 wifi/aidl-export/android/net/wifi/SoftApInfo.aidl create mode 100644 wifi/aidl-export/android/net/wifi/WifiClient.aidl create mode 100644 wifi/aidl-export/android/net/wifi/WifiConfiguration.aidl create mode 100644 wifi/aidl-export/android/net/wifi/WifiEnterpriseConfig.aidl create mode 100644 wifi/aidl-export/android/net/wifi/WifiInfo.aidl create mode 100644 wifi/aidl-export/android/net/wifi/WifiNetworkConnectionStatistics.aidl create mode 100644 wifi/aidl-export/android/net/wifi/WifiNetworkSuggestion.aidl create mode 100644 wifi/aidl-export/android/net/wifi/WifiUsabilityStatsEntry.aidl create mode 100644 wifi/aidl-export/android/net/wifi/WpsInfo.aidl create mode 100644 wifi/aidl-export/android/net/wifi/aware/Characteristics.aidl create mode 100644 wifi/aidl-export/android/net/wifi/aware/PublishConfig.aidl create mode 100644 wifi/aidl-export/android/net/wifi/aware/SubscribeConfig.aidl create mode 100644 wifi/aidl-export/android/net/wifi/hotspot2/OsuProvider.aidl create mode 100644 wifi/aidl-export/android/net/wifi/hotspot2/PasspointConfiguration.aidl create mode 100644 wifi/aidl-export/android/net/wifi/hotspot2/pps/Credential.aidl create mode 100644 wifi/aidl-export/android/net/wifi/hotspot2/pps/HomeSp.aidl create mode 100644 wifi/aidl-export/android/net/wifi/p2p/WifiP2pConfig.aidl create mode 100644 wifi/aidl-export/android/net/wifi/p2p/WifiP2pDevice.aidl create mode 100644 wifi/aidl-export/android/net/wifi/p2p/WifiP2pDeviceList.aidl create mode 100644 wifi/aidl-export/android/net/wifi/p2p/WifiP2pGroup.aidl create mode 100644 wifi/aidl-export/android/net/wifi/p2p/WifiP2pInfo.aidl create mode 100644 wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl create mode 100644 wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl create mode 100644 wifi/aidl-export/android/net/wifi/rtt/RangingRequest.aidl create mode 100644 wifi/aidl-export/android/net/wifi/rtt/RangingResult.aidl create mode 100644 wifi/aidl-export/android/net/wifi/rtt/ResponderConfig.aidl delete mode 100644 wifi/java/android/net/wifi/ScanResult.aidl delete mode 100644 wifi/java/android/net/wifi/SoftApCapability.aidl delete mode 100644 wifi/java/android/net/wifi/SoftApConfiguration.aidl delete mode 100644 wifi/java/android/net/wifi/SoftApInfo.aidl delete mode 100644 wifi/java/android/net/wifi/WifiClient.aidl delete mode 100644 wifi/java/android/net/wifi/WifiConfiguration.aidl delete mode 100644 wifi/java/android/net/wifi/WifiEnterpriseConfig.aidl delete mode 100644 wifi/java/android/net/wifi/WifiInfo.aidl delete mode 100644 wifi/java/android/net/wifi/WifiNetworkConnectionStatistics.aidl delete mode 100644 wifi/java/android/net/wifi/WifiNetworkSuggestion.aidl delete mode 100644 wifi/java/android/net/wifi/WifiUsabilityStatsEntry.aidl delete mode 100644 wifi/java/android/net/wifi/WpsInfo.aidl delete mode 100644 wifi/java/android/net/wifi/aware/Characteristics.aidl delete mode 100644 wifi/java/android/net/wifi/aware/PublishConfig.aidl delete mode 100644 wifi/java/android/net/wifi/aware/SubscribeConfig.aidl delete mode 100644 wifi/java/android/net/wifi/hotspot2/OsuProvider.aidl delete mode 100644 wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.aidl delete mode 100644 wifi/java/android/net/wifi/hotspot2/pps/Credential.aidl delete mode 100644 wifi/java/android/net/wifi/hotspot2/pps/HomeSp.aidl delete mode 100644 wifi/java/android/net/wifi/p2p/WifiP2pConfig.aidl delete mode 100644 wifi/java/android/net/wifi/p2p/WifiP2pDevice.aidl delete mode 100644 wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.aidl delete mode 100644 wifi/java/android/net/wifi/p2p/WifiP2pGroup.aidl delete mode 100644 wifi/java/android/net/wifi/p2p/WifiP2pInfo.aidl delete mode 100644 wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl delete mode 100644 wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl delete mode 100644 wifi/java/android/net/wifi/rtt/RangingRequest.aidl delete mode 100644 wifi/java/android/net/wifi/rtt/RangingResult.aidl delete mode 100644 wifi/java/android/net/wifi/rtt/ResponderConfig.aidl (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 099cbff15fb4..8fc8af980f9e 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -12,9 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. +filegroup { + name: "framework-wifi-updatable-exported-aidl-sources", + srcs: ["aidl-export/**/*.aidl"], + path: "aidl-export", + visibility: ["//visibility:private"], +} filegroup { - name: "framework-wifi-updatable-sources", + name: "framework-wifi-updatable-java-sources", srcs: [ "java/**/*.java", "java/**/*.aidl", @@ -23,6 +29,15 @@ filegroup { ":framework-wifi-non-updatable-sources" ], path: "java", + visibility: ["//visibility:private"], +} + +filegroup { + name: "framework-wifi-updatable-sources", + srcs: [ + ":framework-wifi-updatable-java-sources", + ":framework-wifi-updatable-exported-aidl-sources", + ], } filegroup { diff --git a/wifi/aidl-export/android/net/wifi/ScanResult.aidl b/wifi/aidl-export/android/net/wifi/ScanResult.aidl new file mode 100644 index 000000000000..b30689ca5d16 --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/ScanResult.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2008, 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; + +@JavaOnlyStableParcelable parcelable ScanResult; diff --git a/wifi/aidl-export/android/net/wifi/SoftApCapability.aidl b/wifi/aidl-export/android/net/wifi/SoftApCapability.aidl new file mode 100644 index 000000000000..bf30709f15d1 --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/SoftApCapability.aidl @@ -0,0 +1,19 @@ +/** + * 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; + +parcelable SoftApCapability; diff --git a/wifi/aidl-export/android/net/wifi/SoftApConfiguration.aidl b/wifi/aidl-export/android/net/wifi/SoftApConfiguration.aidl new file mode 100644 index 000000000000..1d06f458318f --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/SoftApConfiguration.aidl @@ -0,0 +1,19 @@ +/* + * 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; + +parcelable SoftApConfiguration; \ No newline at end of file diff --git a/wifi/aidl-export/android/net/wifi/SoftApInfo.aidl b/wifi/aidl-export/android/net/wifi/SoftApInfo.aidl new file mode 100644 index 000000000000..d4551cfac044 --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/SoftApInfo.aidl @@ -0,0 +1,20 @@ +/** + * 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; + +parcelable SoftApInfo; + diff --git a/wifi/aidl-export/android/net/wifi/WifiClient.aidl b/wifi/aidl-export/android/net/wifi/WifiClient.aidl new file mode 100644 index 000000000000..accdaddfc848 --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/WifiClient.aidl @@ -0,0 +1,19 @@ +/* + * 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; + +@JavaOnlyStableParcelable parcelable WifiClient; \ No newline at end of file diff --git a/wifi/aidl-export/android/net/wifi/WifiConfiguration.aidl b/wifi/aidl-export/android/net/wifi/WifiConfiguration.aidl new file mode 100644 index 000000000000..237a74da3052 --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/WifiConfiguration.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2008, 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; + +parcelable WifiConfiguration; diff --git a/wifi/aidl-export/android/net/wifi/WifiEnterpriseConfig.aidl b/wifi/aidl-export/android/net/wifi/WifiEnterpriseConfig.aidl new file mode 100644 index 000000000000..b0f5f849c7ec --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/WifiEnterpriseConfig.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2013, 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; + +parcelable WifiEnterpriseConfig; diff --git a/wifi/aidl-export/android/net/wifi/WifiInfo.aidl b/wifi/aidl-export/android/net/wifi/WifiInfo.aidl new file mode 100644 index 000000000000..db47f0b5aa31 --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/WifiInfo.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2008, 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; + +parcelable WifiInfo; diff --git a/wifi/aidl-export/android/net/wifi/WifiNetworkConnectionStatistics.aidl b/wifi/aidl-export/android/net/wifi/WifiNetworkConnectionStatistics.aidl new file mode 100644 index 000000000000..5f497e2796d8 --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/WifiNetworkConnectionStatistics.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2014, 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; + +parcelable WifiNetworkConnectionStatistics; diff --git a/wifi/aidl-export/android/net/wifi/WifiNetworkSuggestion.aidl b/wifi/aidl-export/android/net/wifi/WifiNetworkSuggestion.aidl new file mode 100644 index 000000000000..eb6995f561de --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/WifiNetworkSuggestion.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2018, 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; + +parcelable WifiNetworkSuggestion; diff --git a/wifi/aidl-export/android/net/wifi/WifiUsabilityStatsEntry.aidl b/wifi/aidl-export/android/net/wifi/WifiUsabilityStatsEntry.aidl new file mode 100644 index 000000000000..839af54b81ba --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/WifiUsabilityStatsEntry.aidl @@ -0,0 +1,19 @@ +/* + * 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; + +parcelable WifiUsabilityStatsEntry; diff --git a/wifi/aidl-export/android/net/wifi/WpsInfo.aidl b/wifi/aidl-export/android/net/wifi/WpsInfo.aidl new file mode 100644 index 000000000000..f5e4ebe4f1af --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/WpsInfo.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2011, 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; + +parcelable WpsInfo; diff --git a/wifi/aidl-export/android/net/wifi/aware/Characteristics.aidl b/wifi/aidl-export/android/net/wifi/aware/Characteristics.aidl new file mode 100644 index 000000000000..77305e9dae0a --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/aware/Characteristics.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2016 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.aware; + +parcelable Characteristics; diff --git a/wifi/aidl-export/android/net/wifi/aware/PublishConfig.aidl b/wifi/aidl-export/android/net/wifi/aware/PublishConfig.aidl new file mode 100644 index 000000000000..2e6dd00b245a --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/aware/PublishConfig.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2016 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.aware; + +parcelable PublishConfig; diff --git a/wifi/aidl-export/android/net/wifi/aware/SubscribeConfig.aidl b/wifi/aidl-export/android/net/wifi/aware/SubscribeConfig.aidl new file mode 100644 index 000000000000..bd73d5ee5ecc --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/aware/SubscribeConfig.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2016 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.aware; + +parcelable SubscribeConfig; diff --git a/wifi/aidl-export/android/net/wifi/hotspot2/OsuProvider.aidl b/wifi/aidl-export/android/net/wifi/hotspot2/OsuProvider.aidl new file mode 100644 index 000000000000..23d0f22e866b --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/hotspot2/OsuProvider.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package android.net.wifi.hotspot2; + +parcelable OsuProvider; diff --git a/wifi/aidl-export/android/net/wifi/hotspot2/PasspointConfiguration.aidl b/wifi/aidl-export/android/net/wifi/hotspot2/PasspointConfiguration.aidl new file mode 100644 index 000000000000..6b1cea8edb5a --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/hotspot2/PasspointConfiguration.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2016, 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.hotspot2; + +parcelable PasspointConfiguration; diff --git a/wifi/aidl-export/android/net/wifi/hotspot2/pps/Credential.aidl b/wifi/aidl-export/android/net/wifi/hotspot2/pps/Credential.aidl new file mode 100644 index 000000000000..3d8e8330c2c4 --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/hotspot2/pps/Credential.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2016, 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.hotspot2.pps; + +parcelable Credential; diff --git a/wifi/aidl-export/android/net/wifi/hotspot2/pps/HomeSp.aidl b/wifi/aidl-export/android/net/wifi/hotspot2/pps/HomeSp.aidl new file mode 100644 index 000000000000..6d343bde7081 --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/hotspot2/pps/HomeSp.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2016, 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.hotspot2.pps; + +parcelable HomeSp; diff --git a/wifi/aidl-export/android/net/wifi/p2p/WifiP2pConfig.aidl b/wifi/aidl-export/android/net/wifi/p2p/WifiP2pConfig.aidl new file mode 100644 index 000000000000..ea3b2803d514 --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/p2p/WifiP2pConfig.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2011, 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.p2p; + +parcelable WifiP2pConfig; diff --git a/wifi/aidl-export/android/net/wifi/p2p/WifiP2pDevice.aidl b/wifi/aidl-export/android/net/wifi/p2p/WifiP2pDevice.aidl new file mode 100644 index 000000000000..8790c6ffe903 --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/p2p/WifiP2pDevice.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2011, 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.p2p; + +parcelable WifiP2pDevice; diff --git a/wifi/aidl-export/android/net/wifi/p2p/WifiP2pDeviceList.aidl b/wifi/aidl-export/android/net/wifi/p2p/WifiP2pDeviceList.aidl new file mode 100644 index 000000000000..6c79009315b5 --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/p2p/WifiP2pDeviceList.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2011, 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.p2p; + +parcelable WifiP2pDeviceList; diff --git a/wifi/aidl-export/android/net/wifi/p2p/WifiP2pGroup.aidl b/wifi/aidl-export/android/net/wifi/p2p/WifiP2pGroup.aidl new file mode 100644 index 000000000000..403f2b19bfda --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/p2p/WifiP2pGroup.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2011, 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.p2p; + +parcelable WifiP2pGroup; diff --git a/wifi/aidl-export/android/net/wifi/p2p/WifiP2pInfo.aidl b/wifi/aidl-export/android/net/wifi/p2p/WifiP2pInfo.aidl new file mode 100644 index 000000000000..a347148622ff --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/p2p/WifiP2pInfo.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2011, 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.p2p; + +parcelable WifiP2pInfo; diff --git a/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl b/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl new file mode 100644 index 000000000000..cf2cb4ae5eb4 --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl @@ -0,0 +1,19 @@ +/* + * 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.p2p.servicediscovery; + +parcelable WifiP2pServiceInfo; diff --git a/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl b/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl new file mode 100644 index 000000000000..d5a1e8f505a9 --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl @@ -0,0 +1,19 @@ +/* + * 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.p2p.servicediscovery; + +parcelable WifiP2pServiceRequest; diff --git a/wifi/aidl-export/android/net/wifi/rtt/RangingRequest.aidl b/wifi/aidl-export/android/net/wifi/rtt/RangingRequest.aidl new file mode 100644 index 000000000000..8053c9416aeb --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/rtt/RangingRequest.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.rtt; + +parcelable RangingRequest; diff --git a/wifi/aidl-export/android/net/wifi/rtt/RangingResult.aidl b/wifi/aidl-export/android/net/wifi/rtt/RangingResult.aidl new file mode 100644 index 000000000000..ae295a610afa --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/rtt/RangingResult.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.rtt; + +parcelable RangingResult; diff --git a/wifi/aidl-export/android/net/wifi/rtt/ResponderConfig.aidl b/wifi/aidl-export/android/net/wifi/rtt/ResponderConfig.aidl new file mode 100644 index 000000000000..fd3988aca06c --- /dev/null +++ b/wifi/aidl-export/android/net/wifi/rtt/ResponderConfig.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.rtt; + +parcelable ResponderConfig; diff --git a/wifi/java/android/net/wifi/ScanResult.aidl b/wifi/java/android/net/wifi/ScanResult.aidl deleted file mode 100644 index b30689ca5d16..000000000000 --- a/wifi/java/android/net/wifi/ScanResult.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2008, 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; - -@JavaOnlyStableParcelable parcelable ScanResult; diff --git a/wifi/java/android/net/wifi/SoftApCapability.aidl b/wifi/java/android/net/wifi/SoftApCapability.aidl deleted file mode 100644 index bf30709f15d1..000000000000 --- a/wifi/java/android/net/wifi/SoftApCapability.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * 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; - -parcelable SoftApCapability; diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.aidl b/wifi/java/android/net/wifi/SoftApConfiguration.aidl deleted file mode 100644 index 1d06f458318f..000000000000 --- a/wifi/java/android/net/wifi/SoftApConfiguration.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 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; - -parcelable SoftApConfiguration; \ No newline at end of file diff --git a/wifi/java/android/net/wifi/SoftApInfo.aidl b/wifi/java/android/net/wifi/SoftApInfo.aidl deleted file mode 100644 index d4551cfac044..000000000000 --- a/wifi/java/android/net/wifi/SoftApInfo.aidl +++ /dev/null @@ -1,20 +0,0 @@ -/** - * 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; - -parcelable SoftApInfo; - diff --git a/wifi/java/android/net/wifi/WifiClient.aidl b/wifi/java/android/net/wifi/WifiClient.aidl deleted file mode 100644 index accdaddfc848..000000000000 --- a/wifi/java/android/net/wifi/WifiClient.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 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; - -@JavaOnlyStableParcelable parcelable WifiClient; \ No newline at end of file diff --git a/wifi/java/android/net/wifi/WifiConfiguration.aidl b/wifi/java/android/net/wifi/WifiConfiguration.aidl deleted file mode 100644 index 237a74da3052..000000000000 --- a/wifi/java/android/net/wifi/WifiConfiguration.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2008, 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; - -parcelable WifiConfiguration; diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.aidl b/wifi/java/android/net/wifi/WifiEnterpriseConfig.aidl deleted file mode 100644 index b0f5f849c7ec..000000000000 --- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2013, 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; - -parcelable WifiEnterpriseConfig; diff --git a/wifi/java/android/net/wifi/WifiInfo.aidl b/wifi/java/android/net/wifi/WifiInfo.aidl deleted file mode 100644 index db47f0b5aa31..000000000000 --- a/wifi/java/android/net/wifi/WifiInfo.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2008, 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; - -parcelable WifiInfo; diff --git a/wifi/java/android/net/wifi/WifiNetworkConnectionStatistics.aidl b/wifi/java/android/net/wifi/WifiNetworkConnectionStatistics.aidl deleted file mode 100644 index 5f497e2796d8..000000000000 --- a/wifi/java/android/net/wifi/WifiNetworkConnectionStatistics.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2014, 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; - -parcelable WifiNetworkConnectionStatistics; diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.aidl b/wifi/java/android/net/wifi/WifiNetworkSuggestion.aidl deleted file mode 100644 index eb6995f561de..000000000000 --- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2018, 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; - -parcelable WifiNetworkSuggestion; diff --git a/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.aidl b/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.aidl deleted file mode 100644 index 839af54b81ba..000000000000 --- a/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 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; - -parcelable WifiUsabilityStatsEntry; diff --git a/wifi/java/android/net/wifi/WpsInfo.aidl b/wifi/java/android/net/wifi/WpsInfo.aidl deleted file mode 100644 index f5e4ebe4f1af..000000000000 --- a/wifi/java/android/net/wifi/WpsInfo.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2011, 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; - -parcelable WpsInfo; diff --git a/wifi/java/android/net/wifi/aware/Characteristics.aidl b/wifi/java/android/net/wifi/aware/Characteristics.aidl deleted file mode 100644 index 77305e9dae0a..000000000000 --- a/wifi/java/android/net/wifi/aware/Characteristics.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2016 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.aware; - -parcelable Characteristics; diff --git a/wifi/java/android/net/wifi/aware/PublishConfig.aidl b/wifi/java/android/net/wifi/aware/PublishConfig.aidl deleted file mode 100644 index 2e6dd00b245a..000000000000 --- a/wifi/java/android/net/wifi/aware/PublishConfig.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2016 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.aware; - -parcelable PublishConfig; diff --git a/wifi/java/android/net/wifi/aware/SubscribeConfig.aidl b/wifi/java/android/net/wifi/aware/SubscribeConfig.aidl deleted file mode 100644 index bd73d5ee5ecc..000000000000 --- a/wifi/java/android/net/wifi/aware/SubscribeConfig.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2016 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.aware; - -parcelable SubscribeConfig; diff --git a/wifi/java/android/net/wifi/hotspot2/OsuProvider.aidl b/wifi/java/android/net/wifi/hotspot2/OsuProvider.aidl deleted file mode 100644 index 23d0f22e866b..000000000000 --- a/wifi/java/android/net/wifi/hotspot2/OsuProvider.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package android.net.wifi.hotspot2; - -parcelable OsuProvider; diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.aidl b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.aidl deleted file mode 100644 index 6b1cea8edb5a..000000000000 --- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2016, 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.hotspot2; - -parcelable PasspointConfiguration; diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Credential.aidl b/wifi/java/android/net/wifi/hotspot2/pps/Credential.aidl deleted file mode 100644 index 3d8e8330c2c4..000000000000 --- a/wifi/java/android/net/wifi/hotspot2/pps/Credential.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2016, 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.hotspot2.pps; - -parcelable Credential; diff --git a/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.aidl b/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.aidl deleted file mode 100644 index 6d343bde7081..000000000000 --- a/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2016, 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.hotspot2.pps; - -parcelable HomeSp; diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.aidl b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.aidl deleted file mode 100644 index ea3b2803d514..000000000000 --- a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2011, 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.p2p; - -parcelable WifiP2pConfig; diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.aidl b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.aidl deleted file mode 100644 index 8790c6ffe903..000000000000 --- a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2011, 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.p2p; - -parcelable WifiP2pDevice; diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.aidl b/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.aidl deleted file mode 100644 index 6c79009315b5..000000000000 --- a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2011, 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.p2p; - -parcelable WifiP2pDeviceList; diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.aidl b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.aidl deleted file mode 100644 index 403f2b19bfda..000000000000 --- a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2011, 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.p2p; - -parcelable WifiP2pGroup; diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pInfo.aidl b/wifi/java/android/net/wifi/p2p/WifiP2pInfo.aidl deleted file mode 100644 index a347148622ff..000000000000 --- a/wifi/java/android/net/wifi/p2p/WifiP2pInfo.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2011, 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.p2p; - -parcelable WifiP2pInfo; diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl deleted file mode 100644 index cf2cb4ae5eb4..000000000000 --- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceInfo.aidl +++ /dev/null @@ -1,19 +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.p2p.servicediscovery; - -parcelable WifiP2pServiceInfo; diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl deleted file mode 100644 index d5a1e8f505a9..000000000000 --- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.aidl +++ /dev/null @@ -1,19 +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.p2p.servicediscovery; - -parcelable WifiP2pServiceRequest; diff --git a/wifi/java/android/net/wifi/rtt/RangingRequest.aidl b/wifi/java/android/net/wifi/rtt/RangingRequest.aidl deleted file mode 100644 index 8053c9416aeb..000000000000 --- a/wifi/java/android/net/wifi/rtt/RangingRequest.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.wifi.rtt; - -parcelable RangingRequest; diff --git a/wifi/java/android/net/wifi/rtt/RangingResult.aidl b/wifi/java/android/net/wifi/rtt/RangingResult.aidl deleted file mode 100644 index ae295a610afa..000000000000 --- a/wifi/java/android/net/wifi/rtt/RangingResult.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.wifi.rtt; - -parcelable RangingResult; diff --git a/wifi/java/android/net/wifi/rtt/ResponderConfig.aidl b/wifi/java/android/net/wifi/rtt/ResponderConfig.aidl deleted file mode 100644 index fd3988aca06c..000000000000 --- a/wifi/java/android/net/wifi/rtt/ResponderConfig.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.wifi.rtt; - -parcelable ResponderConfig; -- cgit v1.2.3 From 4cbe6852f527923c7e0d6a05589ef740dde3213f Mon Sep 17 00:00:00 2001 From: David Su Date: Tue, 21 Jan 2020 13:47:10 -0800 Subject: SoftApConfig: Fix broken JavaDoc @links JavaDoc @links refer to @hide @IntDef, instead reference public constants. Bug: 140299412 Test: m doc-comment-check-docs Change-Id: If076d89167d67ce9dfebc69644947cd6ed37f11d --- wifi/java/android/net/wifi/SoftApConfiguration.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java index c02f8c3a8cd1..c8fd2434e64f 100644 --- a/wifi/java/android/net/wifi/SoftApConfiguration.java +++ b/wifi/java/android/net/wifi/SoftApConfiguration.java @@ -212,7 +212,6 @@ public final class SoftApConfiguration implements Parcelable { */ public static final int SECURITY_TYPE_OPEN = 0; - /** * The definition of security type WPA2-PSK. */ @@ -408,7 +407,11 @@ public final class SoftApConfiguration implements Parcelable { /** * Get security type params which depends on which security passphrase to set. * - * @return One of the security types from {@link SecurityType}. + * @return One of: + * {@link #SECURITY_TYPE_OPEN}, + * {@link #SECURITY_TYPE_WPA2_PSK}, + * {@link #SECURITY_TYPE_WPA3_SAE_TRANSITION}, + * {@link #SECURITY_TYPE_WPA3_SAE} */ public @SecurityType int getSecurityType() { return mSecurityType; -- cgit v1.2.3 From 592f8d52aca3736b9992528feecab10945efa110 Mon Sep 17 00:00:00 2001 From: David Su Date: Tue, 21 Jan 2020 14:15:42 -0800 Subject: Expose WifiConfig.setSecurityParams as public API Also expose associated SECURITY_TYPE_* constants. Bug: 143614759 Test: compiles Change-Id: I39419052791942ed86d3156a5cba1e0e2003098a --- wifi/java/android/net/wifi/WifiConfiguration.java | 41 ++++++++++++++--------- 1 file changed, 25 insertions(+), 16 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index e84369fb7ba1..e2befeb29004 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -402,29 +402,29 @@ public class WifiConfiguration implements Parcelable { public static final String[] strings = { "current", "disabled", "enabled" }; } - /** - * Security types we support. - */ - /** @hide */ + /** Security type for an open network. */ public static final int SECURITY_TYPE_OPEN = 0; - /** @hide */ + /** Security type for a WEP network. */ public static final int SECURITY_TYPE_WEP = 1; - /** @hide */ + /** Security type for a PSK network. */ public static final int SECURITY_TYPE_PSK = 2; - /** @hide */ + /** Security type for an EAP network. */ public static final int SECURITY_TYPE_EAP = 3; - /** @hide */ + /** Security type for an SAE network. */ public static final int SECURITY_TYPE_SAE = 4; - /** @hide */ + /** Security type for an EAP Suite B network. */ public static final int SECURITY_TYPE_EAP_SUITE_B = 5; - /** @hide */ + /** Security type for an OWE network. */ public static final int SECURITY_TYPE_OWE = 6; - /** @hide */ + /** Security type for a WAPI PSK network. */ public static final int SECURITY_TYPE_WAPI_PSK = 7; - /** @hide */ + /** Security type for a WAPI Certificate network. */ public static final int SECURITY_TYPE_WAPI_CERT = 8; - /** @hide */ + /** + * Security types we support. + * @hide + */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "SECURITY_TYPE_" }, value = { SECURITY_TYPE_OPEN, @@ -440,10 +440,19 @@ public class WifiConfiguration implements Parcelable { public @interface SecurityType {} /** - * @hide - * Set security params (sets the various bitsets exposed in WifiConfiguration). + * Set the various security params to correspond to the provided security type. + * This is accomplished by setting the various BitSets exposed in WifiConfiguration. * - * @param securityType One of the security types from {@link SecurityType}. + * @param securityType One of the following security types: + * {@link #SECURITY_TYPE_OPEN}, + * {@link #SECURITY_TYPE_WEP}, + * {@link #SECURITY_TYPE_PSK}, + * {@link #SECURITY_TYPE_EAP}, + * {@link #SECURITY_TYPE_SAE}, + * {@link #SECURITY_TYPE_EAP_SUITE_B}, + * {@link #SECURITY_TYPE_OWE}, + * {@link #SECURITY_TYPE_WAPI_PSK}, or + * {@link #SECURITY_TYPE_WAPI_CERT} */ public void setSecurityParams(@SecurityType int securityType) { // Clear all the bitsets. -- cgit v1.2.3 From 13132500eba8af971d7b19046b2a63b90f51ac8e Mon Sep 17 00:00:00 2001 From: David Su Date: Tue, 21 Jan 2020 15:15:41 -0800 Subject: Wifi Builders: multiple calls to build() should return different instances Previous build() implementation simply returns the object wrapped inside the builder. The expected behavior should be to return a new instance every time build() is called. Bug: 148098082 Test: atest FrameworksWifiApiTests Change-Id: If4c1cf45be155f32bea399ad0e3ec52b28f645a7 --- wifi/java/android/net/wifi/WifiConfiguration.java | 4 +- wifi/java/android/net/wifi/WifiInfo.java | 2 +- .../android/net/wifi/WifiConfigurationTest.java | 40 ++++++++++++++++++ wifi/tests/src/android/net/wifi/WifiInfoTest.java | 47 ++++++++++++++++++++++ 4 files changed, 91 insertions(+), 2 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index e2befeb29004..114e0fa21296 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -1662,7 +1662,9 @@ public class WifiConfiguration implements Parcelable { */ @NonNull public NetworkSelectionStatus build() { - return mNetworkSelectionStatus; + NetworkSelectionStatus status = new NetworkSelectionStatus(); + status.copy(mNetworkSelectionStatus); + return status; } } diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java index f2a875b43538..419bcb107013 100644 --- a/wifi/java/android/net/wifi/WifiInfo.java +++ b/wifi/java/android/net/wifi/WifiInfo.java @@ -435,7 +435,7 @@ public class WifiInfo implements Parcelable { */ @NonNull public WifiInfo build() { - return mWifiInfo; + return new WifiInfo(mWifiInfo); } } diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java index 0ef75aa3eb5a..8023160a811e 100644 --- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java @@ -24,6 +24,7 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertTrue; import android.net.MacAddress; @@ -386,4 +387,43 @@ public class WifiConfigurationTest { .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256)); assertTrue(config.requirePMF); } + + /** + * Test that the NetworkSelectionStatus Builder returns the same values that was set, and that + * calling build multiple times returns different instances. + */ + @Test + public void testNetworkSelectionStatusBuilder() throws Exception { + NetworkSelectionStatus.Builder builder = new NetworkSelectionStatus.Builder() + .setNetworkSelectionDisableReason( + NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION) + .setNetworkSelectionStatus( + NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED); + + NetworkSelectionStatus status1 = builder.build(); + + assertEquals(NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION, + status1.getNetworkSelectionDisableReason()); + assertEquals(NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED, + status1.getNetworkSelectionStatus()); + + NetworkSelectionStatus status2 = builder + .setNetworkSelectionDisableReason(NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD) + .build(); + + // different instances + assertNotSame(status1, status2); + + // assert that status1 didn't change + assertEquals(NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION, + status1.getNetworkSelectionDisableReason()); + assertEquals(NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED, + status1.getNetworkSelectionStatus()); + + // assert that status2 changed + assertEquals(NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD, + status2.getNetworkSelectionDisableReason()); + assertEquals(NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED, + status2.getNetworkSelectionStatus()); + } } diff --git a/wifi/tests/src/android/net/wifi/WifiInfoTest.java b/wifi/tests/src/android/net/wifi/WifiInfoTest.java index af85ce05f23b..04759ac21bba 100644 --- a/wifi/tests/src/android/net/wifi/WifiInfoTest.java +++ b/wifi/tests/src/android/net/wifi/WifiInfoTest.java @@ -18,6 +18,7 @@ package android.net.wifi; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertTrue; import android.os.Parcel; @@ -26,6 +27,8 @@ import androidx.test.filters.SmallTest; import org.junit.Test; +import java.nio.charset.StandardCharsets; + /** * Unit tests for {@link android.net.wifi.WifiInfo}. */ @@ -41,6 +44,11 @@ public class WifiInfoTest { private static final int TEST_WIFI_STANDARD = ScanResult.WIFI_STANDARD_11AC; private static final int TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS = 866; private static final int TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS = 1200; + private static final String TEST_SSID = "Test123"; + private static final String TEST_BSSID = "12:12:12:12:12:12"; + private static final int TEST_RSSI = -60; + private static final int TEST_NETWORK_ID = 5; + private static final int TEST_NETWORK_ID2 = 6; /** * Verify parcel write/read with WifiInfo. @@ -101,4 +109,43 @@ public class WifiInfoTest { assertEquals(null, wifiInfo.getBSSID()); assertEquals(-1, wifiInfo.getNetworkId()); } + + /** + * Test that the WifiInfo Builder returns the same values that was set, and that + * calling build multiple times returns different instances. + */ + @Test + public void testWifiInfoBuilder() throws Exception { + WifiInfo.Builder builder = new WifiInfo.Builder() + .setSsid(TEST_SSID.getBytes(StandardCharsets.UTF_8)) + .setBssid(TEST_BSSID) + .setRssi(TEST_RSSI) + .setNetworkId(TEST_NETWORK_ID); + + WifiInfo info1 = builder.build(); + + assertEquals("\"" + TEST_SSID + "\"", info1.getSSID()); + assertEquals(TEST_BSSID, info1.getBSSID()); + assertEquals(TEST_RSSI, info1.getRssi()); + assertEquals(TEST_NETWORK_ID, info1.getNetworkId()); + + WifiInfo info2 = builder + .setNetworkId(TEST_NETWORK_ID2) + .build(); + + // different instances + assertNotSame(info1, info2); + + // assert that info1 didn't change + assertEquals("\"" + TEST_SSID + "\"", info1.getSSID()); + assertEquals(TEST_BSSID, info1.getBSSID()); + assertEquals(TEST_RSSI, info1.getRssi()); + assertEquals(TEST_NETWORK_ID, info1.getNetworkId()); + + // assert that info2 changed + assertEquals("\"" + TEST_SSID + "\"", info2.getSSID()); + assertEquals(TEST_BSSID, info2.getBSSID()); + assertEquals(TEST_RSSI, info2.getRssi()); + assertEquals(TEST_NETWORK_ID2, info2.getNetworkId()); + } } -- cgit v1.2.3 From a6f0c866c7e0c908f1637e28516d8c327692a338 Mon Sep 17 00:00:00 2001 From: David Su Date: Tue, 21 Jan 2020 16:45:50 -0800 Subject: framework-wifi: Move java_api_finder plugin to build rule with srcs java_api_finder doesn't work if it is added to a build rule without any `srcs`. Bug: 147193292 Test: compiles Change-Id: I26a1da2d41cbe661588f721bf23dac3d26bc38e9 --- wifi/Android.bp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 099cbff15fb4..a6c08b570f17 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -76,6 +76,8 @@ java_library { srcs: [ ":framework-wifi-updatable-sources", ], + // java_api_finder must accompany `srcs` + plugins: ["java_api_finder"], installable: false, visibility: [ "//frameworks/opt/net/wifi/service", @@ -113,7 +115,6 @@ java_library { "com.android.wifi", "test_com.android.wifi", ], - plugins: ["java_api_finder"], } droidstubs { -- cgit v1.2.3 From 81ba3e35489bda3accb28ccdf2fb6baaa2db5680 Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Tue, 21 Jan 2020 11:37:40 -0800 Subject: Updated ResponderLocation.toCivicLocationSparseArray() to return SparseArray Bug: 147924426 Test: atest android.net.wifi.rtt.ResponderLocationTest#testLcrTestCivicLocationSparseArray: PASSED (0ms) Change-Id: Icbcf0c926646ef522ede846db93df85592bec631 --- .../android/net/wifi/rtt/ResponderLocation.java | 4 +++- .../net/wifi/rtt/ResponderLocationTest.java | 25 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/rtt/ResponderLocation.java b/wifi/java/android/net/wifi/rtt/ResponderLocation.java index 970a75d7c418..218b2dcae71d 100644 --- a/wifi/java/android/net/wifi/rtt/ResponderLocation.java +++ b/wifi/java/android/net/wifi/rtt/ResponderLocation.java @@ -21,6 +21,7 @@ import static java.lang.annotation.RetentionPolicy.SOURCE; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.location.Address; import android.location.Location; @@ -1367,7 +1368,8 @@ public final class ResponderLocation implements Parcelable { * */ @Nullable - public SparseArray toCivicLocationSparseArray() { + @SuppressLint("ChangedType") + public SparseArray toCivicLocationSparseArray() { if (mCivicLocation != null && mCivicLocation.isValid()) { return mCivicLocation.toSparseArray(); } else { diff --git a/wifi/tests/src/android/net/wifi/rtt/ResponderLocationTest.java b/wifi/tests/src/android/net/wifi/rtt/ResponderLocationTest.java index b02eebbe9a01..271339cecf1e 100644 --- a/wifi/tests/src/android/net/wifi/rtt/ResponderLocationTest.java +++ b/wifi/tests/src/android/net/wifi/rtt/ResponderLocationTest.java @@ -20,6 +20,7 @@ import android.location.Address; import android.location.Location; import android.net.MacAddress; import android.os.Parcel; +import android.util.SparseArray; import android.webkit.MimeTypeMap; import static junit.framework.Assert.assertEquals; @@ -504,6 +505,30 @@ public class ResponderLocationTest { assertEquals("US", address.getAddressLine(4)); } + /** + * Test that a Civic Location sparseArray can be extracted from a valid lcr buffer. + */ + @Test + public void testLcrTestCivicLocationSparseArray() { + byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE); + byte[] testLcrBuffer = + concatenateArrays(sTestLcrBufferHeader, sTestCivicLocationSEWithAddress); + ResponderLocation responderLocation = new ResponderLocation(testLciBuffer, testLcrBuffer); + + boolean valid = responderLocation.isValid(); + SparseArray civicLocationSparseArray = responderLocation + .toCivicLocationSparseArray(); + + assertTrue(valid); + assertEquals("15", civicLocationSparseArray.get(CivicLocationKeys.HNO)); + assertEquals("Alto", + civicLocationSparseArray.get(CivicLocationKeys.PRIMARY_ROAD_NAME)); + assertEquals("Road", + civicLocationSparseArray.get(CivicLocationKeys.STREET_NAME_POST_MODIFIER)); + assertEquals("Mtn View", civicLocationSparseArray.get(CivicLocationKeys.CITY)); + assertEquals("94043", civicLocationSparseArray.get(CivicLocationKeys.POSTAL_CODE)); + } + /** * Test that a URL can be extracted from a valid lcr buffer with a map image subelement. */ -- cgit v1.2.3 From 315bb8accb65672c6478079e5af3bd60afb07027 Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Fri, 17 Jan 2020 17:09:12 -0800 Subject: Add getMatchingScanResults API to get filtered ScanResults for specified Susgested network configurations. Bug: 146669408 Test: atest android.net.wifi Change-Id: I83caebadcc735db2809f58923ede3331d0ab30b2 --- wifi/java/android/net/wifi/IWifiManager.aidl | 5 ++++ wifi/java/android/net/wifi/WifiManager.java | 28 ++++++++++++++++++++++ .../com/android/server/wifi/BaseWifiService.java | 8 +++++++ 3 files changed, 41 insertions(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 0b5969a8999d..d13a625963b6 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -260,4 +260,9 @@ interface IWifiManager boolean setWifiConnectedNetworkScorer(in IBinder binder, in IWifiConnectedNetworkScorer scorer); void clearWifiConnectedNetworkScorer(); + + /** + * Return the Map of {@link WifiNetworkSuggestion} and the list of + */ + Map getMatchingScanResults(in List networkSuggestions, in List scanResults, String callingPackage, String callingFeatureId); } diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 208ce9c37b23..f6e3ff0ff02c 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -2684,6 +2684,34 @@ public class WifiManager { } } + /** + * Return the filtered ScanResults which may be authenticated by the suggested network + * configurations. + * @param networkSuggestions The list of {@link WifiNetworkSuggestion} + * @param scanResults The scan results to be filtered, this is optional, if it is null or + * empty, wifi system would use the recent scan results in the system. + * @return The map of {@link WifiNetworkSuggestion} and the list of {@link ScanResult} which + * may be authenticated by the corresponding network configuration. + * @hide + */ + @SystemApi + @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE}) + @NonNull + public Map> getMatchingScanResults( + @NonNull List networkSuggestions, + @Nullable List scanResults) { + if (networkSuggestions == null) { + throw new IllegalArgumentException("networkSuggestions must not be null."); + } + try { + return mService.getMatchingScanResults( + networkSuggestions, scanResults, + mContext.getOpPackageName(), mContext.getFeatureId()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Check if scanning is always available. * diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index 56fa6e23a852..19d09d1f2a9c 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -617,4 +617,12 @@ public class BaseWifiService extends IWifiManager.Stub { public void clearWifiConnectedNetworkScorer() { throw new UnsupportedOperationException(); } + + @Override + public Map> getMatchingScanResults( + List networkSuggestions, + List scanResults, + String callingPackage, String callingFeatureId) { + throw new UnsupportedOperationException(); + } } -- cgit v1.2.3 From ac676efc527315efd5f868ec383abb75f911b86b Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Wed, 22 Jan 2020 09:57:41 -0800 Subject: WifiManager: Expose enableWifiConnectivityManager Rename enableWifiConnectivityManager to allowAutoJoin and expose it as a @SystemApi for OEM's to dynamically toggle on/off auto join status. Bug: 141889280 Test: Compiles Change-Id: I0dc5141cd2f751ddf199ce9b2b2ecce564f1b475 --- wifi/java/android/net/wifi/IWifiManager.aidl | 4 +-- wifi/java/android/net/wifi/WifiManager.java | 29 +++++++++++++--------- .../com/android/server/wifi/BaseWifiService.java | 8 +++++- 3 files changed, 26 insertions(+), 15 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 0b5969a8999d..71aac910148e 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -88,6 +88,8 @@ interface IWifiManager boolean disableNetwork(int netId, String packageName); + void allowAutojoinGlobal(boolean choice); + void allowAutojoin(int netId, boolean choice); void allowAutojoinPasspoint(String fqdn, boolean enableAutoJoin); @@ -179,8 +181,6 @@ interface IWifiManager int getVerboseLoggingLevel(); - void enableWifiConnectivityManager(boolean enabled); - void disableEphemeralNetwork(String SSID, String packageName); void factoryReset(String packageName); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 208ce9c37b23..51b7632c59b3 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -4270,6 +4270,23 @@ public class WifiManager { } } + /** + * Allows the OEM to enable/disable auto-join globally. + * + * @param choice true to allow autojoin, false to disallow autojoin + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) + public void allowAutojoinGlobal(boolean choice) { + try { + mService.allowAutojoinGlobal(choice); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Sets the user choice for allowing auto-join to a network. * The updated choice will be made available through the updated config supplied by the @@ -4896,18 +4913,6 @@ public class WifiManager { return false; } - /** - * Enable/disable WifiConnectivityManager - * @hide - */ - public void enableWifiConnectivityManager(boolean enabled) { - try { - mService.enableWifiConnectivityManager(enabled); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - /** * Returns a byte stream representing the data that needs to be backed up to save the * current Wifi state. diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index 56fa6e23a852..849a14d5c5db 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -177,6 +177,11 @@ public class BaseWifiService extends IWifiManager.Stub { throw new UnsupportedOperationException(); } + @Override + public void allowAutojoinGlobal(boolean choice) { + throw new UnsupportedOperationException(); + } + @Override public void allowAutojoin(int netId, boolean choice) { throw new UnsupportedOperationException(); @@ -404,7 +409,8 @@ public class BaseWifiService extends IWifiManager.Stub { throw new UnsupportedOperationException(); } - @Override + /** @deprecated use {@link #allowAutojoinGlobal(boolean)} instead */ + @Deprecated public void enableWifiConnectivityManager(boolean enabled) { throw new UnsupportedOperationException(); } -- cgit v1.2.3 From 670e562a131d386f9e20be93dfcb1e7994c05d54 Mon Sep 17 00:00:00 2001 From: David Su Date: Wed, 22 Jan 2020 12:46:38 -0800 Subject: Add @IntDef to WifiP2pConfig#getGroupOwnerBand() Bug: 147668001 Test: compiles Change-Id: I6aeb8a29d9e9fddfb2d909fc6fe92fef2276eb48 --- wifi/java/android/net/wifi/p2p/WifiP2pConfig.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java index 8fa9c3d6f1a6..9562f95ac162 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java @@ -66,12 +66,20 @@ public class WifiP2pConfig implements Parcelable { /** @hide */ public String passphrase = ""; - /** Get the required band for the group owner. */ + /** + * Get the required band for the group owner. + * The result will be one of the following: + * {@link #GROUP_OWNER_BAND_AUTO}, + * {@link #GROUP_OWNER_BAND_2GHZ}, + * {@link #GROUP_OWNER_BAND_5GHZ} + */ + @GroupOperatingBandType public int getGroupOwnerBand() { return groupOwnerBand; } /** @hide */ + @GroupOperatingBandType public int groupOwnerBand = GROUP_OWNER_BAND_AUTO; /** @hide */ -- cgit v1.2.3 From 85f2342ed85a4e1a8f0934e72718ceae076eb6ae Mon Sep 17 00:00:00 2001 From: Quang Luong Date: Tue, 21 Jan 2020 17:09:02 -0800 Subject: Allow set metered override setting for passpoint Add API to set the metered override setting (METERED_OVERRIDE_NONE, METERED_OVERRIDE_METERED, METERED_OVERRIDE_UNMETERED) per passpoint profile. Bug: 131273033 Test: atest android.net.wifi Change-Id: I5eb2640b8fcf61031714c0a819c0cf1ed793416d --- wifi/java/android/net/wifi/IWifiManager.aidl | 2 + wifi/java/android/net/wifi/WifiManager.java | 19 +++++++++ .../net/wifi/hotspot2/PasspointConfiguration.java | 45 +++++++++++++++++++++- .../com/android/server/wifi/BaseWifiService.java | 5 +++ .../src/android/net/wifi/WifiManagerTest.java | 11 ++++++ .../wifi/hotspot2/PasspointConfigurationTest.java | 3 ++ 6 files changed, 84 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 0b5969a8999d..9ad11aad04f1 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -94,6 +94,8 @@ interface IWifiManager void setMacRandomizationSettingPasspointEnabled(String fqdn, boolean enable); + void setMeteredOverridePasspoint(String fqdn, int meteredOverride); + boolean startScan(String packageName, String featureId); List getScanResults(String callingPackage, String callingFeatureId); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index c35303da9056..a27438779447 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -4316,6 +4316,25 @@ public class WifiManager { } } + /** + * Sets the user's choice of metered override for a Passpoint profile. + * + * @param fqdn the FQDN (fully qualified domain name) of the passpoint profile. + * @param meteredOverride One of three values: {@link WifiConfiguration#METERED_OVERRIDE_NONE}, + * {@link WifiConfiguration#METERED_OVERRIDE_METERED}, + * {@link WifiConfiguration#METERED_OVERRIDE_NOT_METERED} + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) + public void setMeteredOverridePasspoint(@NonNull String fqdn, int meteredOverride) { + try { + mService.setMeteredOverridePasspoint(fqdn, meteredOverride); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Disable an ephemeral network. * diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java index 7c335fc323f5..3a0d080594c8 100644 --- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java +++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java @@ -16,6 +16,9 @@ package android.net.wifi.hotspot2; +import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_NONE; +import static android.net.wifi.WifiConfiguration.MeteredOverride; + import android.annotation.Nullable; import android.annotation.SystemApi; import android.net.wifi.hotspot2.pps.Credential; @@ -437,6 +440,18 @@ public final class PasspointConfiguration implements Parcelable { */ private boolean mIsMacRandomizationEnabled = true; + /** + * Indicates if the end user has expressed an explicit opinion about the + * meteredness of this network, such as through the Settings app. + * This value is one of {@link #METERED_OVERRIDE_NONE}, {@link #METERED_OVERRIDE_METERED}, + * or {@link #METERED_OVERRIDE_NOT_METERED}. + *

    + * This should always override any values from {@link WifiInfo#getMeteredHint()}. + * + * By default this field is set to {@link #METERED_OVERRIDE_NONE}. + */ + private int mMeteredOverride = METERED_OVERRIDE_NONE; + /** * Configures the auto-association status of this Passpoint configuration. A value of true * indicates that the configuration will be considered for auto-connection, a value of false @@ -462,6 +477,16 @@ public final class PasspointConfiguration implements Parcelable { mIsMacRandomizationEnabled = enabled; } + /** + * Sets the metered override setting for this Passpoint configuration. + * + * @param meteredOverride One of the values in {@link MeteredOverride} + * @hide + */ + public void setMeteredOverride(@MeteredOverride int meteredOverride) { + mMeteredOverride = meteredOverride; + } + /** * Indicates whether the Passpoint configuration may be auto-connected to by the framework. A * value of true indicates that auto-connection can happen, a value of false indicates that it @@ -477,6 +502,18 @@ public final class PasspointConfiguration implements Parcelable { return mIsAutoJoinEnabled; } + /** + * Indicates whether the user chose this configuration to be treated as metered or not. + * + * @return One of the values in {@link MeteredOverride} + * @hide + */ + @SystemApi + @MeteredOverride + public int getMeteredOverride() { + return mMeteredOverride; + } + /** * Indicates whether a randomized MAC address or device MAC address will be used for * connections to this Passpoint network. If true, a randomized MAC address will be used. @@ -534,6 +571,7 @@ public final class PasspointConfiguration implements Parcelable { mCarrierId = source.mCarrierId; mIsAutoJoinEnabled = source.mIsAutoJoinEnabled; mIsMacRandomizationEnabled = source.mIsMacRandomizationEnabled; + mMeteredOverride = source.mMeteredOverride; } @Override @@ -565,6 +603,7 @@ public final class PasspointConfiguration implements Parcelable { dest.writeInt(mCarrierId); dest.writeBoolean(mIsAutoJoinEnabled); dest.writeBoolean(mIsMacRandomizationEnabled); + dest.writeInt(mMeteredOverride); } @Override @@ -597,6 +636,7 @@ public final class PasspointConfiguration implements Parcelable { && mCarrierId == that.mCarrierId && mIsAutoJoinEnabled == that.mIsAutoJoinEnabled && mIsMacRandomizationEnabled == that.mIsMacRandomizationEnabled + && mMeteredOverride == that.mMeteredOverride && (mServiceFriendlyNames == null ? that.mServiceFriendlyNames == null : mServiceFriendlyNames.equals(that.mServiceFriendlyNames)); } @@ -607,7 +647,8 @@ public final class PasspointConfiguration implements Parcelable { mUpdateIdentifier, mCredentialPriority, mSubscriptionCreationTimeInMillis, mSubscriptionExpirationTimeInMillis, mUsageLimitUsageTimePeriodInMinutes, mUsageLimitStartTimeInMillis, mUsageLimitDataLimit, mUsageLimitTimeLimitInMinutes, - mServiceFriendlyNames, mCarrierId, mIsAutoJoinEnabled, mIsMacRandomizationEnabled); + mServiceFriendlyNames, mCarrierId, mIsAutoJoinEnabled, mIsMacRandomizationEnabled, + mMeteredOverride); } @Override @@ -663,6 +704,7 @@ public final class PasspointConfiguration implements Parcelable { builder.append("CarrierId:" + mCarrierId); builder.append("IsAutoJoinEnabled:" + mIsAutoJoinEnabled); builder.append("mIsMacRandomizationEnabled:" + mIsMacRandomizationEnabled); + builder.append("mMeteredOverride:" + mMeteredOverride); return builder.toString(); } @@ -770,6 +812,7 @@ public final class PasspointConfiguration implements Parcelable { config.mCarrierId = in.readInt(); config.mIsAutoJoinEnabled = in.readBoolean(); config.mIsMacRandomizationEnabled = in.readBoolean(); + config.mMeteredOverride = in.readInt(); return config; } diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index 56fa6e23a852..c6ba6a802307 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -192,6 +192,11 @@ public class BaseWifiService extends IWifiManager.Stub { throw new UnsupportedOperationException(); } + @Override + public void setMeteredOverridePasspoint(String fqdn, int meteredOverride) { + throw new UnsupportedOperationException(); + } + @Override public boolean startScan(String packageName, String featureId) { throw new UnsupportedOperationException(); diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index f369203e05ab..fa3ed006c11e 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -16,6 +16,7 @@ package android.net.wifi; +import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_METERED; import static android.net.wifi.WifiManager.ActionListener; import static android.net.wifi.WifiManager.BUSY; import static android.net.wifi.WifiManager.ERROR; @@ -1808,6 +1809,16 @@ public class WifiManagerTest { verify(mWifiService).setMacRandomizationSettingPasspointEnabled(fqdn, true); } + /** + * Test behavior of + * {@link WifiManager#setMacRandomizationSettingPasspointEnabled(String, boolean)} + */ + @Test + public void testSetMeteredOverridePasspoint() throws Exception { + final String fqdn = "FullyQualifiedDomainName"; + mWifiManager.setMeteredOverridePasspoint(fqdn, METERED_OVERRIDE_METERED); + verify(mWifiService).setMeteredOverridePasspoint(fqdn, METERED_OVERRIDE_METERED); + } /** * Test behavior of {@link WifiManager#disconnect()} diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java index 603e78b90ff2..654154d77b0d 100644 --- a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java @@ -16,6 +16,8 @@ package android.net.wifi.hotspot2; +import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_NONE; + import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -173,6 +175,7 @@ public class PasspointConfigurationTest { assertFalse(config.validateForR2()); assertTrue(config.isAutoJoinEnabled()); assertTrue(config.isMacRandomizationEnabled()); + assertTrue(config.getMeteredOverride() == METERED_OVERRIDE_NONE); } /** -- cgit v1.2.3 From a218fc4c71eeda7a5409de938766ddf009138650 Mon Sep 17 00:00:00 2001 From: Vamsi Krishna Date: Fri, 23 Feb 2018 16:59:40 +0530 Subject: Wifi: Add support for connecting to FILS APs Add required fields to configure STA to connect to BSSes which have FILS_SHA256 and/or FILS_SHA384 key managements enabled. Bug: 143259898 Test: atest. Test: Basic wifi sanity. Change-Id: I59f0b8000d39298d8a853bdd08c66d7e46bfa70f --- wifi/java/android/net/wifi/ScanResult.java | 10 ++++++++++ wifi/java/android/net/wifi/WifiConfiguration.java | 17 +++++++++++++++-- wifi/java/android/net/wifi/WifiEnterpriseConfig.java | 5 ++++- wifi/java/android/net/wifi/WifiManager.java | 6 ++++++ 4 files changed, 35 insertions(+), 3 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java index 3fda6cda92f5..51927af17888 100644 --- a/wifi/java/android/net/wifi/ScanResult.java +++ b/wifi/java/android/net/wifi/ScanResult.java @@ -209,6 +209,16 @@ public class ScanResult implements Parcelable { @SystemApi public static final int KEY_MGMT_WAPI_CERT = 14; + /** + * @hide + * Security key management scheme: FILS_SHA256. + */ + public static final int KEY_MGMT_FILS_SHA256 = 15; + /** + * @hide + * Security key management scheme: FILS_SHA384. + */ + public static final int KEY_MGMT_FILS_SHA384 = 16; /** * @hide * No cipher suite. diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 114e0fa21296..80fefe6df72d 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -123,7 +123,9 @@ public class WifiConfiguration implements Parcelable { WPA_PSK_SHA256, WPA_EAP_SHA256, WAPI_PSK, - WAPI_CERT}) + WAPI_CERT, + FILS_SHA256, + FILS_SHA384}) public @interface KeyMgmtScheme {} /** WPA is not used; plaintext or static WEP could be used. */ @@ -204,12 +206,23 @@ public class WifiConfiguration implements Parcelable { @SystemApi public static final int WAPI_CERT = 14; + /** + * IEEE 802.11ai FILS SK with SHA256 + * @hide + */ + public static final int FILS_SHA256 = 15; + /** + * IEEE 802.11ai FILS SK with SHA384: + * @hide + */ + public static final int FILS_SHA384 = 16; + public static final String varName = "key_mgmt"; public static final String[] strings = { "NONE", "WPA_PSK", "WPA_EAP", "IEEE8021X", "WPA2_PSK", "OSEN", "FT_PSK", "FT_EAP", "SAE", "OWE", "SUITE_B_192", "WPA_PSK_SHA256", "WPA_EAP_SHA256", - "WAPI_PSK", "WAPI_CERT" }; + "WAPI_PSK", "WAPI_CERT", "FILS_SHA256", "FILS_SHA384" }; } /** diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java index 5edcc2df3804..558d5fa60e99 100644 --- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java +++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java @@ -91,6 +91,8 @@ public class WifiEnterpriseConfig implements Parcelable { public static final String DOM_SUFFIX_MATCH_KEY = "domain_suffix_match"; /** @hide */ public static final String OPP_KEY_CACHING = "proactive_key_caching"; + /** @hide */ + public static final String EAP_ERP = "eap_erp"; /** * String representing the keystore OpenSSL ENGINE's ID. @@ -228,7 +230,8 @@ public class WifiEnterpriseConfig implements Parcelable { /** * Fields that have unquoted values in {@link #mFields}. */ - private static final List UNQUOTED_KEYS = Arrays.asList(ENGINE_KEY, OPP_KEY_CACHING); + private static final List UNQUOTED_KEYS = Arrays.asList(ENGINE_KEY, OPP_KEY_CACHING, + EAP_ERP); @UnsupportedAppUsage private HashMap mFields = new HashMap(); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index f6e3ff0ff02c..d9c7b461af6d 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -2341,6 +2341,12 @@ public class WifiManager { /** @hide */ public static final long WIFI_FEATURE_WAPI = 0x2000000000L; // WAPI + /** @hide */ + public static final long WIFI_FEATURE_FILS_SHA256 = 0x4000000000L; // FILS-SHA256 + + /** @hide */ + public static final long WIFI_FEATURE_FILS_SHA384 = 0x8000000000L; // FILS-SHA384 + private long getSupportedFeatures() { try { return mService.getSupportedFeatures(); -- cgit v1.2.3 From e0c64998e4b0ad07029a54093c7881a005f9aadf Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 23 Jan 2020 01:11:48 +0000 Subject: Revert "Fully qualify android.net.wifi.ScanResult" This reverts commit 32f3943b8d812319b936e7acb6cd95616ea0b4fc. Reason for revert: Underlying bug in the AIDL compiler has been fixed. Reverting this workaround. Bug: 147918827 Change-Id: Ide138668040da7517c9099ef9c5d17a75dc16524 Test: m ANDROID_BUILDSPEC=vendor/google/build/app_build_spec.mk --- wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl | 3 ++- wifi/java/android/net/wifi/IWifiManager.aidl | 9 +++++---- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl b/wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl index 51d74f0fcfa9..d14ec57ea07a 100644 --- a/wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl +++ b/wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl @@ -17,6 +17,7 @@ package android.net.wifi; import android.net.wifi.INetworkRequestUserSelectionCallback; +import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; /** @@ -30,7 +31,7 @@ oneway interface INetworkRequestMatchCallback void onAbort(); - void onMatch(in List scanResults); + void onMatch(in List scanResults); void onUserSelectionConnectSuccess(in WifiConfiguration wificonfiguration); diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 54091a6f4a67..5a98ac86e783 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -36,6 +36,7 @@ import android.net.wifi.ISuggestionConnectionStatusListener; import android.net.wifi.ITrafficStateCallback; import android.net.wifi.ITxPacketCountListener; import android.net.wifi.IWifiConnectedNetworkScorer; +import android.net.wifi.ScanResult; import android.net.wifi.SoftApConfiguration; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; @@ -60,9 +61,9 @@ interface IWifiManager ParceledListSlice getPrivilegedConfiguredNetworks(String packageName, String featureId); - Map getAllMatchingFqdnsForScanResults(in List scanResult); + Map getAllMatchingFqdnsForScanResults(in List scanResult); - Map getMatchingOsuProviders(in List scanResult); + Map getMatchingOsuProviders(in List scanResult); Map getMatchingPasspointConfigsForOsuProviders(in List osuProviders); @@ -96,7 +97,7 @@ interface IWifiManager boolean startScan(String packageName, String featureId); - List getScanResults(String callingPackage, String callingFeatureId); + List getScanResults(String callingPackage, String callingFeatureId); boolean disconnect(String packageName); @@ -253,7 +254,7 @@ interface IWifiManager int calculateSignalLevel(int rssi); - List getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(in List scanResults); + List getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(in List scanResults); boolean setWifiConnectedNetworkScorer(in IBinder binder, in IWifiConnectedNetworkScorer scorer); -- cgit v1.2.3 From 0f9e4b6c3c6cc6a9c469b157ac3728163199c6e3 Mon Sep 17 00:00:00 2001 From: David Su Date: Wed, 22 Jan 2020 18:40:56 -0800 Subject: WifiEnterpriseConfig: Mark as getters/setters @NonNull Bug: 147321173 Test: compiles Change-Id: I9f96348cc8ee0daa550e20604bc7484ee714ff0e --- wifi/java/android/net/wifi/WifiEnterpriseConfig.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java index 5edcc2df3804..04016b606b96 100644 --- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java +++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java @@ -856,11 +856,11 @@ public class WifiEnterpriseConfig implements Parcelable { * like /etc/ssl/certs. If configured, these certificates are added to the * list of trusted CAs. ca_cert may also be included in that case, but it is * not required. - * @param path The path for CA certificate files, or null/empty string to clear. + * @param path The path for CA certificate files, or empty string to clear. * @hide */ @SystemApi - public void setCaPath(@Nullable String path) { + public void setCaPath(@NonNull String path) { setFieldValue(CA_PATH_KEY, path); } @@ -881,11 +881,11 @@ public class WifiEnterpriseConfig implements Parcelable { *

    See the {@link android.security.KeyChain} for details on installing or choosing * a certificate *

    - * @param alias identifies the certificate, or null/empty string to clear. + * @param alias identifies the certificate, or empty string to clear. * @hide */ @SystemApi - public void setClientCertificateAlias(@Nullable String alias) { + public void setClientCertificateAlias(@NonNull String alias) { setFieldValue(CLIENT_CERT_KEY, alias, CLIENT_CERT_PREFIX); setFieldValue(PRIVATE_KEY_ID_KEY, alias, USER_PRIVATE_KEY); // Also, set engine parameters @@ -1360,11 +1360,11 @@ public class WifiEnterpriseConfig implements Parcelable { * If this field is not specified, WAPI-CERT uses ASU ID from WAI packet * as the certificate suite name automatically. * - * @param wapiCertSuite The name for WAPI certificate suite, or null/empty string to clear. + * @param wapiCertSuite The name for WAPI certificate suite, or empty string to clear. * @hide */ @SystemApi - public void setWapiCertSuite(@Nullable String wapiCertSuite) { + public void setWapiCertSuite(@NonNull String wapiCertSuite) { setFieldValue(WAPI_CERT_SUITE_KEY, wapiCertSuite); } @@ -1373,7 +1373,7 @@ public class WifiEnterpriseConfig implements Parcelable { * @return the certificate suite name * @hide */ - @Nullable + @NonNull @SystemApi public String getWapiCertSuite() { return getFieldValue(WAPI_CERT_SUITE_KEY); -- cgit v1.2.3 From a4048219e261c22048de3ded6b81a8af5e27ced9 Mon Sep 17 00:00:00 2001 From: David Su Date: Wed, 22 Jan 2020 16:38:16 -0800 Subject: WifiManager.calculateSignalLevel(): add @IntRange Add @IntRange annotation for calculateSignalLevel, getMaxSignalLevel. Bug: 145746482 Test: compiles Change-Id: I3e61fdd13f0dd0519f969afeb4ebd3eeed823643 --- wifi/java/android/net/wifi/WifiManager.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index c35303da9056..2381d46c14cc 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -22,6 +22,7 @@ import static android.Manifest.permission.READ_WIFI_CREDENTIAL; import android.annotation.CallbackExecutor; import android.annotation.IntDef; +import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; @@ -2345,7 +2346,7 @@ public class WifiManager { return (getSupportedFeatures() & feature) == feature; } - /** + /** * @return true if this adapter supports Passpoint * @hide */ @@ -2869,6 +2870,7 @@ public class WifiManager { * [0, {@link #getMaxSignalLevel()}], where 0 is the lowest (worst signal) RSSI * rating and {@link #getMaxSignalLevel()} is the highest (best signal) RSSI rating. */ + @IntRange(from = 0) public int calculateSignalLevel(int rssi) { try { return mService.calculateSignalLevel(rssi); @@ -2881,6 +2883,7 @@ public class WifiManager { * Get the system default maximum signal level. * This is the maximum RSSI level returned by {@link #calculateSignalLevel(int)}. */ + @IntRange(from = 0) public int getMaxSignalLevel() { return calculateSignalLevel(Integer.MAX_VALUE); } -- cgit v1.2.3 From 09daba158e57120b1781c39d9561bf66701bd950 Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 23 Jan 2020 12:47:24 -0800 Subject: WifiManager: remove Executor-less overloads Executor-less overloads are unnecessary and make call sites less clear. Bug: 144925765 Test: atest FrameworksWifiApiTests Change-Id: Ifd4bff1911e1ae3925c966913fe9c6cf06ca358c --- wifi/java/android/net/wifi/WifiManager.java | 36 ---------------------- .../src/android/net/wifi/WifiManagerTest.java | 28 +++++------------ 2 files changed, 8 insertions(+), 56 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 0e8c6ed8774e..7f99fe4f64b4 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1792,18 +1792,6 @@ public class WifiManager { } } - /** - * Same as {@link #registerNetworkRequestMatchCallback(Executor, NetworkRequestMatchCallback)}, - * except that the callback will be executed on the application's main thread. - * @param callback Callback for network match events to register. - * @hide - */ - @SystemApi - @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - public void registerNetworkRequestMatchCallback(@NonNull NetworkRequestMatchCallback callback) { - registerNetworkRequestMatchCallback(mContext.getMainExecutor(), callback); - } - /** * Registers a callback for NetworkRequest matches. See {@link NetworkRequestMatchCallback}. * Caller can unregister a previously registered callback using @@ -3718,18 +3706,6 @@ public class WifiManager { } } - /** - * Same as {@link #registerSoftApCallback(Executor, SoftApCallback)}, - * except that the callback will be executed on the application's main thread. - * @param callback Callback for soft AP events - * @hide - */ - @SystemApi - @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - public void registerSoftApCallback(@NonNull SoftApCallback callback) { - registerSoftApCallback(mContext.getMainExecutor(), callback); - } - /** * Registers a callback for Soft AP. See {@link SoftApCallback}. Caller will receive the current * soft AP state and number of connected devices immediately after a successful call to this API @@ -5151,18 +5127,6 @@ public class WifiManager { } } - /** - * Same as {@link #registerTrafficStateCallback(Executor, TrafficStateCallback)}, - * except that the callback will be executed on the application's main thread. - * @param callback Callback for traffic state events - * @hide - */ - @SystemApi - @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - public void registerTrafficStateCallback(@NonNull TrafficStateCallback callback) { - registerTrafficStateCallback(mContext.getMainExecutor(), callback); - } - /** * Registers a callback for monitoring traffic state. See {@link TrafficStateCallback}. These * callbacks will be invoked periodically by platform to inform clients about the current diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index f369203e05ab..3846473911a0 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -880,17 +880,6 @@ public class WifiManagerTest { } } - /** - * Verify main looper is used when handler is not provided. - */ - @Test - public void registerSoftApCallbackUsesMainExecutorOnNoExecutorProvided() { - when(mContext.getMainExecutor()).thenReturn( - new HandlerExecutor(new Handler(mLooper.getLooper()))); - mWifiManager.registerSoftApCallback(mSoftApCallback); - verify(mContext).getMainExecutor(); - } - /** * Verify the call to registerSoftApCallback goes to WifiServiceImpl. */ @@ -1389,11 +1378,10 @@ public class WifiManagerTest { @Test public void registerTrafficStateCallbackUsesMainLooperOnNullArgumentForHandler() throws Exception { - when(mContext.getMainExecutor()).thenReturn( - new HandlerExecutor(new Handler(mLooper.getLooper()))); ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(ITrafficStateCallback.Stub.class); - mWifiManager.registerTrafficStateCallback(mTrafficStateCallback); + mWifiManager.registerTrafficStateCallback( + new HandlerExecutor(new Handler(mLooper.getLooper())), mTrafficStateCallback); verify(mWifiService).registerTrafficStateCallback( any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -1474,11 +1462,11 @@ public class WifiManagerTest { @Test public void registerNetworkRequestMatchCallbackCallGoesToWifiServiceImpl() throws Exception { - when(mContext.getMainExecutor()).thenReturn( - new HandlerExecutor(new Handler(mLooper.getLooper()))); ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(INetworkRequestMatchCallback.Stub.class); - mWifiManager.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback); + mWifiManager.registerNetworkRequestMatchCallback( + new HandlerExecutor(new Handler(mLooper.getLooper())), + mNetworkRequestMatchCallback); verify(mWifiService).registerNetworkRequestMatchCallback( any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -1530,11 +1518,11 @@ public class WifiManagerTest { @Test public void networkRequestUserSelectionCallbackCallGoesToWifiServiceImpl() throws Exception { - when(mContext.getMainExecutor()).thenReturn( - new HandlerExecutor(new Handler(mLooper.getLooper()))); ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(INetworkRequestMatchCallback.Stub.class); - mWifiManager.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback); + mWifiManager.registerNetworkRequestMatchCallback( + new HandlerExecutor(new Handler(mLooper.getLooper())), + mNetworkRequestMatchCallback); verify(mWifiService).registerNetworkRequestMatchCallback( any(IBinder.class), callbackCaptor.capture(), anyInt()); -- cgit v1.2.3 From 25e64398465aa689a2d8cbcf2e9490b579775e4a Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 23 Jan 2020 18:21:08 -0800 Subject: WifiInfo: Rename getters Renamed getters to make their meaning clearer. Bug: 145745815 Test: compiles Change-Id: Ia0dc4216a7f38e5d475b6e44dd55bf46c812d2f6 --- wifi/java/android/net/wifi/WifiInfo.java | 92 +++++++++++------------ wifi/tests/src/android/net/wifi/WifiInfoTest.java | 4 +- 2 files changed, 48 insertions(+), 48 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java index 419bcb107013..f8d48c5403f7 100644 --- a/wifi/java/android/net/wifi/WifiInfo.java +++ b/wifi/java/android/net/wifi/WifiInfo.java @@ -178,7 +178,7 @@ public class WifiInfo implements Parcelable { * If connected to a network suggestion or specifier, store the package name of the app, * else null. */ - private String mAppPackageName; + private String mRequestingPackageName; /** * Running total count of lost (not ACKed) transmitted unicast data packets. @@ -201,68 +201,68 @@ public class WifiInfo implements Parcelable { */ public long rxSuccess; - private double mTxBadRate; + private double mLostTxPacketsPerSecond; /** * Average rate of lost transmitted packets, in units of packets per second. * @hide */ @SystemApi - public double getTxBadRate() { - return mTxBadRate; + public double getLostTxPacketsPerSecond() { + return mLostTxPacketsPerSecond; } /** @hide */ - public void setTxBadRate(double txBadRate) { - mTxBadRate = txBadRate; + public void setLostTxPacketsPerSecond(double lostTxPacketsPerSecond) { + mLostTxPacketsPerSecond = lostTxPacketsPerSecond; } - private double mTxRetriesRate; + private double mTxRetriedTxPacketsPerSecond; /** * Average rate of transmitted retry packets, in units of packets per second. * @hide */ @SystemApi - public double getTxRetriesRate() { - return mTxRetriesRate; + public double getRetriedTxPacketsPerSecond() { + return mTxRetriedTxPacketsPerSecond; } /** @hide */ - public void setTxRetriesRate(double txRetriesRate) { - mTxRetriesRate = txRetriesRate; + public void setRetriedTxPacketsRate(double txRetriedTxPacketsPerSecond) { + mTxRetriedTxPacketsPerSecond = txRetriedTxPacketsPerSecond; } - private double mTxSuccessRate; + private double mSuccessfulTxPacketsPerSecond; /** * Average rate of successfully transmitted unicast packets, in units of packets per second. * @hide */ @SystemApi - public double getTxSuccessRate() { - return mTxSuccessRate; + public double getSuccessfulTxPacketsPerSecond() { + return mSuccessfulTxPacketsPerSecond; } /** @hide */ - public void setTxSuccessRate(double txSuccessRate) { - mTxSuccessRate = txSuccessRate; + public void setSuccessfulTxPacketsPerSecond(double successfulTxPacketsPerSecond) { + mSuccessfulTxPacketsPerSecond = successfulTxPacketsPerSecond; } - private double mRxSuccessRate; + private double mSuccessfulRxPacketsPerSecond; /** * Average rate of received unicast data packets, in units of packets per second. * @hide */ @SystemApi - public double getRxSuccessRate() { - return mRxSuccessRate; + public double getSuccessfulRxPacketsPerSecond() { + return mSuccessfulRxPacketsPerSecond; } /** @hide */ - public void setRxSuccessRate(double rxSuccessRate) { - mRxSuccessRate = rxSuccessRate; + public void setSuccessfulRxPacketsPerSecond(double successfulRxPacketsPerSecond) { + mSuccessfulRxPacketsPerSecond = successfulRxPacketsPerSecond; } /** @hide */ @@ -319,17 +319,17 @@ public class WifiInfo implements Parcelable { setMeteredHint(false); setEphemeral(false); setOsuAp(false); - setAppPackageName(null); + setRequestingPackageName(null); setFQDN(null); setProviderFriendlyName(null); txBad = 0; txSuccess = 0; rxSuccess = 0; txRetries = 0; - mTxBadRate = 0; - mTxSuccessRate = 0; - mRxSuccessRate = 0; - mTxRetriesRate = 0; + mLostTxPacketsPerSecond = 0; + mSuccessfulTxPacketsPerSecond = 0; + mSuccessfulRxPacketsPerSecond = 0; + mTxRetriedTxPacketsPerSecond = 0; score = 0; } @@ -353,8 +353,8 @@ public class WifiInfo implements Parcelable { mMeteredHint = source.mMeteredHint; mEphemeral = source.mEphemeral; mTrusted = source.mTrusted; - mAppPackageName = - source.mAppPackageName; + mRequestingPackageName = + source.mRequestingPackageName; mOsuAp = source.mOsuAp; mFqdn = source.mFqdn; mProviderFriendlyName = source.mProviderFriendlyName; @@ -362,10 +362,10 @@ public class WifiInfo implements Parcelable { txRetries = source.txRetries; txSuccess = source.txSuccess; rxSuccess = source.rxSuccess; - mTxBadRate = source.mTxBadRate; - mTxRetriesRate = source.mTxRetriesRate; - mTxSuccessRate = source.mTxSuccessRate; - mRxSuccessRate = source.mRxSuccessRate; + mLostTxPacketsPerSecond = source.mLostTxPacketsPerSecond; + mTxRetriedTxPacketsPerSecond = source.mTxRetriedTxPacketsPerSecond; + mSuccessfulTxPacketsPerSecond = source.mSuccessfulTxPacketsPerSecond; + mSuccessfulRxPacketsPerSecond = source.mSuccessfulRxPacketsPerSecond; score = source.score; mWifiStandard = source.mWifiStandard; mMaxSupportedTxLinkSpeed = source.mMaxSupportedTxLinkSpeed; @@ -777,8 +777,8 @@ public class WifiInfo implements Parcelable { } /** {@hide} */ - public void setAppPackageName(@Nullable String packageName) { - mAppPackageName = packageName; + public void setRequestingPackageName(@Nullable String packageName) { + mRequestingPackageName = packageName; } /** @@ -788,8 +788,8 @@ public class WifiInfo implements Parcelable { * @hide */ @SystemApi - public @Nullable String getAppPackageName() { - return mAppPackageName; + public @Nullable String getRequestingPackageName() { + return mRequestingPackageName; } @@ -956,16 +956,16 @@ public class WifiInfo implements Parcelable { dest.writeInt(mTrusted ? 1 : 0); dest.writeInt(score); dest.writeLong(txSuccess); - dest.writeDouble(mTxSuccessRate); + dest.writeDouble(mSuccessfulTxPacketsPerSecond); dest.writeLong(txRetries); - dest.writeDouble(mTxRetriesRate); + dest.writeDouble(mTxRetriedTxPacketsPerSecond); dest.writeLong(txBad); - dest.writeDouble(mTxBadRate); + dest.writeDouble(mLostTxPacketsPerSecond); dest.writeLong(rxSuccess); - dest.writeDouble(mRxSuccessRate); + dest.writeDouble(mSuccessfulRxPacketsPerSecond); mSupplicantState.writeToParcel(dest, flags); dest.writeInt(mOsuAp ? 1 : 0); - dest.writeString(mAppPackageName); + dest.writeString(mRequestingPackageName); dest.writeString(mFqdn); dest.writeString(mProviderFriendlyName); dest.writeInt(mWifiStandard); @@ -1000,16 +1000,16 @@ public class WifiInfo implements Parcelable { info.mTrusted = in.readInt() != 0; info.score = in.readInt(); info.txSuccess = in.readLong(); - info.mTxSuccessRate = in.readDouble(); + info.mSuccessfulTxPacketsPerSecond = in.readDouble(); info.txRetries = in.readLong(); - info.mTxRetriesRate = in.readDouble(); + info.mTxRetriedTxPacketsPerSecond = in.readDouble(); info.txBad = in.readLong(); - info.mTxBadRate = in.readDouble(); + info.mLostTxPacketsPerSecond = in.readDouble(); info.rxSuccess = in.readLong(); - info.mRxSuccessRate = in.readDouble(); + info.mSuccessfulRxPacketsPerSecond = in.readDouble(); info.mSupplicantState = SupplicantState.CREATOR.createFromParcel(in); info.mOsuAp = in.readInt() != 0; - info.mAppPackageName = in.readString(); + info.mRequestingPackageName = in.readString(); info.mFqdn = in.readString(); info.mProviderFriendlyName = in.readString(); info.mWifiStandard = in.readInt(); diff --git a/wifi/tests/src/android/net/wifi/WifiInfoTest.java b/wifi/tests/src/android/net/wifi/WifiInfoTest.java index 04759ac21bba..311bbc41b8fe 100644 --- a/wifi/tests/src/android/net/wifi/WifiInfoTest.java +++ b/wifi/tests/src/android/net/wifi/WifiInfoTest.java @@ -64,7 +64,7 @@ public class WifiInfoTest { writeWifiInfo.setOsuAp(true); writeWifiInfo.setFQDN(TEST_FQDN); writeWifiInfo.setProviderFriendlyName(TEST_PROVIDER_NAME); - writeWifiInfo.setAppPackageName(TEST_PACKAGE_NAME); + writeWifiInfo.setRequestingPackageName(TEST_PACKAGE_NAME); writeWifiInfo.setWifiStandard(TEST_WIFI_STANDARD); writeWifiInfo.setMaxSupportedTxLinkSpeedMbps(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS); writeWifiInfo.setMaxSupportedRxLinkSpeedMbps(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS); @@ -83,7 +83,7 @@ public class WifiInfoTest { assertTrue(readWifiInfo.isTrusted()); assertTrue(readWifiInfo.isOsuAp()); assertTrue(readWifiInfo.isPasspointAp()); - assertEquals(TEST_PACKAGE_NAME, readWifiInfo.getAppPackageName()); + assertEquals(TEST_PACKAGE_NAME, readWifiInfo.getRequestingPackageName()); assertEquals(TEST_FQDN, readWifiInfo.getPasspointFqdn()); assertEquals(TEST_PROVIDER_NAME, readWifiInfo.getPasspointProviderFriendlyName()); assertEquals(TEST_WIFI_STANDARD, readWifiInfo.getWifiStandard()); -- cgit v1.2.3 From 690c3fd0bc0054ebde07b6a9549ec065bec82b3f Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Thu, 23 Jan 2020 18:40:07 -0800 Subject: [SAE] Support for WPA3 Personal auto-upgrade Support for auto-upgrading WPA2-Personal saved network to WPA3-Personal. Match PSK saved networks to SAE scan result candidates for auto-upgrade. Do not auto-upgrade if legacy PSK APs are in range, to allow roaming. Added overlays to enable or disable the feature, and to allow driver offload, where the framework would always send both PSK and SAE key managements to supplicant. Bug: 142507644 Test: atest ScanResultMatchInfoTest ClientModeImplTest WifiCandidatesTest Test: Manual test with WPA3 in transition AP, verify upgrade Test: Manual test with WPA3 in transition AP and WPA2 AP in range, verify no upgrade Change-Id: I931b53cbad5ad9b6edef532fe330b489cc8109d2 --- wifi/java/android/net/wifi/WifiConfiguration.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 114e0fa21296..0ef224a5f8ee 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -481,12 +481,14 @@ public class WifiConfiguration implements Parcelable { allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X); break; case SECURITY_TYPE_SAE: + allowedProtocols.set(WifiConfiguration.Protocol.RSN); allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SAE); allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP); allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); requirePMF = true; break; case SECURITY_TYPE_EAP_SUITE_B: + allowedProtocols.set(WifiConfiguration.Protocol.RSN); allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SUITE_B_192); allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_256); allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256); @@ -496,6 +498,7 @@ public class WifiConfiguration implements Parcelable { requirePMF = true; break; case SECURITY_TYPE_OWE: + allowedProtocols.set(WifiConfiguration.Protocol.RSN); allowedKeyManagement.set(WifiConfiguration.KeyMgmt.OWE); allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP); allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); -- cgit v1.2.3 From 660d9d0e2b5f59baadde013b98663436f5c12c04 Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 23 Jan 2020 13:53:08 -0800 Subject: Rename WifiManager.enableVerboseLogging/getVerboseLoggingLevel - Rename enableVerboseLogging -> setVerboseLoggingEnabled - Rename getVerboseLoggingLevel -> isVerboseLoggingEnabled - Converted getter/setter to take/return boolean Bug: 144925765 Test: compiles Change-Id: If40d58ec687680f731ba75a1db81ff65d58f364b --- wifi/java/android/net/wifi/WifiManager.java | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index fb3e794d92d1..c7475ee92dc7 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -4854,13 +4854,19 @@ public class WifiManager { /** * Set Wi-Fi verbose logging level from developer settings. * - * @param verbose the verbose logging level to set. 0 will disable verbose logging, a positive - * integer will enable verbose logging. + * @param enable true to enable verbose logging, false to disable. * * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) + public void setVerboseLoggingEnabled(boolean enable) { + enableVerboseLogging(enable ? 1 : 0); + } + + /** @hide */ + @UnsupportedAppUsage + @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void enableVerboseLogging (int verbose) { try { mService.enableVerboseLogging(verbose); @@ -4871,15 +4877,23 @@ public class WifiManager { } /** - * Get the persisted WiFi verbose logging level, set by {@link #enableVerboseLogging(int)}. + * Get the persisted Wi-Fi verbose logging level, set by + * {@link #setVerboseLoggingEnabled(boolean)}. * No permissions are required to call this method. * - * @return 0 to indicate that verbose logging is disabled, a positive integer to indicate that - * verbose logging is enabled. + * @return true to indicate that verbose logging is enabled, false to indicate that verbose + * logging is disabled. * * @hide */ @SystemApi + public boolean isVerboseLoggingEnabled() { + return getVerboseLoggingLevel() > 0; + } + + /** @hide */ + // TODO(b/145484145): remove once SUW stops calling this via reflection + @UnsupportedAppUsage public int getVerboseLoggingLevel() { try { return mService.getVerboseLoggingLevel(); @@ -5204,7 +5218,7 @@ public class WifiManager { * level from wifi service. */ private void updateVerboseLoggingEnabledFromService() { - mVerboseLoggingEnabled = getVerboseLoggingLevel() > 0; + mVerboseLoggingEnabled = isVerboseLoggingEnabled(); } /** -- cgit v1.2.3 From 8d12d098a67515de4e37cd3dccbfe1993acf1bb4 Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Mon, 27 Jan 2020 10:06:15 -0800 Subject: [WIFI] Update instructions for running tests Time to stop using local solutions. Change-Id: If2fddf4874fc4019680e72f57f54fab7a5824278 --- wifi/tests/README.md | 21 +-------------------- wifi/tests/runtests.sh | 25 ------------------------- 2 files changed, 1 insertion(+), 45 deletions(-) delete mode 100755 wifi/tests/runtests.sh (limited to 'wifi') diff --git a/wifi/tests/README.md b/wifi/tests/README.md index b0594f2d29b1..f90940470432 100644 --- a/wifi/tests/README.md +++ b/wifi/tests/README.md @@ -8,12 +8,9 @@ libraries. The easiest way to run tests is simply run ``` -frameworks/base/wifi/tests/runtests.sh +atest android.net.wifi ``` -`runtests.sh` will build the test project and all of its dependencies and push the APK to the -connected device. It will then run the tests on the device. - To pick up changes in framework/base, you will need to: 1. rebuild the framework library 'make -j32' 2. sync over the updated library to the device 'adb sync' @@ -24,22 +21,6 @@ To enable syncing data to the device for first time after clean reflash: 2. adb reboot 3. adb remount -See below for a few example of options to limit which tests are run. -See the -[AndroidJUnitRunner Documentation](https://developer.android.com/reference/android/support/test/runner/AndroidJUnitRunner.html) -for more details on the supported options. - -``` -runtests.sh -e package android.net.wifi -runtests.sh -e class android.net.wifi.WifiScannerTest -``` - -If you manually build and push the test APK to the device you can run tests using - -``` -adb shell am instrument -w 'android.net.wifi.test/androidx.test.runner.AndroidJUnitRunner' -``` - ## Adding Tests Tests can be added by adding classes to the src directory. JUnit4 style test cases can be written by simply annotating test methods with `org.junit.Test`. diff --git a/wifi/tests/runtests.sh b/wifi/tests/runtests.sh deleted file mode 100755 index 4024371dd97d..000000000000 --- a/wifi/tests/runtests.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env bash - -if [ -z $ANDROID_BUILD_TOP ]; then - echo "You need to source and lunch before you can use this script" - exit 1 -fi - -echo "Running tests" - -set -e # fail early - -echo "+ mmma -j32 $ANDROID_BUILD_TOP/frameworks/base/wifi/tests" -# NOTE Don't actually run the command above since this shell doesn't inherit functions from the -# caller. -$ANDROID_BUILD_TOP/build/soong/soong_ui.bash --make-mode MODULES-IN-frameworks-base-wifi-tests - -set -x # print commands - -adb wait-for-device - -TARGET_ARCH=$($ANDROID_BUILD_TOP/build/soong/soong_ui.bash --dumpvar-mode TARGET_ARCH) -adb install -r -g "$OUT/testcases/FrameworksWifiApiTests/$TARGET_ARCH/FrameworksWifiApiTests.apk" - -adb shell am instrument --no-hidden-api-checks -w "$@" \ - 'android.net.wifi.test/androidx.test.runner.AndroidJUnitRunner' -- cgit v1.2.3 From 80e289cef469dc8665097aa4bc4907ec171c3d0a Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 23 Jan 2020 17:19:36 -0800 Subject: WifiManager/WifiScanner: Misc API cleanup - Protected getCurrentNetwork() with a privileged permission - Undeprecated restoreSupplicantBackupData: we will still need to support restoring old backup data for the foreseeable future. What is not supported is getting backup data in the old supplicant format. - Cleanup annotation for WifiScanner: the entire class is @SystemApi, no need to mark the individual methods @SystemApi Bug: 144925765 Test: compiles Change-Id: Ie3852af04efa88def4f52499e7c802f0adb747e8 --- wifi/java/android/net/wifi/WifiManager.java | 7 ++++--- wifi/java/android/net/wifi/WifiScanner.java | 2 -- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index fb3e794d92d1..3448e522ecfa 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -4910,7 +4910,10 @@ public class WifiManager { */ @Nullable @SystemApi - @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_SETTINGS, + android.Manifest.permission.NETWORK_SETUP_WIZARD + }) public Network getCurrentNetwork() { try { return mService.getCurrentNetwork(); @@ -5012,10 +5015,8 @@ public class WifiManager { * and ipconfig.txt file. * @param supplicantData bytes representing wpa_supplicant.conf * @param ipConfigData bytes representing ipconfig.txt - * @deprecated this is no longer supported. * @hide */ - @Deprecated @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void restoreSupplicantBackupData( diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index 18533ef5b117..6f01350d8af4 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -1037,10 +1037,8 @@ public class WifiScanner { /** * Retrieve the most recent scan results from a single scan request. - * {@hide} */ @NonNull - @SystemApi @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public List getSingleScanResults() { validateChannel(); -- cgit v1.2.3 From 4411940b632293fb62913199a09b5977930a9555 Mon Sep 17 00:00:00 2001 From: David Su Date: Mon, 27 Jan 2020 13:26:52 -0800 Subject: Wifi: Rename removeDoubleQuotes to sanitizeSsid Keep removeDoubleQuotes as it is marked @UnsupportedAppUsage. Bug: 145745815 Test: compiles Change-Id: I68a16b64eba3d84265b5cf2c83b434dc4fc7fa3c --- wifi/java/android/net/wifi/WifiInfo.java | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java index f8d48c5403f7..7c031eaaeaf4 100644 --- a/wifi/java/android/net/wifi/WifiInfo.java +++ b/wifi/java/android/net/wifi/WifiInfo.java @@ -889,6 +889,13 @@ public class WifiInfo implements Parcelable { */ @Nullable @SystemApi + public static String sanitizeSsid(@Nullable String string) { + return removeDoubleQuotes(string); + } + + /** @hide */ + @UnsupportedAppUsage + @Nullable public static String removeDoubleQuotes(@Nullable String string) { if (string == null) return null; final int length = string.length(); -- cgit v1.2.3 From 3f69afa7d7b0da88618fdb2edc9636c310b7a226 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Tue, 28 Jan 2020 13:21:06 -0800 Subject: WifiManager: Add exemption notes for deprecated APIs Bug: 148456017 Test: Compiles (m doc-comment-check-docs) Change-Id: I252a9525c3277ee57f337f2f340ebed3da79c106 --- wifi/java/android/net/wifi/WifiManager.java | 83 +++++++++++++++++++++++------ 1 file changed, 68 insertions(+), 15 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 1d71cf972aec..9a251062cd9e 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1334,10 +1334,12 @@ public class WifiManager { * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration * when auto-connecting to wifi. * Compatibility Note: For applications targeting - * {@link android.os.Build.VERSION_CODES#Q} or above, this API will return an empty list, - * except for: + * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return an + * empty list. + *

    + * Deprecation Exemptions: *

      - *
    • Device Owner (DO) & Profile Owner (PO) apps will have access to the full list. + *
    • Device Owner (DO), Profile Owner (PO) and system apps will have access to the full list. *
    • Callers with Carrier privilege will receive a restricted list only containing * configurations which they created. *
    @@ -1528,7 +1530,13 @@ public class WifiManager { * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration * when auto-connecting to wifi. * Compatibility Note: For applications targeting - * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return {@code -1}. + * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return + * {@code -1}. + *

    + * Deprecation Exemptions: + *

      + *
    • Device Owner (DO), Profile Owner (PO) and system apps. + *
    */ @Deprecated public int addNetwork(WifiConfiguration config) { @@ -1563,7 +1571,13 @@ public class WifiManager { * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration * when auto-connecting to wifi. * Compatibility Note: For applications targeting - * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return {@code -1}. + * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return + * {@code -1}. + *

    + * Deprecation Exemptions: + *

      + *
    • Device Owner (DO), Profile Owner (PO) and system apps. + *
    */ @Deprecated public int updateNetwork(WifiConfiguration config) { @@ -1961,8 +1975,13 @@ public class WifiManager { * See {@link #addNetworkSuggestions(List)}, {@link #removeNetworkSuggestions(List)} for new * API to add Wi-Fi networks for consideration when auto-connecting to wifi. * Compatibility Note: For applications targeting - * {@link android.os.Build.VERSION_CODES#R} or above, except for system of DO/PO apps, this API - * will throw {@link IllegalArgumentException} + * {@link android.os.Build.VERSION_CODES#R} or above, this API will always fail and throw + * {@link IllegalArgumentException}. + *

    + * Deprecation Exemptions: + *

      + *
    • Device Owner (DO), Profile Owner (PO) and system apps. + *
    */ public void addOrUpdatePasspointConfiguration(PasspointConfiguration config) { try { @@ -2088,7 +2107,13 @@ public class WifiManager { * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration * when auto-connecting to wifi. * Compatibility Note: For applications targeting - * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return false. + * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return + * {@code false}. + *

    + * Deprecation Exemptions: + *

      + *
    • Device Owner (DO), Profile Owner (PO) and system apps. + *
    */ @Deprecated public boolean removeNetwork(int netId) { @@ -2132,7 +2157,12 @@ public class WifiManager { * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration * when auto-connecting to wifi. * Compatibility Note: For applications targeting - * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return false. + * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return + * {@code false}. + * Deprecation Exemptions: + *
      + *
    • Device Owner (DO), Profile Owner (PO) and system apps. + *
    */ @Deprecated public boolean enableNetwork(int netId, boolean attemptConnect) { @@ -2162,7 +2192,13 @@ public class WifiManager { * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration * when auto-connecting to wifi. * Compatibility Note: For applications targeting - * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return false. + * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return + * {@code false}. + *

    + * Deprecation Exemptions: + *

      + *
    • Device Owner (DO), Profile Owner (PO) and system apps. + *
    */ @Deprecated public boolean disableNetwork(int netId) { @@ -2185,7 +2221,13 @@ public class WifiManager { * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration * when auto-connecting to wifi. * Compatibility Note: For applications targeting - * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return false. + * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return + * {@code false}. + *

    + * Deprecation Exemptions: + *

      + *
    • Device Owner (DO), Profile Owner (PO) and system apps. + *
    */ @Deprecated public boolean disconnect() { @@ -2209,7 +2251,13 @@ public class WifiManager { * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration * when auto-connecting to wifi. * Compatibility Note: For applications targeting - * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return false. + * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return + * {@code false}. + *

    + * Deprecation Exemptions: + *

      + *
    • Device Owner (DO), Profile Owner (PO) and system apps. + *
    */ @Deprecated public boolean reconnect() { @@ -2803,9 +2851,14 @@ public class WifiManager { * @deprecated Starting with Build.VERSION_CODES#Q, applications are not allowed to * enable/disable Wi-Fi. * Compatibility Note: For applications targeting - * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return {@code false} - * and will have no effect. If apps are targeting an older SDK ( - * {@link android.os.Build.VERSION_CODES#P} or below), they can continue to use this API. + * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return + * {@code false}. If apps are targeting an older SDK ({@link android.os.Build.VERSION_CODES#P} + * or below), they can continue to use this API. + *

    + * Deprecation Exemptions: + *

      + *
    • Device Owner (DO), Profile Owner (PO) and system apps. + *
    */ @Deprecated public boolean setWifiEnabled(boolean enabled) { -- cgit v1.2.3 From 5d1f1d415009784836293324af36d98b306d4b97 Mon Sep 17 00:00:00 2001 From: David Su Date: Wed, 29 Jan 2020 14:50:14 -0800 Subject: Remove WifiManager.isDualModeSupported() Remove isDualModeSupported, replace callers with isStaApConcurrencySupported. Bug: 144925765 Test: atest FrameworksWifiApiTests Test: boots up and connects to Wifi Change-Id: I2ed7c483599a1f919cf8a14c22659cf957b67cad --- wifi/java/android/net/wifi/IWifiManager.aidl | 2 -- wifi/java/android/net/wifi/WifiManager.java | 23 ---------------------- .../com/android/server/wifi/BaseWifiService.java | 4 +++- .../src/android/net/wifi/WifiManagerTest.java | 10 ---------- 4 files changed, 3 insertions(+), 36 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 31b3a5064932..1f1c0c12cf21 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -123,8 +123,6 @@ interface IWifiManager boolean isWifiStandardSupported(int standard); - boolean needs5GHzToAnyApBandConversion(); - DhcpInfo getDhcpInfo(); boolean isScanAlwaysAvailable(); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 9a251062cd9e..76f97164032c 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -2801,29 +2801,6 @@ public class WifiManager { } } - /** - * Check if the device is dual mode capable i.e. supports concurrent STA + Soft AP. - * - * If the device is dual mode capable, it may require conversion of the user's Soft AP band - * selection {@link SoftApConfiguration#mBand} from {@link SoftApConfiguration#BAND_5GHZ} to - * include also {@link SoftApConfiguration#BAND_2GHZ}, since if the device is connected to a - * 5GHz DFS channel as a STA, it may be unable to honor a request to start Soft AP on the same - * DFS channel. - * - * @return {@code true} if dual mode STA + AP is supported by this device, {@code false} - * otherwise. - * @hide - */ - @SystemApi - @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - public boolean isDualModeSupported() { - try { - return mService.needs5GHzToAnyApBandConversion(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - /** * Return the DHCP-assigned addresses from the last successful DHCP request, * if any. diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index b46755349ad7..060c85cac209 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -38,6 +38,7 @@ import android.net.wifi.ScanResult; import android.net.wifi.SoftApConfiguration; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; import android.net.wifi.WifiNetworkSuggestion; import android.net.wifi.hotspot2.IProvisioningCallback; import android.net.wifi.hotspot2.OsuProvider; @@ -268,7 +269,8 @@ public class BaseWifiService extends IWifiManager.Stub { throw new UnsupportedOperationException(); } - @Override + /** @deprecated use {@link WifiManager#isStaApConcurrencySupported()} */ + @Deprecated public boolean needs5GHzToAnyApBandConversion() { throw new UnsupportedOperationException(); } diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 0c2876e340c1..a189d507a32a 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -1927,16 +1927,6 @@ public class WifiManagerTest { assertEquals(wifiInfo, mWifiManager.getConnectionInfo()); } - /** - * Test behavior of {@link WifiManager#isDualModeSupported()} ()} - */ - @Test - public void testIsDualModeSupported() throws Exception { - when(mWifiService.needs5GHzToAnyApBandConversion()).thenReturn(true); - assertTrue(mWifiManager.isDualModeSupported()); - verify(mWifiService).needs5GHzToAnyApBandConversion(); - } - /** * Test behavior of {@link WifiManager#is5GHzBandSupported()} */ -- cgit v1.2.3 From 27c3df8ee15b8a06b7884b99dbf3a2cc27abc478 Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Wed, 29 Jan 2020 14:14:45 -0800 Subject: [Passpoint] Create an API to get a unique identifier Create an API to get a unique identifier of a PasspointConfiguration object. Bug: 148555465 Test: atest PasspointConfigurationTest Change-Id: I74ada04d21b1b8df28b78ca4dd91482bf79dc6cc --- .../net/wifi/hotspot2/PasspointConfiguration.java | 15 +++++++ .../wifi/hotspot2/PasspointConfigurationTest.java | 51 ++++++++++++++++++++++ 2 files changed, 66 insertions(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java index 3a0d080594c8..756d679b8f21 100644 --- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java +++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java @@ -19,6 +19,7 @@ package android.net.wifi.hotspot2; import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_NONE; import static android.net.wifi.WifiConfiguration.MeteredOverride; +import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.net.wifi.hotspot2.pps.Credential; @@ -895,4 +896,18 @@ public final class PasspointConfiguration implements Parcelable { public boolean isOsuProvisioned() { return getUpdateIdentifier() != Integer.MIN_VALUE; } + + /** + * Get a unique identifier for a PasspointConfiguration object. + * + * @return A unique identifier + * @throws IllegalStateException if Credential or HomeSP nodes are not initialized + */ + public @NonNull String getUniqueId() throws IllegalStateException { + if (mCredential == null || mHomeSp == null || TextUtils.isEmpty(mHomeSp.getFqdn())) { + throw new IllegalStateException("Credential or HomeSP are not initialized"); + } + + return mHomeSp.getFqdn(); + } } diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java index 654154d77b0d..e78c5bf992f3 100644 --- a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java @@ -18,6 +18,7 @@ package android.net.wifi.hotspot2; import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_NONE; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -364,4 +365,54 @@ public class PasspointConfigurationTest { assertTrue(config.validateForR2()); assertTrue(config.isOsuProvisioned()); } + + /** + * Verify that the unique identifier generated is correct. + * + * @throws Exception + */ + @Test + public void validateUniqueId() throws Exception { + PasspointConfiguration config = PasspointTestUtils.createConfig(); + String uniqueId; + uniqueId = config.getUniqueId(); + assertEquals(uniqueId, config.getHomeSp().getFqdn()); + } + + /** + * Verify that the unique identifier API generates an exception if HomeSP is not initialized. + * + * @throws Exception + */ + @Test + public void validateUniqueIdExceptionWithEmptyHomeSp() throws Exception { + PasspointConfiguration config = PasspointTestUtils.createConfig(); + config.setHomeSp(null); + boolean exceptionCaught = false; + try { + String uniqueId = config.getUniqueId(); + } catch (IllegalStateException e) { + exceptionCaught = true; + } + assertTrue(exceptionCaught); + } + + /** + * Verify that the unique identifier API generates an exception if Credential is not + * initialized. + * + * @throws Exception + */ + @Test + public void validateUniqueIdExceptionWithEmptyCredential() throws Exception { + PasspointConfiguration config = PasspointTestUtils.createConfig(); + config.setCredential(null); + boolean exceptionCaught = false; + try { + String uniqueId = config.getUniqueId(); + } catch (IllegalStateException e) { + exceptionCaught = true; + } + assertTrue(exceptionCaught); + } } -- cgit v1.2.3 From 35b3843cccd40907b06d036e7d16f58cfcddcc69 Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Thu, 30 Jan 2020 10:37:55 -0800 Subject: [WPA3] Restore @hide to WifiConfiguration#SuiteBCipher Following up on API council review, restore the @hide to WifiConfiguration#SuiteBCipher and removed the link to it from WifiConfiguration#allowedSuiteBCiphers. SuiteBCipher is used internally. Bug: 148515393 Test: Compiles Change-Id: I8fe85295f807d5f9ec1b00585026dc01b7c0f29a --- wifi/java/android/net/wifi/WifiConfiguration.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 0ef224a5f8ee..372af42a3d14 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -373,6 +373,7 @@ public class WifiConfiguration implements Parcelable { * ECDHE_ECDSA * ECDHE_RSA * + * @hide */ public static class SuiteBCipher { private SuiteBCipher() { } @@ -715,8 +716,8 @@ public class WifiConfiguration implements Parcelable { public BitSet allowedGroupManagementCiphers; /** * The set of SuiteB ciphers supported by this configuration. - * To be used for WPA3-Enterprise mode. - * See {@link SuiteBCipher} for descriptions of the values. + * To be used for WPA3-Enterprise mode. Set automatically by the framework based on the + * certificate type that is used in this configuration. */ @NonNull public BitSet allowedSuiteBCiphers; -- cgit v1.2.3 From 4b702336f71225ec2615adc35b510463bf1ede66 Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 30 Jan 2020 12:43:41 -0800 Subject: Rename PERSISTENT_NET_ID/TEMPORARY_NET_ID Renamed to NETWORK_ID_PERSISTENT/ NETWORK_ID_TEMPORARY to conform to API guidelines. Bug: 147668001 Test: compiles Change-Id: I29d1f4b52e5b5f9852c14bc1861c15de96811e21 --- wifi/java/android/net/wifi/p2p/WifiP2pConfig.java | 12 ++++++------ wifi/java/android/net/wifi/p2p/WifiP2pGroup.java | 18 +++++++++++++----- wifi/java/android/net/wifi/p2p/WifiP2pManager.java | 2 +- 3 files changed, 20 insertions(+), 12 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java index 9562f95ac162..36c7213b3799 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java @@ -137,12 +137,12 @@ public class WifiP2pConfig implements Parcelable { /** @hide */ @UnsupportedAppUsage - public int netId = WifiP2pGroup.PERSISTENT_NET_ID; + public int netId = WifiP2pGroup.NETWORK_ID_PERSISTENT; /** * Get the network ID of this P2P configuration. - * @return either a non-negative network ID, or one of {@link WifiP2pGroup#PERSISTENT_NET_ID} or - * {@link WifiP2pGroup#TEMPORARY_NET_ID}. + * @return either a non-negative network ID, or one of + * {@link WifiP2pGroup#NETWORK_ID_PERSISTENT} or {@link WifiP2pGroup#NETWORK_ID_TEMPORARY}. */ public int getNetworkId() { return netId; @@ -280,7 +280,7 @@ public class WifiP2pConfig implements Parcelable { private String mPassphrase = ""; private int mGroupOperatingBand = GROUP_OWNER_BAND_AUTO; private int mGroupOperatingFrequency = GROUP_OWNER_BAND_AUTO; - private int mNetId = WifiP2pGroup.TEMPORARY_NET_ID; + private int mNetId = WifiP2pGroup.NETWORK_ID_TEMPORARY; /** * Specify the peer's MAC address. If not set, the device will @@ -460,9 +460,9 @@ public class WifiP2pConfig implements Parcelable { */ public @NonNull Builder enablePersistentMode(boolean persistent) { if (persistent) { - mNetId = WifiP2pGroup.PERSISTENT_NET_ID; + mNetId = WifiP2pGroup.NETWORK_ID_PERSISTENT; } else { - mNetId = WifiP2pGroup.TEMPORARY_NET_ID; + mNetId = WifiP2pGroup.NETWORK_ID_TEMPORARY; } return this; } diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java index 21f6704be0bb..e497b22d7769 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java @@ -41,7 +41,15 @@ public class WifiP2pGroup implements Parcelable { * The temporary network id. * @see #getNetworkId() */ - public static final int TEMPORARY_NET_ID = -1; + public static final int NETWORK_ID_TEMPORARY = -1; + + /** + * The temporary network id. + * + * @hide + */ + @UnsupportedAppUsage + public static final int TEMPORARY_NET_ID = NETWORK_ID_TEMPORARY; /** * The persistent network id. @@ -49,7 +57,7 @@ public class WifiP2pGroup implements Parcelable { * Otherwise, create a new persistent profile. * @see #getNetworkId() */ - public static final int PERSISTENT_NET_ID = -2; + public static final int NETWORK_ID_PERSISTENT = -2; /** The network name */ private String mNetworkName; @@ -130,13 +138,13 @@ public class WifiP2pGroup implements Parcelable { mPassphrase = match.group(4); mOwner = new WifiP2pDevice(match.group(5)); if (match.group(6) != null) { - mNetId = PERSISTENT_NET_ID; + mNetId = NETWORK_ID_PERSISTENT; } else { - mNetId = TEMPORARY_NET_ID; + mNetId = NETWORK_ID_TEMPORARY; } } else if (tokens[0].equals("P2P-INVITATION-RECEIVED")) { String sa = null; - mNetId = PERSISTENT_NET_ID; + mNetId = NETWORK_ID_PERSISTENT; for (String token : tokens) { String[] nameValue = token.split("="); if (nameValue.length != 2) continue; diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java index 3459c9496595..0fe06756a969 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java @@ -1293,7 +1293,7 @@ public class WifiP2pManager { @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void createGroup(Channel c, ActionListener listener) { checkChannel(c); - c.mAsyncChannel.sendMessage(CREATE_GROUP, WifiP2pGroup.PERSISTENT_NET_ID, + c.mAsyncChannel.sendMessage(CREATE_GROUP, WifiP2pGroup.NETWORK_ID_PERSISTENT, c.putListener(listener)); } -- cgit v1.2.3 From 8149f80bca4eff0646e8c5f393b5fb10c5d11814 Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 30 Jan 2020 15:56:02 -0800 Subject: WifiConfig: Hide RecentFailures and expose int failure code RecentFailures is just a wrapper around an int, no need to expose it. Instead, just expose a getter for the int itself, and the constants for the possible values of the int. Bug: 146046526 Test: make RunSettingsLibRoboTests -j40 Test: atest FrameworksWifiApiTests Change-Id: I817ec208c5ac6658c9d6cf443837ff7ea82679e0 --- wifi/java/android/net/wifi/WifiConfiguration.java | 73 +++++++++++++++-------- 1 file changed, 47 insertions(+), 26 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 0ef224a5f8ee..24357bdb77d6 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -1929,54 +1929,38 @@ public class WifiConfiguration implements Parcelable { private NetworkSelectionStatus mNetworkSelectionStatus = new NetworkSelectionStatus(); /** - * @hide * This class is intended to store extra failure reason information for the most recent * connection attempt, so that it may be surfaced to the settings UI + * @hide */ - @SystemApi + // TODO(b/148626966): called by SUW via reflection, remove once SUW is updated public static class RecentFailure { private RecentFailure() {} - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(value = {NONE, STATUS_AP_UNABLE_TO_HANDLE_NEW_STA}) - public @interface AssociationStatus {} - - /** - * No recent failure, or no specific reason given for the recent connection failure - */ - public static final int NONE = 0; - /** - * Connection to this network recently failed due to Association Rejection Status 17 - * (AP is full) - */ - public static final int STATUS_AP_UNABLE_TO_HANDLE_NEW_STA = 17; /** * Association Rejection Status code (NONE for success/non-association-rejection-fail) */ - @AssociationStatus - private int mAssociationStatus = NONE; + @RecentFailureReason + private int mAssociationStatus = RECENT_FAILURE_NONE; /** * @param status the association status code for the recent failure - * @hide */ - public void setAssociationStatus(@AssociationStatus int status) { + public void setAssociationStatus(@RecentFailureReason int status) { mAssociationStatus = status; } /** * Sets the RecentFailure to NONE - * @hide */ public void clear() { - mAssociationStatus = NONE; + mAssociationStatus = RECENT_FAILURE_NONE; } /** - * Get the recent failure code. One of {@link #NONE} or - * {@link #STATUS_AP_UNABLE_TO_HANDLE_NEW_STA}. + * Get the recent failure code. One of {@link #RECENT_FAILURE_NONE} or + * {@link #RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA}. */ - @AssociationStatus + @RecentFailureReason public int getAssociationStatus() { return mAssociationStatus; } @@ -1986,10 +1970,47 @@ public class WifiConfiguration implements Parcelable { * RecentFailure member * @hide */ + // TODO(b/148626966): called by SUW via reflection, once SUW is updated, make private and + // rename to mRecentFailure @NonNull - @SystemApi public final RecentFailure recentFailure = new RecentFailure(); + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = "RECENT_FAILURE_", value = { + RECENT_FAILURE_NONE, + RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA}) + public @interface RecentFailureReason {} + + /** + * No recent failure, or no specific reason given for the recent connection failure + * @hide + */ + @SystemApi + public static final int RECENT_FAILURE_NONE = 0; + /** + * Connection to this network recently failed due to Association Rejection Status 17 + * (AP is full) + * @hide + */ + @SystemApi + public static final int RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA = 17; + + /** + * Get the failure reason for the most recent connection attempt, or + * {@link #RECENT_FAILURE_NONE} if there was no failure. + * + * Failure reasons include: + * {@link #RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA} + * + * @hide + */ + @RecentFailureReason + @SystemApi + public int getRecentFailureReason() { + return recentFailure.getAssociationStatus(); + } + /** * Get the network selection status. * @hide -- cgit v1.2.3 From c87521077de12516b708f78fcdefef81652576d9 Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 30 Jan 2020 17:50:55 -0800 Subject: Rename WifiConfiguration.getHasEverConnected() Renamed to hasEverConnected() to conform to API guidelines. Bug: 146046526 Test: compiles Change-Id: Id7031baf7844799dd7ecafa09ff657065262a1cb --- wifi/java/android/net/wifi/WifiConfiguration.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 0ef224a5f8ee..da304d4467b3 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -1609,7 +1609,7 @@ public class WifiConfiguration implements Parcelable { } /** True if the device has ever connected to this network, false otherwise. */ - public boolean getHasEverConnected() { + public boolean hasEverConnected() { return mHasEverConnected; } @@ -1881,7 +1881,7 @@ public class WifiConfiguration implements Parcelable { setCandidate(source.getCandidate()); setCandidateScore(source.getCandidateScore()); setConnectChoice(source.getConnectChoice()); - setHasEverConnected(source.getHasEverConnected()); + setHasEverConnected(source.hasEverConnected()); } /** @hide */ @@ -1900,7 +1900,7 @@ public class WifiConfiguration implements Parcelable { } else { dest.writeInt(CONNECT_CHOICE_NOT_EXISTS); } - dest.writeInt(getHasEverConnected() ? 1 : 0); + dest.writeInt(hasEverConnected() ? 1 : 0); } /** @hide */ @@ -2142,7 +2142,7 @@ public class WifiConfiguration implements Parcelable { sbuf.append(" connect choice: ").append(mNetworkSelectionStatus.getConnectChoice()); } sbuf.append(" hasEverConnected: ") - .append(mNetworkSelectionStatus.getHasEverConnected()).append("\n"); + .append(mNetworkSelectionStatus.hasEverConnected()).append("\n"); if (this.numAssociation > 0) { sbuf.append(" numAssociation ").append(this.numAssociation).append("\n"); -- cgit v1.2.3 From 6b3e3cb4c83ef84a7f859145f1086d29e85413d4 Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 30 Jan 2020 17:57:22 -0800 Subject: Rename NetworkSelectionStatus.NETWORK_SELECTION_ENABLE Renamed to DISABLED_NONE to be consistent with the other DISABLE_* constants. Bug: 146046526 Test: compiles Change-Id: Ic1aedf783e28ad773614dc879cf9d2d2393a28ed --- wifi/java/android/net/wifi/WifiConfiguration.java | 38 +++++++++++------------ 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index da304d4467b3..561354a799be 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -1251,8 +1251,8 @@ public class WifiConfiguration implements Parcelable { /** @hide */ @Retention(RetentionPolicy.SOURCE) - @IntDef(value = { - NETWORK_SELECTION_ENABLE, + @IntDef(prefix = "DISABLED_", value = { + DISABLED_NONE, DISABLED_ASSOCIATION_REJECTION, DISABLED_AUTHENTICATION_FAILURE, DISABLED_DHCP_FAILURE, @@ -1266,7 +1266,7 @@ public class WifiConfiguration implements Parcelable { // Quality Network disabled reasons /** Default value. Means not disabled. */ - public static final int NETWORK_SELECTION_ENABLE = 0; + public static final int DISABLED_NONE = 0; /** * The starting index for network selection disabled reasons. * @hide @@ -1355,7 +1355,7 @@ public class WifiConfiguration implements Parcelable { private static SparseArray buildDisableReasonInfos() { SparseArray reasons = new SparseArray<>(); - reasons.append(NETWORK_SELECTION_ENABLE, + reasons.append(DISABLED_NONE, new DisableReasonInfo( // Note that these strings are persisted in // XmlUtil.NetworkSelectionStatusXmlUtil#writeToXml, @@ -1649,7 +1649,7 @@ public class WifiConfiguration implements Parcelable { /** * * Set the current network's disable reason. - * One of the {@link #NETWORK_SELECTION_ENABLE} or DISABLED_* constants. + * One of the {@link #DISABLED_NONE} or DISABLED_* constants. * e.g. {@link #DISABLED_ASSOCIATION_REJECTION}. * @see NetworkSelectionStatus#getNetworkSelectionDisableReason() */ @@ -1673,7 +1673,7 @@ public class WifiConfiguration implements Parcelable { /** * Get the network disable reason string for a reason code (for debugging). - * @param reason specific error reason. One of the {@link #NETWORK_SELECTION_ENABLE} or + * @param reason specific error reason. One of the {@link #DISABLED_NONE} or * DISABLED_* constants e.g. {@link #DISABLED_ASSOCIATION_REJECTION}. * @return network disable reason string, or null if the reason is invalid. */ @@ -1739,7 +1739,7 @@ public class WifiConfiguration implements Parcelable { /** * Returns the current network's disable reason. - * One of the {@link #NETWORK_SELECTION_ENABLE} or DISABLED_* constants + * One of the {@link #DISABLED_NONE} or DISABLED_* constants * e.g. {@link #DISABLED_ASSOCIATION_REJECTION}. */ @NetworkSelectionDisableReason @@ -1779,13 +1779,13 @@ public class WifiConfiguration implements Parcelable { /** * Get the disable counter of a specific reason. - * @param reason specific failure reason. One of the {@link #NETWORK_SELECTION_ENABLE} or + * @param reason specific failure reason. One of the {@link #DISABLED_NONE} or * DISABLED_* constants e.g. {@link #DISABLED_ASSOCIATION_REJECTION}. * @exception IllegalArgumentException for invalid reason * @return counter number for specific error reason. */ public int getDisableReasonCounter(@NetworkSelectionDisableReason int reason) { - if (reason >= NETWORK_SELECTION_ENABLE && reason < NETWORK_SELECTION_DISABLED_MAX) { + if (reason >= DISABLED_NONE && reason < NETWORK_SELECTION_DISABLED_MAX) { return mNetworkSeclectionDisableCounter[reason]; } else { throw new IllegalArgumentException("Illegal reason value: " + reason); @@ -1800,7 +1800,7 @@ public class WifiConfiguration implements Parcelable { * @hide */ public void setDisableReasonCounter(int reason, int value) { - if (reason >= NETWORK_SELECTION_ENABLE && reason < NETWORK_SELECTION_DISABLED_MAX) { + if (reason >= DISABLED_NONE && reason < NETWORK_SELECTION_DISABLED_MAX) { mNetworkSeclectionDisableCounter[reason] = value; } else { throw new IllegalArgumentException("Illegal reason value: " + reason); @@ -1814,7 +1814,7 @@ public class WifiConfiguration implements Parcelable { * @hide */ public void incrementDisableReasonCounter(int reason) { - if (reason >= NETWORK_SELECTION_ENABLE && reason < NETWORK_SELECTION_DISABLED_MAX) { + if (reason >= DISABLED_NONE && reason < NETWORK_SELECTION_DISABLED_MAX) { mNetworkSeclectionDisableCounter[reason]++; } else { throw new IllegalArgumentException("Illegal reason value: " + reason); @@ -1828,8 +1828,8 @@ public class WifiConfiguration implements Parcelable { * @hide */ public void clearDisableReasonCounter(int reason) { - if (reason >= NETWORK_SELECTION_ENABLE && reason < NETWORK_SELECTION_DISABLED_MAX) { - mNetworkSeclectionDisableCounter[reason] = NETWORK_SELECTION_ENABLE; + if (reason >= DISABLED_NONE && reason < NETWORK_SELECTION_DISABLED_MAX) { + mNetworkSeclectionDisableCounter[reason] = DISABLED_NONE; } else { throw new IllegalArgumentException("Illegal reason value: " + reason); } @@ -1840,7 +1840,7 @@ public class WifiConfiguration implements Parcelable { * @hide */ public void clearDisableReasonCounter() { - Arrays.fill(mNetworkSeclectionDisableCounter, NETWORK_SELECTION_ENABLE); + Arrays.fill(mNetworkSeclectionDisableCounter, DISABLED_NONE); } /** @@ -1870,7 +1870,7 @@ public class WifiConfiguration implements Parcelable { public void copy(NetworkSelectionStatus source) { mStatus = source.mStatus; mNetworkSelectionDisableReason = source.mNetworkSelectionDisableReason; - for (int index = NETWORK_SELECTION_ENABLE; index < NETWORK_SELECTION_DISABLED_MAX; + for (int index = DISABLED_NONE; index < NETWORK_SELECTION_DISABLED_MAX; index++) { mNetworkSeclectionDisableCounter[index] = source.mNetworkSeclectionDisableCounter[index]; @@ -1888,7 +1888,7 @@ public class WifiConfiguration implements Parcelable { public void writeToParcel(Parcel dest) { dest.writeInt(getNetworkSelectionStatus()); dest.writeInt(getNetworkSelectionDisableReason()); - for (int index = NETWORK_SELECTION_ENABLE; index < NETWORK_SELECTION_DISABLED_MAX; + for (int index = DISABLED_NONE; index < NETWORK_SELECTION_DISABLED_MAX; index++) { dest.writeInt(getDisableReasonCounter(index)); } @@ -1907,7 +1907,7 @@ public class WifiConfiguration implements Parcelable { public void readFromParcel(Parcel in) { setNetworkSelectionStatus(in.readInt()); setNetworkSelectionDisableReason(in.readInt()); - for (int index = NETWORK_SELECTION_ENABLE; index < NETWORK_SELECTION_DISABLED_MAX; + for (int index = DISABLED_NONE; index < NETWORK_SELECTION_DISABLED_MAX; index++) { setDisableReasonCounter(index, in.readInt()); } @@ -2129,8 +2129,8 @@ public class WifiConfiguration implements Parcelable { sbuf.append(" mNetworkSelectionDisableReason ") .append(mNetworkSelectionStatus.getNetworkDisableReasonString() + "\n"); - for (int index = mNetworkSelectionStatus.NETWORK_SELECTION_ENABLE; - index < mNetworkSelectionStatus.NETWORK_SELECTION_DISABLED_MAX; index++) { + for (int index = NetworkSelectionStatus.DISABLED_NONE; + index < NetworkSelectionStatus.NETWORK_SELECTION_DISABLED_MAX; index++) { if (mNetworkSelectionStatus.getDisableReasonCounter(index) != 0) { sbuf.append(NetworkSelectionStatus.getNetworkDisableReasonString(index) + " counter:" + mNetworkSelectionStatus.getDisableReasonCounter(index) -- cgit v1.2.3 From d5f4d2a65c8a4a8cfb9a86aedba7c5804ed07c92 Mon Sep 17 00:00:00 2001 From: Mingguang Xu Date: Fri, 31 Jan 2020 00:22:35 -0800 Subject: Extension API: Use NetworkScore object in API surface Test: atest android.net.wifi Bug: 135573686, 122133502, 136312816, 135572156 Change-Id: I499cc1294164edf40510013226b35029ec52dd3c Signed-off-by: Mingguang Xu --- wifi/java/android/net/wifi/IScoreChangeCallback.aidl | 4 +++- wifi/java/android/net/wifi/WifiManager.java | 12 +++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IScoreChangeCallback.aidl b/wifi/java/android/net/wifi/IScoreChangeCallback.aidl index fd236107bc6e..462a97844d76 100644 --- a/wifi/java/android/net/wifi/IScoreChangeCallback.aidl +++ b/wifi/java/android/net/wifi/IScoreChangeCallback.aidl @@ -16,6 +16,8 @@ package android.net.wifi; +import android.net.NetworkScore; + /** * Interface for Wi-Fi network score callback. * @@ -23,7 +25,7 @@ package android.net.wifi; */ oneway interface IScoreChangeCallback { - void onStatusChange(int sessionId, boolean exiting); + void onScoreChange(int sessionId, in NetworkScore score); void onTriggerUpdateOfWifiUsabilityStats(int sessionId); } diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 76f97164032c..da521ed4d8a1 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -38,6 +38,7 @@ import android.net.ConnectivityManager; import android.net.DhcpInfo; import android.net.MacAddress; import android.net.Network; +import android.net.NetworkScore; import android.net.NetworkStack; import android.net.wifi.hotspot2.IProvisioningCallback; import android.net.wifi.hotspot2.OsuProvider; @@ -5948,10 +5949,11 @@ public class WifiManager { * * @param sessionId The ID to indicate current Wi-Fi network connection obtained from * {@link WifiConnectedNetworkScorer#start(int)}. - * @param isUsable The bit to indicate whether current Wi-Fi network is usable or not. - * Populated by connected network scorer in applications. + * @param score The {@link android.net.NetworkScore} object representing the + * characteristics of current Wi-Fi network. Populated by connected network + * scorer in applications. */ - void onStatusChange(int sessionId, boolean isUsable); + void onScoreChange(int sessionId, @NonNull NetworkScore score); /** * Called by applications to trigger an update of {@link WifiUsabilityStatsEntry}. @@ -5977,9 +5979,9 @@ public class WifiManager { } @Override - public void onStatusChange(int sessionId, boolean isUsable) { + public void onScoreChange(int sessionId, @NonNull NetworkScore score) { try { - mScoreChangeCallback.onStatusChange(sessionId, isUsable); + mScoreChangeCallback.onScoreChange(sessionId, score); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } -- cgit v1.2.3 From 387452ab516a8ee7081f90e1269199d029924849 Mon Sep 17 00:00:00 2001 From: Ahmed ElArabawy Date: Fri, 31 Jan 2020 16:18:12 -0800 Subject: Wifi: Improve documentation to setScanningEnabled This commit improves documentation to WifiScanner#setScanningEnabled() A reference to the intent ACTION_WIFI_SCAN_AVAILABLE is added. Bug: 147804434 Test: No test is done. Change-Id: I91f4555cb9054ba60590bb06bb0bc5c00584eb90 --- wifi/java/android/net/wifi/WifiScanner.java | 2 ++ 1 file changed, 2 insertions(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index 6f01350d8af4..8250a95c97a9 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -836,6 +836,8 @@ public class WifiScanner { * Enable/Disable wifi scanning. * * @param enable set to true to enable scanning, set to false to disable all types of scanning. + * + * @see WifiManager#ACTION_WIFI_SCAN_AVAILABLE * {@hide} */ @SystemApi -- cgit v1.2.3 From 77eecbc89ccaf47f50ead0d6f0d3448636049dad Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Mon, 3 Feb 2020 14:59:58 +0800 Subject: Wifi: revise javadoc of constants Bug: 148107493 Test: N/A Change-Id: I8b09712b82461a3f7b7fdff6c38fe64e97dcc5a5 --- wifi/java/android/net/wifi/WifiEnterpriseConfig.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java index 04016b606b96..db0d36e5c086 100644 --- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java +++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java @@ -60,13 +60,13 @@ public class WifiEnterpriseConfig implements Parcelable { "android.net.wifi.extra.WAPI_AS_CERTIFICATE_DATA"; /** - * Intent extra: name for WAPI AS certificates + * Intent extra: name for WAPI USER certificates */ public static final String EXTRA_WAPI_USER_CERTIFICATE_NAME = "android.net.wifi.extra.WAPI_USER_CERTIFICATE_NAME"; /** - * Intent extra: data for WAPI AS certificates + * Intent extra: data for WAPI USER certificates */ public static final String EXTRA_WAPI_USER_CERTIFICATE_DATA = "android.net.wifi.extra.WAPI_USER_CERTIFICATE_DATA"; -- cgit v1.2.3 From 762a9e3a2a39618376999d9929f16f4c456e1d2a Mon Sep 17 00:00:00 2001 From: David Su Date: Wed, 29 Jan 2020 17:51:13 -0800 Subject: WifiConfiguration: Remove IpConfiguration helpers e.g. WifiConfiguration.getProxySettings() can simply be replaced with WifiConfiguration .getIpConfiguration().getProxySettings(). There is no need for WifiConfiguration to expose these APIs. Bug: 146046526 Test: atest FrameworksWifiApiTests Change-Id: I75eee369f2bfea7bd09e665b40d26452c142a8a5 --- wifi/java/android/net/wifi/WifiConfiguration.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 8d95cb010856..d416091ee897 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -2533,7 +2533,7 @@ public class WifiConfiguration implements Parcelable { * @hide */ @Nullable - @SystemApi + @UnsupportedAppUsage public StaticIpConfiguration getStaticIpConfiguration() { return mIpConfiguration.getStaticIpConfiguration(); } @@ -2549,7 +2549,7 @@ public class WifiConfiguration implements Parcelable { * @hide */ @NonNull - @SystemApi + @UnsupportedAppUsage public IpConfiguration.IpAssignment getIpAssignment() { return mIpConfiguration.getIpAssignment(); } @@ -2565,7 +2565,7 @@ public class WifiConfiguration implements Parcelable { * @hide */ @NonNull - @SystemApi + @UnsupportedAppUsage public IpConfiguration.ProxySettings getProxySettings() { return mIpConfiguration.getProxySettings(); } @@ -2628,7 +2628,7 @@ public class WifiConfiguration implements Parcelable { * Set the {@link ProxySettings} and {@link ProxyInfo} for this network. * @hide */ - @SystemApi + @UnsupportedAppUsage public void setProxy(@NonNull ProxySettings settings, @NonNull ProxyInfo proxy) { mIpConfiguration.setProxySettings(settings); mIpConfiguration.setHttpProxy(proxy); -- cgit v1.2.3 From a6528df850b3445947b9c8e08444c536236632b2 Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Mon, 3 Feb 2020 11:37:00 -0800 Subject: [WIFICOND][API] Expose public constructor for data classes. To help with testing. Per API council feedback. Bug: 148680192 Test: atest android.net.wifi.wificond Change-Id: I2902ff1f9a29f174be8fafac63e935631c7c5786 --- wifi/java/android/net/wifi/wificond/NativeScanResult.java | 2 +- wifi/java/android/net/wifi/wificond/NativeWifiClient.java | 3 +-- wifi/java/android/net/wifi/wificond/RadioChainInfo.java | 4 +++- 3 files changed, 5 insertions(+), 4 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/wificond/NativeScanResult.java b/wifi/java/android/net/wifi/wificond/NativeScanResult.java index 6ed17081bdb5..85251e8b1d42 100644 --- a/wifi/java/android/net/wifi/wificond/NativeScanResult.java +++ b/wifi/java/android/net/wifi/wificond/NativeScanResult.java @@ -169,7 +169,7 @@ public final class NativeScanResult implements Parcelable { } /** - * @hide + * Construct an empty native scan result. */ public NativeScanResult() { } diff --git a/wifi/java/android/net/wifi/wificond/NativeWifiClient.java b/wifi/java/android/net/wifi/wificond/NativeWifiClient.java index 554f9295ef0d..916c11579075 100644 --- a/wifi/java/android/net/wifi/wificond/NativeWifiClient.java +++ b/wifi/java/android/net/wifi/wificond/NativeWifiClient.java @@ -36,8 +36,7 @@ public final class NativeWifiClient implements Parcelable { @NonNull public final byte[] macAddress; /** - * public constructor - * @hide + * Construct a native Wi-Fi client. */ public NativeWifiClient(@NonNull byte[] macAddress) { this.macAddress = macAddress; diff --git a/wifi/java/android/net/wifi/wificond/RadioChainInfo.java b/wifi/java/android/net/wifi/wificond/RadioChainInfo.java index 64102dde94c0..97c0ee9d1c2c 100644 --- a/wifi/java/android/net/wifi/wificond/RadioChainInfo.java +++ b/wifi/java/android/net/wifi/wificond/RadioChainInfo.java @@ -61,7 +61,9 @@ public final class RadioChainInfo implements Parcelable { return level; } - /** @hide */ + /** + * Construct a RadioChainInfo. + */ public RadioChainInfo(int chainId, int level) { this.chainId = chainId; this.level = level; -- cgit v1.2.3 From f842ef2fe68c4e89299a2081b3796929f84d2443 Mon Sep 17 00:00:00 2001 From: David Su Date: Mon, 3 Feb 2020 14:36:45 -0800 Subject: Rename WifiManager.ACTION_WIFI_SCAN_AVAILABLE Renamed to WIFI_SCAN_AVAILABILITY_CHANGED to conform to API guidelines. Bug: 148781526 Test: compiles Change-Id: Ifa00f84bbeda9cfe34c442f6d906f757ec9ff51f --- wifi/java/android/net/wifi/WifiManager.java | 6 +++--- wifi/java/android/net/wifi/WifiScanner.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 76f97164032c..b242186de036 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -256,12 +256,12 @@ public class WifiManager { * - {@link #EXTRA_SCAN_AVAILABLE} */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String ACTION_WIFI_SCAN_AVAILABLE = - "android.net.wifi.action.WIFI_SCAN_AVAILABLE"; + public static final String ACTION_WIFI_SCAN_AVAILABILITY_CHANGED = + "android.net.wifi.action.WIFI_SCAN_AVAILABILITY_CHANGED"; /** * A boolean extra indicating whether scanning is currently available. - * Sent in the broadcast {@link #ACTION_WIFI_SCAN_AVAILABLE}. + * Sent in the broadcast {@link #ACTION_WIFI_SCAN_AVAILABILITY_CHANGED}. * Its value is true if scanning is currently available, false otherwise. */ public static final String EXTRA_SCAN_AVAILABLE = "android.net.wifi.extra.SCAN_AVAILABLE"; diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index 8250a95c97a9..a85f40b3c1b8 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -837,7 +837,7 @@ public class WifiScanner { * * @param enable set to true to enable scanning, set to false to disable all types of scanning. * - * @see WifiManager#ACTION_WIFI_SCAN_AVAILABLE + * @see WifiManager#ACTION_WIFI_SCAN_AVAILABILITY_CHANGED * {@hide} */ @SystemApi -- cgit v1.2.3 From 0e46cc88cd9b126d6a5c1156744bf027d85829f1 Mon Sep 17 00:00:00 2001 From: "Nate(Qiang) Jiang" Date: Mon, 3 Feb 2020 11:32:42 -0800 Subject: Make autojoin consistent Bug: 148780003 Test: atest android.net.wifi Change-Id: I6aef43fa9df6787a61f0c150be7910cabef47d31 --- wifi/java/android/net/wifi/WifiManager.java | 22 ++++++++++---------- .../android/net/wifi/WifiNetworkSuggestion.java | 18 ++++++++-------- .../net/wifi/hotspot2/PasspointConfiguration.java | 24 +++++++++++----------- .../net/wifi/WifiNetworkSuggestionTest.java | 16 +++++++-------- .../wifi/hotspot2/PasspointConfigurationTest.java | 2 +- 5 files changed, 41 insertions(+), 41 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 76f97164032c..09dc17140044 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -4308,16 +4308,16 @@ public class WifiManager { } /** - * Allows the OEM to enable/disable auto-join globally. + * Enable/disable auto-join globally. * - * @param choice true to allow autojoin, false to disallow autojoin + * @param allowAutojoin true to allow auto-join, false to disallow auto-join * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - public void allowAutojoinGlobal(boolean choice) { + public void allowAutojoinGlobal(boolean allowAutojoin) { try { - mService.allowAutojoinGlobal(choice); + mService.allowAutojoinGlobal(allowAutojoin); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4329,15 +4329,15 @@ public class WifiManager { * The updated choice will be made available through the updated config supplied by the * CONFIGURED_NETWORKS_CHANGED broadcast. * - * @param netId the id of the network to allow/disallow autojoin for. - * @param choice true to allow autojoin, false to disallow autojoin + * @param netId the id of the network to allow/disallow auto-join for. + * @param allowAutojoin true to allow auto-join, false to disallow auto-join * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - public void allowAutojoin(int netId, boolean choice) { + public void allowAutojoin(int netId, boolean allowAutojoin) { try { - mService.allowAutojoin(netId, choice); + mService.allowAutojoin(netId, allowAutojoin); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4347,14 +4347,14 @@ public class WifiManager { * Configure auto-join settings for a Passpoint profile. * * @param fqdn the FQDN (fully qualified domain name) of the passpoint profile. - * @param enableAutoJoin true to enable autojoin, false to disable autojoin. + * @param allowAutojoin true to enable auto-join, false to disable auto-join. * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - public void allowAutojoinPasspoint(@NonNull String fqdn, boolean enableAutoJoin) { + public void allowAutojoinPasspoint(@NonNull String fqdn, boolean allowAutojoin) { try { - mService.allowAutojoinPasspoint(fqdn, enableAutoJoin); + mService.allowAutojoinPasspoint(fqdn, allowAutojoin); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java index 6085eae252ef..720149695abc 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java +++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java @@ -126,7 +126,7 @@ public final class WifiNetworkSuggestion implements Parcelable { /** * Whether this network is initialized with auto-join enabled (the default) or not. */ - private boolean mIsInitialAutoJoinEnabled; + private boolean mIsInitialAutojoinEnabled; /** * Pre-shared key for use with WAPI-PSK networks. @@ -159,7 +159,7 @@ public final class WifiNetworkSuggestion implements Parcelable { mIsMetered = false; mIsSharedWithUser = true; mIsSharedWithUserSet = false; - mIsInitialAutoJoinEnabled = true; + mIsInitialAutojoinEnabled = true; mPriority = UNASSIGNED_PRIORITY; mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID; mWapiPskPassphrase = null; @@ -467,10 +467,10 @@ public final class WifiNetworkSuggestion implements Parcelable { * * @param enabled true for initializing with auto-join enabled (the default), false to * initializing with auto-join disabled. - * @return Instance of (@link {@link Builder} to enable chaining of the builder method. + * @return Instance of {@link Builder} to enable chaining of the builder method. */ - public @NonNull Builder setIsInitialAutoJoinEnabled(boolean enabled) { - mIsInitialAutoJoinEnabled = enabled; + public @NonNull Builder setIsInitialAutojoinEnabled(boolean enabled) { + mIsInitialAutojoinEnabled = enabled; return this; } @@ -664,10 +664,10 @@ public final class WifiNetworkSuggestion implements Parcelable { mIsSharedWithUser = false; } } - if (!mIsSharedWithUser && !mIsInitialAutoJoinEnabled) { + if (!mIsSharedWithUser && !mIsInitialAutojoinEnabled) { throw new IllegalStateException("Should have not a network with both " + "setCredentialSharedWithUser and " - + "setIsAutoJoinEnabled set to false"); + + "setIsAutojoinEnabled set to false"); } if (mIsNetworkUntrusted) { if (mIsSharedWithUserSet && mIsSharedWithUser) { @@ -683,7 +683,7 @@ public final class WifiNetworkSuggestion implements Parcelable { mIsAppInteractionRequired, mIsUserInteractionRequired, mIsSharedWithUser, - mIsInitialAutoJoinEnabled, + mIsInitialAutojoinEnabled, mIsNetworkUntrusted); } } @@ -774,7 +774,7 @@ public final class WifiNetworkSuggestion implements Parcelable { in.readBoolean(), // isAppInteractionRequired in.readBoolean(), // isUserInteractionRequired in.readBoolean(), // isSharedCredentialWithUser - in.readBoolean(), // isAutoJoinEnabled + in.readBoolean(), // isAutojoinEnabled in.readBoolean() ); } diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java index 756d679b8f21..615331f65258 100644 --- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java +++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java @@ -432,7 +432,7 @@ public final class PasspointConfiguration implements Parcelable { * considered for auto-connection. If true then yes, if false then it isn't considered as part * of auto-connection - but can still be manually connected to. */ - private boolean mIsAutoJoinEnabled = true; + private boolean mIsAutojoinEnabled = true; /** * The mac randomization setting specifies whether a randomized or device MAC address will @@ -459,11 +459,11 @@ public final class PasspointConfiguration implements Parcelable { * indicates that only manual connection will work - the framework will not auto-associate to * this Passpoint network. * - * @param autoJoinEnabled true to be considered for framework auto-connection, false otherwise. + * @param autojoinEnabled true to be considered for framework auto-connection, false otherwise. * @hide */ - public void setAutoJoinEnabled(boolean autoJoinEnabled) { - mIsAutoJoinEnabled = autoJoinEnabled; + public void setAutojoinEnabled(boolean autojoinEnabled) { + mIsAutojoinEnabled = autojoinEnabled; } /** @@ -499,8 +499,8 @@ public final class PasspointConfiguration implements Parcelable { * @hide */ @SystemApi - public boolean isAutoJoinEnabled() { - return mIsAutoJoinEnabled; + public boolean isAutojoinEnabled() { + return mIsAutojoinEnabled; } /** @@ -570,7 +570,7 @@ public final class PasspointConfiguration implements Parcelable { mServiceFriendlyNames = source.mServiceFriendlyNames; mAaaServerTrustedNames = source.mAaaServerTrustedNames; mCarrierId = source.mCarrierId; - mIsAutoJoinEnabled = source.mIsAutoJoinEnabled; + mIsAutojoinEnabled = source.mIsAutojoinEnabled; mIsMacRandomizationEnabled = source.mIsMacRandomizationEnabled; mMeteredOverride = source.mMeteredOverride; } @@ -602,7 +602,7 @@ public final class PasspointConfiguration implements Parcelable { (HashMap) mServiceFriendlyNames); dest.writeBundle(bundle); dest.writeInt(mCarrierId); - dest.writeBoolean(mIsAutoJoinEnabled); + dest.writeBoolean(mIsAutojoinEnabled); dest.writeBoolean(mIsMacRandomizationEnabled); dest.writeInt(mMeteredOverride); } @@ -635,7 +635,7 @@ public final class PasspointConfiguration implements Parcelable { && mUsageLimitDataLimit == that.mUsageLimitDataLimit && mUsageLimitTimeLimitInMinutes == that.mUsageLimitTimeLimitInMinutes && mCarrierId == that.mCarrierId - && mIsAutoJoinEnabled == that.mIsAutoJoinEnabled + && mIsAutojoinEnabled == that.mIsAutojoinEnabled && mIsMacRandomizationEnabled == that.mIsMacRandomizationEnabled && mMeteredOverride == that.mMeteredOverride && (mServiceFriendlyNames == null ? that.mServiceFriendlyNames == null @@ -648,7 +648,7 @@ public final class PasspointConfiguration implements Parcelable { mUpdateIdentifier, mCredentialPriority, mSubscriptionCreationTimeInMillis, mSubscriptionExpirationTimeInMillis, mUsageLimitUsageTimePeriodInMinutes, mUsageLimitStartTimeInMillis, mUsageLimitDataLimit, mUsageLimitTimeLimitInMinutes, - mServiceFriendlyNames, mCarrierId, mIsAutoJoinEnabled, mIsMacRandomizationEnabled, + mServiceFriendlyNames, mCarrierId, mIsAutojoinEnabled, mIsMacRandomizationEnabled, mMeteredOverride); } @@ -703,7 +703,7 @@ public final class PasspointConfiguration implements Parcelable { builder.append("ServiceFriendlyNames: ").append(mServiceFriendlyNames); } builder.append("CarrierId:" + mCarrierId); - builder.append("IsAutoJoinEnabled:" + mIsAutoJoinEnabled); + builder.append("IsAutojoinEnabled:" + mIsAutojoinEnabled); builder.append("mIsMacRandomizationEnabled:" + mIsMacRandomizationEnabled); builder.append("mMeteredOverride:" + mMeteredOverride); return builder.toString(); @@ -811,7 +811,7 @@ public final class PasspointConfiguration implements Parcelable { "serviceFriendlyNames"); config.setServiceFriendlyNames(friendlyNamesMap); config.mCarrierId = in.readInt(); - config.mIsAutoJoinEnabled = in.readBoolean(); + config.mIsAutojoinEnabled = in.readBoolean(); config.mIsMacRandomizationEnabled = in.readBoolean(); config.mMeteredOverride = in.readInt(); return config; diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java index 15accc337429..af6fb5c1cd22 100644 --- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java +++ b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java @@ -105,7 +105,7 @@ public class WifiNetworkSuggestionTest { .setSsid(TEST_SSID) .setWpa2Passphrase(TEST_PRESHARED_KEY) .setIsUserInteractionRequired(true) - .setIsInitialAutoJoinEnabled(false) + .setIsInitialAutojoinEnabled(false) .setIsMetered(true) .build(); @@ -155,7 +155,7 @@ public class WifiNetworkSuggestionTest { .setSsid(TEST_SSID) .setWpa3Passphrase(TEST_PRESHARED_KEY) .setCredentialSharedWithUser(true) - .setIsInitialAutoJoinEnabled(false) + .setIsInitialAutojoinEnabled(false) .build(); assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID); @@ -732,20 +732,20 @@ public class WifiNetworkSuggestionTest { /** * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception - * when {@link WifiNetworkSuggestion.Builder#setIsInitialAutoJoinEnabled(boolean)} to + * when {@link WifiNetworkSuggestion.Builder#setIsInitialAutojoinEnabled(boolean)} to * false on a open network suggestion. */ @Test(expected = IllegalStateException.class) public void testSetIsAutoJoinDisabledWithOpenNetwork() { new WifiNetworkSuggestion.Builder() .setSsid(TEST_SSID) - .setIsInitialAutoJoinEnabled(false) + .setIsInitialAutojoinEnabled(false) .build(); } /** * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception - * when set both {@link WifiNetworkSuggestion.Builder#setIsInitialAutoJoinEnabled(boolean)} + * when set both {@link WifiNetworkSuggestion.Builder#setIsInitialAutojoinEnabled(boolean)} * and {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} (boolean)} * to false on a network suggestion. */ @@ -755,7 +755,7 @@ public class WifiNetworkSuggestionTest { .setSsid(TEST_SSID) .setWpa2Passphrase(TEST_PRESHARED_KEY) .setCredentialSharedWithUser(false) - .setIsInitialAutoJoinEnabled(false) + .setIsInitialAutojoinEnabled(false) .build(); } @@ -808,7 +808,7 @@ public class WifiNetworkSuggestionTest { /** * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception - * when set both {@link WifiNetworkSuggestion.Builder#setIsInitialAutoJoinEnabled(boolean)} + * when set both {@link WifiNetworkSuggestion.Builder#setIsInitialAutojoinEnabled(boolean)} * and {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} (boolean)} * to false on a passpoint suggestion. */ @@ -818,7 +818,7 @@ public class WifiNetworkSuggestionTest { new WifiNetworkSuggestion.Builder() .setPasspointConfig(passpointConfiguration) .setCredentialSharedWithUser(false) - .setIsInitialAutoJoinEnabled(false) + .setIsInitialAutojoinEnabled(false) .build(); } } diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java index e78c5bf992f3..ce542c2bc4e9 100644 --- a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java @@ -174,7 +174,7 @@ public class PasspointConfigurationTest { assertFalse(config.validate()); assertFalse(config.validateForR2()); - assertTrue(config.isAutoJoinEnabled()); + assertTrue(config.isAutojoinEnabled()); assertTrue(config.isMacRandomizationEnabled()); assertTrue(config.getMeteredOverride() == METERED_OVERRIDE_NONE); } -- cgit v1.2.3 From 859331aa11d978c3935ceb955922029e11686df4 Mon Sep 17 00:00:00 2001 From: David Su Date: Mon, 3 Feb 2020 16:57:42 -0800 Subject: Register RttManager correctly RttManager is an exception in that the service name (Context.WIFI_RTT_SERVICE) it is published under is different from its binder name (Context.WIFI_RTT_RANGING_SERVICE). When `SystemServiceRegistry.registerContextAwareService()` tries to get the binder of Context.WIFI_RTT_SERVICE, it won't find anything since there is no binder published under that name. Thus, the registration will fail. Instead, delegate RttManager construction to WifiRttManager construction. Bug: 148817663 Test: atest android.net.wifi.rtt.cts.WifiRttTest Change-Id: I94e505583689f3fd3836dba2f7feb0e7f0ab1378 --- .../java/android/net/wifi/WifiFrameworkInitializer.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiFrameworkInitializer.java b/wifi/java/android/net/wifi/WifiFrameworkInitializer.java index 002820b1bcc8..1507199b0264 100644 --- a/wifi/java/android/net/wifi/WifiFrameworkInitializer.java +++ b/wifi/java/android/net/wifi/WifiFrameworkInitializer.java @@ -101,15 +101,6 @@ public class WifiFrameworkInitializer { return new WifiScanner(context, service, getInstanceLooper()); } ); - SystemServiceRegistry.registerContextAwareService( - Context.WIFI_RTT_SERVICE, - RttManager.class, - (context, serviceBinder) -> { - IWifiRttManager service = IWifiRttManager.Stub.asInterface(serviceBinder); - WifiRttManager wifiRttManager = new WifiRttManager(context, service); - return new RttManager(context, wifiRttManager); - } - ); SystemServiceRegistry.registerContextAwareService( Context.WIFI_RTT_RANGING_SERVICE, WifiRttManager.class, @@ -118,5 +109,13 @@ public class WifiFrameworkInitializer { return new WifiRttManager(context, service); } ); + SystemServiceRegistry.registerContextAwareService( + Context.WIFI_RTT_SERVICE, + RttManager.class, + context -> { + WifiRttManager wifiRttManager = context.getSystemService(WifiRttManager.class); + return new RttManager(context, wifiRttManager); + } + ); } } -- cgit v1.2.3 From 98b1d8d5a25249b64432746b18e40b084201cef8 Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Mon, 3 Feb 2020 18:06:25 -0800 Subject: [WIFICOND][API] Update channel API from array to list Per API council feedback. Bug: 148680192 Test: atest android.net.wifi Change-Id: I3a6230eee6fbace68df8b67fb3fa64e299152d40 --- .../android/net/wifi/wificond/WifiCondManager.java | 17 +++++----- .../net/wifi/wificond/WifiCondManagerTest.java | 36 +++++++++++++++++++++- 2 files changed, 45 insertions(+), 8 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/wificond/WifiCondManager.java b/wifi/java/android/net/wifi/wificond/WifiCondManager.java index 4847640b1418..43aa1b64efbc 100644 --- a/wifi/java/android/net/wifi/wificond/WifiCondManager.java +++ b/wifi/java/android/net/wifi/wificond/WifiCondManager.java @@ -41,16 +41,19 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.stream.Collectors; /** - * This class encapsulates the interface the wificond daemon presents to the Wi-Fi framework. The - * interface is only for use by the Wi-Fi framework and access is protected by SELinux permissions. + * This class encapsulates the interface the wificond (Wi-Fi Conductor) daemon presents to the + * Wi-Fi framework. The interface is only for use by the Wi-Fi framework and access is protected + * by SELinux permissions: only the system server and wpa_supplicant can use WifiCondManager. * * @hide */ @@ -1011,13 +1014,13 @@ public class WifiCondManager { * WifiScanner.WIFI_BAND_5_GHZ * WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY * WifiScanner.WIFI_BAND_6_GHZ - * @return frequencies vector of valid frequencies (MHz), or an empty array for error. + * @return frequencies List of valid frequencies (MHz), or an empty list for error. * @throws IllegalArgumentException if band is not recognized. */ - public @NonNull int[] getChannelsMhzForBand(@WifiAnnotations.WifiBandBasic int band) { + public @NonNull List getChannelsMhzForBand(@WifiAnnotations.WifiBandBasic int band) { if (mWificond == null) { Log.e(TAG, "No valid wificond scanner interface handler"); - return new int[0]; + return Collections.emptyList(); } int[] result = null; try { @@ -1041,9 +1044,9 @@ public class WifiCondManager { Log.e(TAG, "Failed to request getChannelsForBand due to remote exception"); } if (result == null) { - result = new int[0]; + return Collections.emptyList(); } - return result; + return Arrays.stream(result).boxed().collect(Collectors.toList()); } /** Helper function to look up the interface handle using name */ diff --git a/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java b/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java index f262268d7179..5ba02a779663 100644 --- a/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java +++ b/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java @@ -65,6 +65,8 @@ import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -741,10 +743,42 @@ public class WifiCondManagerTest { verify(deathHandler).run(); // The handles should be cleared after death. - assertEquals(0, mWificondControl.getChannelsMhzForBand(WifiScanner.WIFI_BAND_5_GHZ).length); + assertEquals(0, mWificondControl.getChannelsMhzForBand(WifiScanner.WIFI_BAND_5_GHZ).size()); verify(mWificond, never()).getAvailable5gNonDFSChannels(); } + /** + * Verify primitive array to list translation of channel API. + */ + @Test + public void testGetChannels() throws Exception { + int[] resultsEmpty = new int[0]; + int[] resultsSingle = new int[]{100}; + int[] resultsMore = new int[]{100, 200}; + + List emptyList = Collections.emptyList(); + List singleList = Arrays.asList(100); + List moreList = Arrays.asList(100, 200); + + when(mWificond.getAvailable2gChannels()).thenReturn(null); + assertEquals(mWificondControl.getChannelsMhzForBand(WifiScanner.WIFI_BAND_24_GHZ), + emptyList); + assertEquals(mWificondControl.getChannelsMhzForBand(WifiScanner.WIFI_BAND_5_GHZ), + emptyList); + + when(mWificond.getAvailable2gChannels()).thenReturn(resultsEmpty); + assertEquals(mWificondControl.getChannelsMhzForBand(WifiScanner.WIFI_BAND_24_GHZ), + emptyList); + + when(mWificond.getAvailable2gChannels()).thenReturn(resultsSingle); + assertEquals(mWificondControl.getChannelsMhzForBand(WifiScanner.WIFI_BAND_24_GHZ), + singleList); + + when(mWificond.getAvailable2gChannels()).thenReturn(resultsMore); + assertEquals(mWificondControl.getChannelsMhzForBand(WifiScanner.WIFI_BAND_24_GHZ), + moreList); + } + /** * sendMgmtFrame() should fail if a null callback is passed in. */ -- cgit v1.2.3 From 722a3606096055ba1c107a1a3efd126380c9ce87 Mon Sep 17 00:00:00 2001 From: Anton Hansson Date: Mon, 3 Feb 2020 16:55:24 +0000 Subject: Create all variants of stubs for wifi Add separate publicapi, systemapi and module_libs stubs for wifi, and use a naming scheme consistent with other modules. Bug: 147768409 Test: m Test: m framework-wifi-stubs-{public,system,module_libs_}api Change-Id: I8b606c440f76349f2406b72c23e3f67b6378d385 --- wifi/Android.bp | 69 ++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 56 insertions(+), 13 deletions(-) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index dae04c6c3a25..e55971ef8f72 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -132,27 +132,70 @@ java_library { ], } -droidstubs { - name: "framework-wifi-stubs-srcs", - srcs: [ - ":framework-annotations", - ":framework-wifi-updatable-sources", - ], +stubs_defaults { + name: "framework-wifi-stubs-srcs-defaults", // This is needed as IOnWifiActivityEnergyInfoListener.aidl in framework-wifi depends on // WifiActivityEnergyInfo.aidl in framework-minus-apex aidl: { include_dirs: ["frameworks/base/core/java"], }, - defaults: [ "framework-module-stubs-defaults-systemapi" ], - sdk_version: "core_current", - libs: ["android_system_stubs_current"], + srcs: [ ":framework-wifi-updatable-sources" ], + libs: [ "framework-annotations-lib" ], + sdk_version: "system_current", +} + +droidstubs { + name: "framework-wifi-stubs-srcs-publicapi", + defaults: [ + "framework-module-stubs-defaults-publicapi", + "framework-wifi-stubs-srcs-defaults", + ], +} + +droidstubs { + name: "framework-wifi-stubs-srcs-systemapi", + defaults: [ + "framework-module-stubs-defaults-systemapi", + "framework-wifi-stubs-srcs-defaults", + ], +} + +droidstubs { + name: "framework-wifi-api-module_libs_api", + defaults: [ + "framework-module-api-defaults-module_libs_api", + "framework-wifi-stubs-srcs-defaults", + ], +} + +droidstubs { + name: "framework-wifi-stubs-srcs-module_libs_api", + defaults: [ + "framework-module-stubs-defaults-module_libs_api", + "framework-wifi-stubs-srcs-defaults", + ], } java_library { - name: "framework-wifi-stubs", - srcs: [":framework-wifi-stubs-srcs"], - sdk_version: "core_current", - libs: ["android_system_stubs_current"], + name: "framework-wifi-stubs-publicapi", + srcs: [":framework-wifi-stubs-srcs-publicapi"], + sdk_version: "current", + installable: false, +} + +java_library { + name: "framework-wifi-stubs-systemapi", + srcs: [":framework-wifi-stubs-srcs-systemapi"], + sdk_version: "system_current", + libs: ["framework-annotations-lib"], + installable: false, +} + +java_library { + name: "framework-wifi-stubs-module_libs_api", + srcs: [":framework-wifi-stubs-srcs-module_libs_api"], + sdk_version: "system_current", + libs: ["framework-annotations-lib"], installable: false, } -- cgit v1.2.3 From fd5cbd6523c643708815f9dcf9bfc2ccb1267fbd Mon Sep 17 00:00:00 2001 From: David Su Date: Tue, 28 Jan 2020 15:17:39 -0800 Subject: WifiConfiguration: unmark apBand as @SystemApi SoftApConfiguration is the new official API for storing Soft AP configurations. Thus, remove @SystemApi for WifiConfiguration#apBand. Bug: 148424108 Bug: 146046526 Test: compiles Change-Id: I39d2a664ac336998322b63a64e174d6802b1ac54 --- wifi/java/android/net/wifi/WifiConfiguration.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 91b7df372e01..62d6067c86f3 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -568,14 +568,12 @@ public class WifiConfiguration implements Parcelable { * 2GHz band. * @hide */ - @SystemApi public static final int AP_BAND_2GHZ = 0; /** * 5GHz band. * @hide */ - @SystemApi public static final int AP_BAND_5GHZ = 1; /** @@ -583,7 +581,6 @@ public class WifiConfiguration implements Parcelable { * operating country code and current radio conditions. * @hide */ - @SystemApi public static final int AP_BAND_ANY = -1; /** @@ -593,7 +590,7 @@ public class WifiConfiguration implements Parcelable { * * @hide */ - @SystemApi + @UnsupportedAppUsage @ApBand public int apBand = AP_BAND_2GHZ; -- cgit v1.2.3 From a52e3168d45401076d4852f03973f074eda2b2cf Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 30 Jan 2020 20:24:49 -0800 Subject: Migrate to getNetworkSelectionStatus() isNetworkEnabled() & isNetworkPermanentlyDisabled() should not be formal APIs. Instead, getNetworkSelectionStatus() with a set of constants is sufficient as an API surface, and will be more maintainable in the future. Also fixed testOsuAccessPointSummary_showsProvisioningUpdates that was previously broken. Bug: 146046526 Test: atest FrameworksWifiApiTests SettingsLibTests Test: make RunSettingsLibRoboTests -j40 Change-Id: I89ed4f0de0ce693bbf4f77be84f08b82a89037bb --- wifi/java/android/net/wifi/WifiConfiguration.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 91b7df372e01..87c2ce9aa307 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -1709,7 +1709,10 @@ public class WifiConfiguration implements Parcelable { return mStatus; } - /** True if the current network is enabled to join network selection, false otherwise. */ + /** + * True if the current network is enabled to join network selection, false otherwise. + * @hide + */ public boolean isNetworkEnabled() { return mStatus == NETWORK_SELECTION_ENABLED; } @@ -1722,7 +1725,10 @@ public class WifiConfiguration implements Parcelable { return mStatus == NETWORK_SELECTION_TEMPORARY_DISABLED; } - /** True if the current network is permanently disabled, false otherwise. */ + /** + * True if the current network is permanently disabled, false otherwise. + * @hide + */ public boolean isNetworkPermanentlyDisabled() { return mStatus == NETWORK_SELECTION_PERMANENTLY_DISABLED; } -- cgit v1.2.3 From e6d6949b9aece62bc0a9736c0ad10de0d6ce0565 Mon Sep 17 00:00:00 2001 From: David Su Date: Tue, 4 Feb 2020 17:26:46 -0800 Subject: Wifi: Hide NETWORK_SELECTION_DISABLED_MAX NETWORK_SELECTION_DISABLED_MAX is a constant, but it could change if a new reason is added. Instead expose a static method getMaxNetworkSelectionDisableReason(). Bug: 146046526 Test: atest FrameworksWifiApiTests Change-Id: I2fde8a0207b12d9055ed0cd4b6346b678a2819bf --- wifi/java/android/net/wifi/WifiConfiguration.java | 26 +++++++++++++++++++++- .../android/net/wifi/WifiConfigurationTest.java | 14 ++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 87c2ce9aa307..1906e249c6d9 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -1304,9 +1304,33 @@ public class WifiConfiguration implements Parcelable { public static final int DISABLED_BY_WRONG_PASSWORD = 8; /** This network is disabled because service is not subscribed. */ public static final int DISABLED_AUTHENTICATION_NO_SUBSCRIPTION = 9; - /** All other disable reasons should be strictly less than this value. */ + /** + * All other disable reasons should be strictly less than this value. + * @hide + */ public static final int NETWORK_SELECTION_DISABLED_MAX = 10; + /** + * Get an integer that is equal to the maximum integer value of all the + * DISABLED_* reasons + * e.g. {@link #DISABLED_NONE}, {@link #DISABLED_ASSOCIATION_REJECTION}, etc. + * + * All DISABLED_* constants will be contiguous in the range + * 0, 1, 2, 3, ..., getMaxNetworkSelectionDisableReasons() + * + *
    + * For example, this can be used to iterate through all the network selection + * disable reasons like so: + *
    {@code
    +         * for (int reason = 0; reason <= getMaxNetworkSelectionDisableReasons(); reason++) {
    +         *     ...
    +         * }
    +         * }
    + */ + public static int getMaxNetworkSelectionDisableReason() { + return NETWORK_SELECTION_DISABLED_MAX - 1; + } + /** * Contains info about disable reasons. * @hide diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java index 8023160a811e..05a3dce44022 100644 --- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java @@ -335,6 +335,20 @@ public class WifiConfigurationTest { } } + /** + * Ensure that {@link NetworkSelectionStatus#getMaxNetworkSelectionDisableReason()} returns + * the maximum disable reason. + */ + @Test + public void testNetworkSelectionGetMaxNetworkSelectionDisableReason() { + int maxReason = Integer.MIN_VALUE; + for (int i = 0; i < NetworkSelectionStatus.DISABLE_REASON_INFOS.size(); i++) { + int reason = NetworkSelectionStatus.DISABLE_REASON_INFOS.keyAt(i); + maxReason = Math.max(maxReason, reason); + } + assertEquals(maxReason, NetworkSelectionStatus.getMaxNetworkSelectionDisableReason()); + } + /** * Ensure that {@link WifiConfiguration#setSecurityParams(int)} sets up the * {@link WifiConfiguration} object correctly for SAE security type. -- cgit v1.2.3 From f0a249541edfd0be7a36e7f0ea58259660b51f4c Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Tue, 4 Feb 2020 16:18:28 +0800 Subject: Wifi: revise P2P API Bug: 146423859 Bug: 144799344 Test: atest FrameworksWifiApiTests atest FrameworksWifiTests Change-Id: I8e815182e1d6158a520f4fa793339dd34726b243 --- wifi/java/android/net/wifi/p2p/WifiP2pConfig.java | 2 ++ .../android/net/wifi/p2p/WifiP2pGroupList.java | 6 +++-- wifi/java/android/net/wifi/p2p/WifiP2pManager.java | 29 ++++++++++++++++++---- wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java | 25 ++++++++++--------- .../android/net/wifi/p2p/WifiP2pDeviceTest.java | 2 +- .../android/net/wifi/p2p/WifiP2pWfdInfoTest.java | 4 +-- 6 files changed, 46 insertions(+), 22 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java index 36c7213b3799..d47989235f0b 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java @@ -17,6 +17,7 @@ package android.net.wifi.p2p; import android.annotation.IntDef; +import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; @@ -133,6 +134,7 @@ public class WifiP2pConfig implements Parcelable { * * By default this field is set to {@link #GROUP_OWNER_INTENT_AUTO}. */ + @IntRange(from = 0, to = 15) public int groupOwnerIntent = GROUP_OWNER_INTENT_AUTO; /** @hide */ diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java index cdb2806af0b1..8a86311defca 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java @@ -22,7 +22,9 @@ import android.os.Parcel; import android.os.Parcelable; import android.util.LruCache; +import java.util.ArrayList; import java.util.Collection; +import java.util.List; import java.util.Map; @@ -78,8 +80,8 @@ public final class WifiP2pGroupList implements Parcelable { * Get the list of P2P groups. */ @NonNull - public Collection getGroupList() { - return mGroups.snapshot().values(); + public List getGroupList() { + return new ArrayList<>(mGroups.snapshot().values()); } /** diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java index 0fe06756a969..9c2cad99614d 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java @@ -326,6 +326,12 @@ public class WifiP2pManager { /** * Broadcast intent action indicating that remembered persistent groups have changed. + * + * You can not receive this through components declared + * in manifests, only by explicitly registering for it with + * {@link android.content.Context#registerReceiver(android.content.BroadcastReceiver, + * android.content.IntentFilter) Context.registerReceiver()}. + * * @hide */ @SystemApi @@ -1347,20 +1353,33 @@ public class WifiP2pManager { } /** - * Force p2p to enter or exit listen state + * Force p2p to enter listen state * * @param c is the channel created at {@link #initialize(Context, Looper, ChannelListener)} - * @param enable enables or disables listening * @param listener for callbacks on success or failure. Can be null. * * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - public void listen(@NonNull Channel c, boolean enable, @Nullable ActionListener listener) { + public void startListening(@NonNull Channel c, @Nullable ActionListener listener) { checkChannel(c); - c.mAsyncChannel.sendMessage(enable ? START_LISTEN : STOP_LISTEN, - 0, c.putListener(listener)); + c.mAsyncChannel.sendMessage(START_LISTEN, 0, c.putListener(listener)); + } + + /** + * Force p2p to exit listen state + * + * @param c is the channel created at {@link #initialize(Context, Looper, ChannelListener)} + * @param listener for callbacks on success or failure. Can be null. + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) + public void stopListening(@NonNull Channel c, @Nullable ActionListener listener) { + checkChannel(c); + c.mAsyncChannel.sendMessage(STOP_LISTEN, 0, c.putListener(listener)); } /** diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java index 5484d248429f..e399b5b9afa6 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java @@ -17,6 +17,7 @@ package android.net.wifi.p2p; import android.annotation.IntDef; +import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; @@ -34,7 +35,7 @@ import java.util.Locale; */ public final class WifiP2pWfdInfo implements Parcelable { - private boolean mWfdEnabled; + private boolean mEnabled; /** Device information bitmap */ private int mDeviceInfo; @@ -85,15 +86,15 @@ public final class WifiP2pWfdInfo implements Parcelable { /** @hide */ @UnsupportedAppUsage public WifiP2pWfdInfo(int devInfo, int ctrlPort, int maxTput) { - mWfdEnabled = true; + mEnabled = true; mDeviceInfo = devInfo; mCtrlPort = ctrlPort; mMaxThroughput = maxTput; } /** Returns true is Wifi Display is enabled, false otherwise. */ - public boolean isWfdEnabled() { - return mWfdEnabled; + public boolean isEnabled() { + return mEnabled; } /** @@ -101,8 +102,8 @@ public final class WifiP2pWfdInfo implements Parcelable { * * @param enabled true to enable Wifi Display, false to disable */ - public void setWfdEnabled(boolean enabled) { - mWfdEnabled = enabled; + public void setEnabled(boolean enabled) { + mEnabled = enabled; } /** @@ -177,12 +178,12 @@ public final class WifiP2pWfdInfo implements Parcelable { } /** Sets the TCP port at which the WFD Device listens for RTSP messages. */ - public void setControlPort(int port) { + public void setControlPort(@IntRange(from = 0) int port) { mCtrlPort = port; } /** Sets the maximum average throughput capability of the WFD Device, in megabits/second. */ - public void setMaxThroughput(int maxThroughput) { + public void setMaxThroughput(@IntRange(from = 0) int maxThroughput) { mMaxThroughput = maxThroughput; } @@ -200,7 +201,7 @@ public final class WifiP2pWfdInfo implements Parcelable { @Override public String toString() { StringBuffer sbuf = new StringBuffer(); - sbuf.append("WFD enabled: ").append(mWfdEnabled); + sbuf.append("WFD enabled: ").append(mEnabled); sbuf.append("WFD DeviceInfo: ").append(mDeviceInfo); sbuf.append("\n WFD CtrlPort: ").append(mCtrlPort); sbuf.append("\n WFD MaxThroughput: ").append(mMaxThroughput); @@ -215,7 +216,7 @@ public final class WifiP2pWfdInfo implements Parcelable { /** Copy constructor. */ public WifiP2pWfdInfo(@Nullable WifiP2pWfdInfo source) { if (source != null) { - mWfdEnabled = source.mWfdEnabled; + mEnabled = source.mEnabled; mDeviceInfo = source.mDeviceInfo; mCtrlPort = source.mCtrlPort; mMaxThroughput = source.mMaxThroughput; @@ -225,14 +226,14 @@ public final class WifiP2pWfdInfo implements Parcelable { /** Implement the Parcelable interface */ @Override public void writeToParcel(@NonNull Parcel dest, int flags) { - dest.writeInt(mWfdEnabled ? 1 : 0); + dest.writeInt(mEnabled ? 1 : 0); dest.writeInt(mDeviceInfo); dest.writeInt(mCtrlPort); dest.writeInt(mMaxThroughput); } private void readFromParcel(Parcel in) { - mWfdEnabled = (in.readInt() == 1); + mEnabled = (in.readInt() == 1); mDeviceInfo = in.readInt(); mCtrlPort = in.readInt(); mMaxThroughput = in.readInt(); diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceTest.java index 17ee75594c2f..6edc287068e8 100644 --- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceTest.java +++ b/wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceTest.java @@ -45,7 +45,7 @@ public class WifiP2pDeviceTest { assertEquals(devA.groupCapability, devB.groupCapability); assertEquals(devA.status, devB.status); if (devA.wfdInfo != null) { - assertEquals(devA.wfdInfo.isWfdEnabled(), devB.wfdInfo.isWfdEnabled()); + assertEquals(devA.wfdInfo.isEnabled(), devB.wfdInfo.isEnabled()); assertEquals(devA.wfdInfo.getDeviceInfoHex(), devB.wfdInfo.getDeviceInfoHex()); assertEquals(devA.wfdInfo.getControlPort(), devB.wfdInfo.getControlPort()); assertEquals(devA.wfdInfo.getMaxThroughput(), devB.wfdInfo.getMaxThroughput()); diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java index 15a0aacf6e5b..2a9b36b47172 100644 --- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java +++ b/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java @@ -55,8 +55,8 @@ public class WifiP2pWfdInfoTest { public void testSettersGetters() throws Exception { WifiP2pWfdInfo info = new WifiP2pWfdInfo(); - info.setWfdEnabled(true); - assertTrue(info.isWfdEnabled()); + info.setEnabled(true); + assertTrue(info.isEnabled()); info.setDeviceType(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE); assertEquals(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE, info.getDeviceType()); -- cgit v1.2.3 From d20f03011f95bd04bace0977d246cdc737ce5627 Mon Sep 17 00:00:00 2001 From: Anton Hansson Date: Wed, 5 Feb 2020 09:46:24 +0000 Subject: Revert "Create all variants of stubs for wifi" This reverts commit 722a3606096055ba1c107a1a3efd126380c9ce87. Exempt-From-Owner-Approval: clean revert Reason for revert: Broke the apps build Change-Id: I14e25b924d7415a53a5f5994054f4fd5d9ff99cc --- wifi/Android.bp | 69 +++++++++++---------------------------------------------- 1 file changed, 13 insertions(+), 56 deletions(-) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index e55971ef8f72..dae04c6c3a25 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -132,70 +132,27 @@ java_library { ], } -stubs_defaults { - name: "framework-wifi-stubs-srcs-defaults", +droidstubs { + name: "framework-wifi-stubs-srcs", + srcs: [ + ":framework-annotations", + ":framework-wifi-updatable-sources", + ], // This is needed as IOnWifiActivityEnergyInfoListener.aidl in framework-wifi depends on // WifiActivityEnergyInfo.aidl in framework-minus-apex aidl: { include_dirs: ["frameworks/base/core/java"], }, - srcs: [ ":framework-wifi-updatable-sources" ], - libs: [ "framework-annotations-lib" ], - sdk_version: "system_current", -} - -droidstubs { - name: "framework-wifi-stubs-srcs-publicapi", - defaults: [ - "framework-module-stubs-defaults-publicapi", - "framework-wifi-stubs-srcs-defaults", - ], -} - -droidstubs { - name: "framework-wifi-stubs-srcs-systemapi", - defaults: [ - "framework-module-stubs-defaults-systemapi", - "framework-wifi-stubs-srcs-defaults", - ], -} - -droidstubs { - name: "framework-wifi-api-module_libs_api", - defaults: [ - "framework-module-api-defaults-module_libs_api", - "framework-wifi-stubs-srcs-defaults", - ], -} - -droidstubs { - name: "framework-wifi-stubs-srcs-module_libs_api", - defaults: [ - "framework-module-stubs-defaults-module_libs_api", - "framework-wifi-stubs-srcs-defaults", - ], -} - -java_library { - name: "framework-wifi-stubs-publicapi", - srcs: [":framework-wifi-stubs-srcs-publicapi"], - sdk_version: "current", - installable: false, -} - -java_library { - name: "framework-wifi-stubs-systemapi", - srcs: [":framework-wifi-stubs-srcs-systemapi"], - sdk_version: "system_current", - libs: ["framework-annotations-lib"], - installable: false, + defaults: [ "framework-module-stubs-defaults-systemapi" ], + sdk_version: "core_current", + libs: ["android_system_stubs_current"], } java_library { - name: "framework-wifi-stubs-module_libs_api", - srcs: [":framework-wifi-stubs-srcs-module_libs_api"], - sdk_version: "system_current", - libs: ["framework-annotations-lib"], + name: "framework-wifi-stubs", + srcs: [":framework-wifi-stubs-srcs"], + sdk_version: "core_current", + libs: ["android_system_stubs_current"], installable: false, } -- cgit v1.2.3 From d098b4f7b2c909d7be189e662e6a2cb156e3e8d2 Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Tue, 4 Feb 2020 13:39:17 -0800 Subject: [WIFICOND][API] Clarify time usage - Use long for time - Add annotations Per API council feedback. Bug: 148680192 Test: atest android.net.wifi Test: atest com.android.server.wifi Change-Id: Ib32640a864b8f4d7674348c1eb8bbd6d4f17ab32 --- wifi/java/android/net/wifi/wificond/PnoSettings.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/wificond/PnoSettings.java b/wifi/java/android/net/wifi/wificond/PnoSettings.java index 57c9ca5fd302..533d37d3a23a 100644 --- a/wifi/java/android/net/wifi/wificond/PnoSettings.java +++ b/wifi/java/android/net/wifi/wificond/PnoSettings.java @@ -16,6 +16,7 @@ package android.net.wifi.wificond; +import android.annotation.DurationMillisLong; import android.annotation.NonNull; import android.annotation.SystemApi; import android.os.Parcel; @@ -33,7 +34,7 @@ import java.util.Objects; */ @SystemApi public final class PnoSettings implements Parcelable { - private int mIntervalMs; + private long mIntervalMs; private int mMin2gRssi; private int mMin5gRssi; private int mMin6gRssi; @@ -47,17 +48,17 @@ public final class PnoSettings implements Parcelable { * * @return An interval in milliseconds. */ - public int getIntervalMillis() { + public @DurationMillisLong long getIntervalMillis() { return mIntervalMs; } /** * Set the requested PNO scan interval in milliseconds. * - * @param intervalMs An interval in milliseconds. + * @param intervalMillis An interval in milliseconds. */ - public void setIntervalMillis(int intervalMs) { - this.mIntervalMs = intervalMs; + public void setIntervalMillis(@DurationMillisLong long intervalMillis) { + this.mIntervalMs = intervalMillis; } /** @@ -176,7 +177,7 @@ public final class PnoSettings implements Parcelable { **/ @Override public void writeToParcel(@NonNull Parcel out, int flags) { - out.writeInt(mIntervalMs); + out.writeLong(mIntervalMs); out.writeInt(mMin2gRssi); out.writeInt(mMin5gRssi); out.writeInt(mMin6gRssi); @@ -189,7 +190,7 @@ public final class PnoSettings implements Parcelable { @Override public PnoSettings createFromParcel(Parcel in) { PnoSettings result = new PnoSettings(); - result.mIntervalMs = in.readInt(); + result.mIntervalMs = in.readLong(); result.mMin2gRssi = in.readInt(); result.mMin5gRssi = in.readInt(); result.mMin6gRssi = in.readInt(); -- cgit v1.2.3 From ec97fd9d0d70af86203b6e16bb6ff8669576ef0c Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Tue, 4 Feb 2020 14:58:20 -0800 Subject: [WIFICOND][API] Documentation clarification for AP callback registration Bug: 148680192 Test: N/A (builds) Change-Id: Ibb912a7007b36e0ea3417e6d34dca7ddd618678d --- wifi/java/android/net/wifi/wificond/WifiCondManager.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/wificond/WifiCondManager.java b/wifi/java/android/net/wifi/wificond/WifiCondManager.java index 43aa1b64efbc..d4be38a885a4 100644 --- a/wifi/java/android/net/wifi/wificond/WifiCondManager.java +++ b/wifi/java/android/net/wifi/wificond/WifiCondManager.java @@ -1071,8 +1071,13 @@ public class WifiCondManager { } /** - * Register the provided callback handler for SoftAp events. Note that the Soft AP itself is - * configured using {@link #setupInterfaceForSoftApMode(String)}. + * Register the provided callback handler for SoftAp events. The interface must first be created + * using {@link #setupInterfaceForSoftApMode(String)}. The callback registration is valid until + * the interface is deleted using {@link #tearDownSoftApInterface(String)} (no deregistration + * method is provided). + *

    + * Note that only one callback can be registered at a time - any registration overrides previous + * registrations. * * @param ifaceName Name of the interface on which to register the callback. * @param executor The Executor on which to execute the callbacks. -- cgit v1.2.3 From 97ba3da29516e95dc2d834dc93ec7ea11dd2f105 Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Tue, 4 Feb 2020 15:10:41 -0800 Subject: [WIFICOND][API] Simplify initialization sequence Per API council request: rename 'initialize' to the only function it (really) executed - setting up a death listener. Bug: 148680192 Test: atest android.net.wifi Test: atest com.android.server.wifi Change-Id: I0857f1b550f6bdae039dae76b663bc2813dc5bdb --- wifi/java/android/net/wifi/wificond/WifiCondManager.java | 13 ++++--------- .../src/android/net/wifi/wificond/WifiCondManagerTest.java | 5 ++--- 2 files changed, 6 insertions(+), 12 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/wificond/WifiCondManager.java b/wifi/java/android/net/wifi/wificond/WifiCondManager.java index d4be38a885a4..d556ac9e4205 100644 --- a/wifi/java/android/net/wifi/wificond/WifiCondManager.java +++ b/wifi/java/android/net/wifi/wificond/WifiCondManager.java @@ -496,22 +496,17 @@ public class WifiCondManager { } /** - * Initializes WifiCondManager & registers a death notification for the WifiCondManager which - * acts as a proxy for the wificond daemon (i.e. the death listener will be called when and if - * the wificond daemon dies). - * - * Note: This method clears any existing state in wificond daemon. + * Register a death notification for the WifiCondManager which acts as a proxy for the + * wificond daemon (i.e. the death listener will be called when and if the wificond daemon + * dies). * * @param deathEventHandler A {@link Runnable} to be called whenever the wificond daemon dies. - * @return Returns true on success. */ - public boolean initialize(@NonNull Runnable deathEventHandler) { + public void setOnServiceDeadCallback(@NonNull Runnable deathEventHandler) { if (mDeathEventHandler != null) { Log.e(TAG, "Death handler already present"); } mDeathEventHandler = deathEventHandler; - tearDownInterfaces(); - return true; } /** diff --git a/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java b/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java index 5ba02a779663..32105be6ae4c 100644 --- a/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java +++ b/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java @@ -720,8 +720,7 @@ public class WifiCondManagerTest { @Test public void testRegisterDeathHandler() throws Exception { Runnable deathHandler = mock(Runnable.class); - assertTrue(mWificondControl.initialize(deathHandler)); - verify(mWificond).tearDownInterfaces(); + mWificondControl.setOnServiceDeadCallback(deathHandler); mWificondControl.binderDied(); mLooper.dispatchAll(); verify(deathHandler).run(); @@ -734,7 +733,7 @@ public class WifiCondManagerTest { @Test public void testDeathHandling() throws Exception { Runnable deathHandler = mock(Runnable.class); - assertTrue(mWificondControl.initialize(deathHandler)); + mWificondControl.setOnServiceDeadCallback(deathHandler); testSetupInterfaceForClientMode(); -- cgit v1.2.3 From e4fad05f526fcbeff2af37502b9537bec037ce51 Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Tue, 4 Feb 2020 16:25:06 -0800 Subject: [WIFICOND][API] Update documentation - Interface initialization sequence - Scan behavior Bug: 148680192 Test: builds (doc changes only) Change-Id: I58cdb7122ab0d484cf6ae20b6b9b7b4ce0093f12 --- .../android/net/wifi/wificond/WifiCondManager.java | 81 +++++++++++++++++----- 1 file changed, 65 insertions(+), 16 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/wificond/WifiCondManager.java b/wifi/java/android/net/wifi/wificond/WifiCondManager.java index d556ac9e4205..7a31a5afab05 100644 --- a/wifi/java/android/net/wifi/wificond/WifiCondManager.java +++ b/wifi/java/android/net/wifi/wificond/WifiCondManager.java @@ -598,11 +598,12 @@ public class WifiCondManager { } /** - * Tear down a specific client (STA) interface, initially configured using + * Tear down a specific client (STA) interface configured using * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}. * * @param ifaceName Name of the interface to tear down. - * @return Returns true on success. + * @return Returns true on success, false on failure (e.g. when called before an interface was + * set up). */ public boolean tearDownClientInterface(@NonNull String ifaceName) { if (getClientInterface(ifaceName) == null) { @@ -676,11 +677,12 @@ public class WifiCondManager { } /** - * Tear down a Soft AP interface initially configured using + * Tear down a Soft AP interface configured using * {@link #setupInterfaceForSoftApMode(String)}. * * @param ifaceName Name of the interface to tear down. - * @return Returns true on success. + * @return Returns true on success, false on failure (e.g. when called before an interface was + * set up). */ public boolean tearDownSoftApInterface(@NonNull String ifaceName) { if (getApInterface(ifaceName) == null) { @@ -745,9 +747,13 @@ public class WifiCondManager { /** * Request signal polling. * - * @param ifaceName Name of the interface on which to poll. + * @param ifaceName Name of the interface on which to poll. The interface must have been + * already set up using + *{@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} + * or {@link #setupInterfaceForSoftApMode(String)}. + * * @return A {@link SignalPollResult} object containing interface statistics, or a null on - * error. + * error (e.g. the interface hasn't been set up yet). */ @Nullable public SignalPollResult signalPoll(@NonNull String ifaceName) { IClientInterface iface = getClientInterface(ifaceName); @@ -771,10 +777,14 @@ public class WifiCondManager { } /** - * Get current transmit (Tx) packet counters of the specified interface. + * Get current transmit (Tx) packet counters of the specified interface. The interface must + * have been already set up using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} + * or {@link #setupInterfaceForSoftApMode(String)}. * * @param ifaceName Name of the interface. - * @return {@link TxPacketCounters} of the current interface or null on error. + * @return {@link TxPacketCounters} of the current interface or null on error (e.g. when + * called before the interface has been set up). */ @Nullable public TxPacketCounters getTxPacketCounters(@NonNull String ifaceName) { IClientInterface iface = getClientInterface(ifaceName); @@ -808,10 +818,15 @@ public class WifiCondManager { * be done using {@link #startScan(String, int, Set, List)} or * {@link #startPnoScan(String, PnoSettings, Executor, PnoScanRequestCallback)}. * + * Note: The interface must have been already set up using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} + * or {@link #setupInterfaceForSoftApMode(String)}. + * * @param ifaceName Name of the interface. * @param scanType The type of scan result to be returned, can be * {@link #SCAN_TYPE_SINGLE_SCAN} or {@link #SCAN_TYPE_PNO_SCAN}. - * @return Returns an array of {@link NativeScanResult} or an empty array on failure. + * @return Returns an array of {@link NativeScanResult} or an empty array on failure (e.g. when + * called before the interface has been set up). */ @NonNull public List getScanResults(@NonNull String ifaceName, @ScanResultType int scanType) { @@ -864,13 +879,19 @@ public class WifiCondManager { * The latest scans can be obtained using {@link #getScanResults(String, int)} and using a * {@link #SCAN_TYPE_SINGLE_SCAN} for the {@code scanType}. * + * Note: The interface must have been already set up using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} + * or {@link #setupInterfaceForSoftApMode(String)}. + * * @param ifaceName Name of the interface on which to initiate the scan. * @param scanType Type of scan to perform, can be any of * {@link WifiScanner#SCAN_TYPE_HIGH_ACCURACY}, {@link WifiScanner#SCAN_TYPE_LOW_POWER}, or * {@link WifiScanner#SCAN_TYPE_LOW_LATENCY}. * @param freqs list of frequencies to scan for, if null scan all supported channels. - * @param hiddenNetworkSSIDs List of hidden networks to be scanned for. - * @return Returns true on success. + * @param hiddenNetworkSSIDs List of hidden networks to be scanned for, a null indicates that + * no hidden frequencies will be scanned for. + * @return Returns true on success, false on failure (e.g. when called before the interface + * has been set up). */ public boolean startScan(@NonNull String ifaceName, @WifiAnnotations.ScanType int scanType, @Nullable Set freqs, @Nullable List hiddenNetworkSSIDs) { @@ -926,11 +947,16 @@ public class WifiCondManager { * The latest PNO scans can be obtained using {@link #getScanResults(String, int)} with the * {@code scanType} set to {@link #SCAN_TYPE_PNO_SCAN}. * + * Note: The interface must have been already set up using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} + * or {@link #setupInterfaceForSoftApMode(String)}. + * * @param ifaceName Name of the interface on which to request a PNO. * @param pnoSettings PNO scan configuration. * @param executor The Executor on which to execute the callback. * @param callback Callback for the results of the offload request. - * @return true on success. + * @return true on success, false on failure (e.g. when called before the interface has been set + * up). */ public boolean startPnoScan(@NonNull String ifaceName, @NonNull PnoSettings pnoSettings, @NonNull @CallbackExecutor Executor executor, @@ -964,8 +990,13 @@ public class WifiCondManager { * Stop PNO scan configured with * {@link #startPnoScan(String, PnoSettings, Executor, PnoScanRequestCallback)}. * + * Note: The interface must have been already set up using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} + * or {@link #setupInterfaceForSoftApMode(String)}. + * * @param ifaceName Name of the interface on which the PNO scan was configured. - * @return true on success. + * @return true on success, false on failure (e.g. when called before the interface has been + * set up). */ public boolean stopPnoScan(@NonNull String ifaceName) { IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); @@ -982,7 +1013,13 @@ public class WifiCondManager { } /** - * Abort ongoing single scan started with {@link #startScan(String, int, Set, List)}. + * Abort ongoing single scan started with {@link #startScan(String, int, Set, List)}. No failure + * callback, e.g. {@link ScanEventCallback#onScanFailed()}, is triggered by this operation. + * + * Note: The interface must have been already set up using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} + * or {@link #setupInterfaceForSoftApMode(String)}. If the interface has not been set up then + * this method has no impact. * * @param ifaceName Name of the interface on which the scan was started. */ @@ -1050,7 +1087,14 @@ public class WifiCondManager { } /** - * Get the device phy capabilities for a given interface + * Get the device phy capabilities for a given interface. + * + * Note: The interface must have been already set up using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} + * or {@link #setupInterfaceForSoftApMode(String)}. + * + * @return DeviceWiphyCapabilities or null on error (e.g. when called on an interface which has + * not been set up). */ @Nullable public DeviceWiphyCapabilities getDeviceWiphyCapabilities(@NonNull String ifaceName) { if (mWificond == null) { @@ -1077,7 +1121,8 @@ public class WifiCondManager { * @param ifaceName Name of the interface on which to register the callback. * @param executor The Executor on which to execute the callbacks. * @param callback Callback for AP events. - * @return true on success, false otherwise. + * @return true on success, false on failure (e.g. when called on an interface which has not + * been set up). */ public boolean registerApCallback(@NonNull String ifaceName, @NonNull @CallbackExecutor Executor executor, @@ -1113,6 +1158,10 @@ public class WifiCondManager { * Send a management frame on the specified interface at the specified rate. Useful for probing * the link with arbitrary frames. * + * Note: The interface must have been already set up using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} + * or {@link #setupInterfaceForSoftApMode(String)}. + * * @param ifaceName The interface on which to send the frame. * @param frame The raw byte array of the management frame to tramit. * @param mcs The MCS (modulation and coding scheme), i.e. rate, at which to transmit the -- cgit v1.2.3 From 9b2f735c931742ddcd848d4f6e9946b184ab2d5d Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Wed, 5 Feb 2020 08:12:50 -0800 Subject: WifiScanner: Revise deprecation notes Feedback from API council. Bug: 148853334 Test: Compiles Change-Id: Ie672674a37cd565f1fb29e80f6eb500b1e308597 --- wifi/java/android/net/wifi/WifiScanner.java | 40 +++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 10 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index a85f40b3c1b8..b4eb30b8cfe6 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -293,26 +293,34 @@ public class WifiScanner { public final List hiddenNetworks = new ArrayList<>(); /** * period of background scan; in millisecond, 0 => single shot scan - * @deprecated Background scan support is removed. + * @deprecated Background scan support has always been hardware vendor dependent. This + * support may not be present on newer devices. Use {@link #startScan(ScanSettings, + * ScanListener)} instead for single scans. */ @Deprecated public int periodInMs; /** * must have a valid REPORT_EVENT value - * @deprecated Background scan support is removed. + * @deprecated Background scan support has always been hardware vendor dependent. This + * support may not be present on newer devices. Use {@link #startScan(ScanSettings, + * ScanListener)} instead for single scans. */ @Deprecated public int reportEvents; /** * defines number of bssids to cache from each scan - * @deprecated Background scan support is removed. + * @deprecated Background scan support has always been hardware vendor dependent. This + * support may not be present on newer devices. Use {@link #startScan(ScanSettings, + * ScanListener)} instead for single scans. */ @Deprecated public int numBssidsPerScan; /** * defines number of scans to cache; use it with REPORT_EVENT_AFTER_BUFFER_FULL * to wake up at fixed interval - * @deprecated Background scan support is removed. + * @deprecated Background scan support has always been hardware vendor dependent. This + * support may not be present on newer devices. Use {@link #startScan(ScanSettings, + * ScanListener)} instead for single scans. */ @Deprecated public int maxScansToCache; @@ -321,14 +329,18 @@ public class WifiScanner { * a truncated binary exponential backoff bucket and the scan period will grow * exponentially as per formula: actual_period(N) = period * (2 ^ (N/stepCount)) * to maxPeriodInMs - * @deprecated Background scan support is removed. + * @deprecated Background scan support has always been hardware vendor dependent. This + * support may not be present on newer devices. Use {@link #startScan(ScanSettings, + * ScanListener)} instead for single scans. */ @Deprecated public int maxPeriodInMs; /** * for truncated binary exponential back off bucket, number of scans to perform * for a given period - * @deprecated Background scan support is removed. + * @deprecated Background scan support has always been hardware vendor dependent. This + * support may not be present on newer devices. Use {@link #startScan(ScanSettings, + * ScanListener)} instead for single scans. */ @Deprecated public int stepCount; @@ -806,7 +818,9 @@ public class WifiScanner { /** * Framework co-ordinates scans across multiple apps; so it may not give exactly the * same period requested. If period of a scan is changed; it is reported by this event. - * @deprecated Background scan support is removed. + * @deprecated Background scan support has always been hardware vendor dependent. This + * support may not be present on newer devices. Use {@link #startScan(ScanSettings, + * ScanListener)} instead for single scans. */ @Deprecated public void onPeriodChanged(int periodInMs); @@ -913,7 +927,9 @@ public class WifiScanner { * @param listener specifies the object to report events to. This object is also treated as a * key for this scan, and must also be specified to cancel the scan. Multiple * scans should also not share this object. - * @deprecated Background scan support is removed. + * @deprecated Background scan support has always been hardware vendor dependent. This support + * may not be present on newer devices. Use {@link #startScan(ScanSettings, ScanListener)} + * instead for single scans. */ @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) @@ -935,7 +951,9 @@ public class WifiScanner { * stop an ongoing wifi scan * @param listener specifies which scan to cancel; must be same object as passed in {@link * #startBackgroundScan} - * @deprecated Background scan support is removed. + * @deprecated Background scan support has always been hardware vendor dependent. This support + * may not be present on newer devices. Use {@link #startScan(ScanSettings, ScanListener)} + * instead for single scans. */ @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) @@ -953,7 +971,9 @@ public class WifiScanner { /** * reports currently available scan results on appropriate listeners * @return true if all scan results were reported correctly - * @deprecated Background scan support is removed. + * @deprecated Background scan support has always been hardware vendor dependent. This support + * may not be present on newer devices. Use {@link #startScan(ScanSettings, ScanListener)} + * instead for single scans. */ @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) -- cgit v1.2.3 From e8d73bb397a92601590bf69c6ace73b286244439 Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Wed, 5 Feb 2020 13:16:53 -0800 Subject: [WIFICOND][API] Replace capability BitSet by an int The capability bit set is standard constrained - 16 bits and no more. Can use a simpler/lighter int. Per API council feedback. Bug: 148680192 Test: atest android.net.wifi Test: atest com.android.server.wifi Change-Id: I47e8458d64f998da2e9743ad850687bc56a24cf6 --- .../net/wifi/wificond/NativeScanResult.java | 27 +++++----------------- .../net/wifi/wificond/NativeScanResultTest.java | 3 +-- 2 files changed, 7 insertions(+), 23 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/wificond/NativeScanResult.java b/wifi/java/android/net/wifi/wificond/NativeScanResult.java index 85251e8b1d42..7cc617d61b00 100644 --- a/wifi/java/android/net/wifi/wificond/NativeScanResult.java +++ b/wifi/java/android/net/wifi/wificond/NativeScanResult.java @@ -24,7 +24,6 @@ import android.os.Parcelable; import com.android.internal.annotations.VisibleForTesting; import java.util.ArrayList; -import java.util.BitSet; import java.util.List; /** @@ -34,8 +33,6 @@ import java.util.List; */ @SystemApi public final class NativeScanResult implements Parcelable { - private static final int CAPABILITY_SIZE = 16; - /** @hide */ @VisibleForTesting public byte[] ssid; @@ -56,7 +53,7 @@ public final class NativeScanResult implements Parcelable { public long tsf; /** @hide */ @VisibleForTesting - public BitSet capability; + public int capability; /** @hide */ @VisibleForTesting public boolean associated; @@ -134,7 +131,7 @@ public final class NativeScanResult implements Parcelable { * Returns the capabilities of the AP repseresented by this scan result as advertised in the * received probe response or beacon. * - * This is a bit mask describing the capabilities of a BSS. See IEEE Std 802.11: 8.4.1.4: + * This is a bit mask describing the capabilities of a BSS. See IEEE Std 802.11: 9.4.1.4: * Bit 0 - ESS * Bit 1 - IBSS * Bit 2 - CF Pollable @@ -143,7 +140,7 @@ public final class NativeScanResult implements Parcelable { * Bit 5 - Short Preamble * Bit 6 - PBCC * Bit 7 - Channel Agility - * Bit 8 - Spectrum Mgmt + * Bit 8 - Spectrum Management * Bit 9 - QoS * Bit 10 - Short Slot Time * Bit 11 - APSD @@ -154,7 +151,7 @@ public final class NativeScanResult implements Parcelable { * * @return a bit mask of capabilities. */ - @NonNull public BitSet getCapabilities() { + @NonNull public int getCapabilities() { return capability; } @@ -188,13 +185,7 @@ public final class NativeScanResult implements Parcelable { out.writeInt(frequency); out.writeInt(signalMbm); out.writeLong(tsf); - int capabilityInt = 0; - for (int i = 0; i < CAPABILITY_SIZE; i++) { - if (capability.get(i)) { - capabilityInt |= 1 << i; - } - } - out.writeInt(capabilityInt); + out.writeInt(capability); out.writeInt(associated ? 1 : 0); out.writeTypedList(radioChainInfos); } @@ -220,13 +211,7 @@ public final class NativeScanResult implements Parcelable { result.frequency = in.readInt(); result.signalMbm = in.readInt(); result.tsf = in.readLong(); - int capabilityInt = in.readInt(); - result.capability = new BitSet(CAPABILITY_SIZE); - for (int i = 0; i < CAPABILITY_SIZE; i++) { - if ((capabilityInt & (1 << i)) != 0) { - result.capability.set(i); - } - } + result.capability = in.readInt(); result.associated = (in.readInt() != 0); result.radioChainInfos = new ArrayList<>(); in.readTypedList(result.radioChainInfos, RadioChainInfo.CREATOR); diff --git a/wifi/tests/src/android/net/wifi/wificond/NativeScanResultTest.java b/wifi/tests/src/android/net/wifi/wificond/NativeScanResultTest.java index 06f12f7f37ea..0df170f8786c 100644 --- a/wifi/tests/src/android/net/wifi/wificond/NativeScanResultTest.java +++ b/wifi/tests/src/android/net/wifi/wificond/NativeScanResultTest.java @@ -28,7 +28,6 @@ import org.junit.Test; import java.util.ArrayList; import java.util.Arrays; -import java.util.BitSet; /** * Unit tests for {@link android.net.wifi.wificond.NativeScanResult}. @@ -46,7 +45,7 @@ public class NativeScanResultTest { private static final int TEST_FREQUENCY = 2456; private static final int TEST_SIGNAL_MBM = -45; private static final long TEST_TSF = 34455441; - private static final BitSet TEST_CAPABILITY = new BitSet(16) {{ set(2); set(5); }}; + private static final int TEST_CAPABILITY = (0x1 << 2) | (0x1 << 5); private static final boolean TEST_ASSOCIATED = true; private static final int[] RADIO_CHAIN_IDS = { 0, 1 }; private static final int[] RADIO_CHAIN_LEVELS = { -56, -65 }; -- cgit v1.2.3 From 1dfe2a74e561cb3a45416c36ebb274f3fd2d0954 Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Wed, 5 Feb 2020 16:48:04 -0800 Subject: WifiTrackerLibTests - remove dependency on hide API Bug: 148980222 Test: atest com.android.wifitrackerlib Change-Id: I167e1cf02ff5d85b2a354cb6c1df2f516e4140a7 --- wifi/Android.bp | 1 - 1 file changed, 1 deletion(-) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index dae04c6c3a25..6a29b1c36052 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -63,7 +63,6 @@ test_access_hidden_api_whitelist = [ "//frameworks/base/wifi/tests", "//frameworks/opt/net/wifi/tests/wifitests:__subpackages__", - "//frameworks/opt/net/wifi/libs/WifiTrackerLib/tests", "//external/robolectric-shadows:__subpackages__", "//frameworks/base/packages/SettingsLib/tests/integ", "//external/sl4a:__subpackages__", -- cgit v1.2.3 From 4313e6c22a8a7397be31aa02b1117338bb9a11d8 Mon Sep 17 00:00:00 2001 From: David Su Date: Wed, 5 Feb 2020 18:11:46 -0800 Subject: Move BaseWifiService out of frameworks-wifi BaseWifiService should not be in framework-wifi.jar (i.e. bootclasspath) because it is only used in wifi-service. Bug: 146413358 Test: boots up and connects to wifi Change-Id: I951b635981ab077536076e899bd0987d61817d93 --- .../com/android/server/wifi/BaseWifiService.java | 641 --------------------- 1 file changed, 641 deletions(-) delete mode 100644 wifi/java/com/android/server/wifi/BaseWifiService.java (limited to 'wifi') diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java deleted file mode 100644 index 060c85cac209..000000000000 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ /dev/null @@ -1,641 +0,0 @@ -/** - * Copyright (c) 2018, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License") { - * throw new UnsupportedOperationException(); - } - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.wifi; - -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.IOnWifiActivityEnergyInfoListener; -import android.net.wifi.IOnWifiUsabilityStatsListener; -import android.net.wifi.IScanResultsCallback; -import android.net.wifi.ISoftApCallback; -import android.net.wifi.ISuggestionConnectionStatusListener; -import android.net.wifi.ITrafficStateCallback; -import android.net.wifi.ITxPacketCountListener; -import android.net.wifi.IWifiConnectedNetworkScorer; -import android.net.wifi.IWifiManager; -import android.net.wifi.ScanResult; -import android.net.wifi.SoftApConfiguration; -import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiInfo; -import android.net.wifi.WifiManager; -import android.net.wifi.WifiNetworkSuggestion; -import android.net.wifi.hotspot2.IProvisioningCallback; -import android.net.wifi.hotspot2.OsuProvider; -import android.net.wifi.hotspot2.PasspointConfiguration; -import android.os.IBinder; -import android.os.RemoteException; -import android.os.ResultReceiver; -import android.os.WorkSource; -import android.os.connectivity.WifiActivityEnergyInfo; - -import java.util.List; -import java.util.Map; - -/** - * Empty concrete class implementing IWifiManager with stub methods throwing runtime exceptions. - * - * This class is meant to be extended by real implementations of IWifiManager in order to facilitate - * cross-repo changes to WiFi internal APIs, including the introduction of new APIs, the removal of - * deprecated APIs, or the migration of existing API signatures. - * - * When an existing API is scheduled for removal, it can be removed from IWifiManager.aidl - * immediately and marked as @Deprecated first in this class. Children inheriting this class are - * then given a short grace period to update themselves before the @Deprecated stub is removed for - * good. If the API scheduled for removal has a replacement or an overload (signature change), - * these should be introduced before the stub is removed to allow children to migrate. - * - * When a new API is added to IWifiManager.aidl, a stub should be added in BaseWifiService as - * well otherwise compilation will fail. - */ -public class BaseWifiService extends IWifiManager.Stub { - - private static final String TAG = BaseWifiService.class.getSimpleName(); - - @Override - public long getSupportedFeatures() { - throw new UnsupportedOperationException(); - } - - /** @deprecated use {@link #getWifiActivityEnergyInfoAsync} instead */ - @Deprecated - public WifiActivityEnergyInfo reportActivityInfo() { - throw new UnsupportedOperationException(); - } - - /** @deprecated use {@link #getWifiActivityEnergyInfoAsync} instead */ - @Deprecated - public void requestActivityInfo(ResultReceiver result) { - throw new UnsupportedOperationException(); - } - - @Override - public void getWifiActivityEnergyInfoAsync(IOnWifiActivityEnergyInfoListener listener) { - throw new UnsupportedOperationException(); - } - - @Override - public ParceledListSlice getConfiguredNetworks(String packageName, String featureId) { - throw new UnsupportedOperationException(); - } - - @Override - public ParceledListSlice getPrivilegedConfiguredNetworks(String packageName, String featureId) { - throw new UnsupportedOperationException(); - } - - @Override - public Map>> getAllMatchingFqdnsForScanResults( - List scanResults) { - throw new UnsupportedOperationException(); - } - - @Override - public Map> getMatchingOsuProviders( - List scanResults) { - throw new UnsupportedOperationException(); - } - - @Override - public Map getMatchingPasspointConfigsForOsuProviders( - List osuProviders) { - throw new UnsupportedOperationException(); - } - - @Override - public int addOrUpdateNetwork(WifiConfiguration config, String packageName) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean addOrUpdatePasspointConfiguration( - PasspointConfiguration config, String packageName) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean removePasspointConfiguration(String fqdn, String packageName) { - throw new UnsupportedOperationException(); - } - - @Override - public List getPasspointConfigurations(String packageName) { - throw new UnsupportedOperationException(); - } - - @Override - public List getWifiConfigsForPasspointProfiles(List fqdnList) { - throw new UnsupportedOperationException(); - } - - @Override - public void queryPasspointIcon(long bssid, String fileName) { - throw new UnsupportedOperationException(); - } - - @Override - public int matchProviderWithCurrentNetwork(String fqdn) { - throw new UnsupportedOperationException(); - } - - @Override - public void deauthenticateNetwork(long holdoff, boolean ess) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean removeNetwork(int netId, String packageName) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean enableNetwork(int netId, boolean disableOthers, String packageName) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean disableNetwork(int netId, String packageName) { - throw new UnsupportedOperationException(); - } - - @Override - public void allowAutojoinGlobal(boolean choice) { - throw new UnsupportedOperationException(); - } - - @Override - public void allowAutojoin(int netId, boolean choice) { - throw new UnsupportedOperationException(); - } - - @Override - public void allowAutojoinPasspoint(String fqdn, boolean enableAutoJoin) { - throw new UnsupportedOperationException(); - } - - @Override - public void setMacRandomizationSettingPasspointEnabled(String fqdn, boolean enable) { - throw new UnsupportedOperationException(); - } - - @Override - public void setMeteredOverridePasspoint(String fqdn, int meteredOverride) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean startScan(String packageName, String featureId) { - throw new UnsupportedOperationException(); - } - - @Override - public List getScanResults(String callingPackage, String callingFeatureId) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean disconnect(String packageName) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean reconnect(String packageName) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean reassociate(String packageName) { - throw new UnsupportedOperationException(); - } - - @Override - public WifiInfo getConnectionInfo(String callingPackage, String callingFeatureId) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean setWifiEnabled(String packageName, boolean enable) { - throw new UnsupportedOperationException(); - } - - @Override - public int getWifiEnabledState() { - throw new UnsupportedOperationException(); - } - - @Override - public String getCountryCode() { - throw new UnsupportedOperationException(); - } - - /** @deprecated use {@link #is5GHzBandSupported} instead */ - @Deprecated - public boolean isDualBandSupported() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean is5GHzBandSupported() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean is6GHzBandSupported() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isWifiStandardSupported(int standard) { - throw new UnsupportedOperationException(); - } - - /** @deprecated use {@link WifiManager#isStaApConcurrencySupported()} */ - @Deprecated - public boolean needs5GHzToAnyApBandConversion() { - throw new UnsupportedOperationException(); - } - - @Override - public DhcpInfo getDhcpInfo() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isScanAlwaysAvailable() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean acquireWifiLock(IBinder lock, int lockType, String tag, WorkSource ws) { - throw new UnsupportedOperationException(); - } - - @Override - public void updateWifiLockWorkSource(IBinder lock, WorkSource ws) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean releaseWifiLock(IBinder lock) { - throw new UnsupportedOperationException(); - } - - @Override - public void initializeMulticastFiltering() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isMulticastEnabled() { - throw new UnsupportedOperationException(); - } - - @Override - public void acquireMulticastLock(IBinder binder, String tag) { - throw new UnsupportedOperationException(); - } - - @Override - public void releaseMulticastLock(String tag) { - throw new UnsupportedOperationException(); - } - - @Override - public void updateInterfaceIpState(String ifaceName, int mode) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean startSoftAp(WifiConfiguration wifiConfig) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean startTetheredHotspot(SoftApConfiguration softApConfig) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean stopSoftAp() { - throw new UnsupportedOperationException(); - } - - @Override - public int startLocalOnlyHotspot(ILocalOnlyHotspotCallback callback, String packageName, - String featureId, SoftApConfiguration customConfig) { - throw new UnsupportedOperationException(); - } - - @Override - public void stopLocalOnlyHotspot() { - throw new UnsupportedOperationException(); - } - - @Override - public void startWatchLocalOnlyHotspot(ILocalOnlyHotspotCallback callback) { - throw new UnsupportedOperationException(); - } - - @Override - public void stopWatchLocalOnlyHotspot() { - throw new UnsupportedOperationException(); - } - - @Override - public int getWifiApEnabledState() { - throw new UnsupportedOperationException(); - } - - @Override - public WifiConfiguration getWifiApConfiguration() { - throw new UnsupportedOperationException(); - } - - @Override - public SoftApConfiguration getSoftApConfiguration() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean setWifiApConfiguration(WifiConfiguration wifiConfig, String packageName) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean setSoftApConfiguration(SoftApConfiguration softApConfig, String packageName) { - throw new UnsupportedOperationException(); - } - - @Override - public void notifyUserOfApBandConversion(String packageName) { - throw new UnsupportedOperationException(); - } - - @Override - public void enableTdls(String remoteIPAddress, boolean enable) { - throw new UnsupportedOperationException(); - } - - @Override - public void enableTdlsWithMacAddress(String remoteMacAddress, boolean enable) { - throw new UnsupportedOperationException(); - } - - @Override - public String getCurrentNetworkWpsNfcConfigurationToken() { - throw new UnsupportedOperationException(); - } - - @Override - public void enableVerboseLogging(int verbose) { - throw new UnsupportedOperationException(); - } - - @Override - public int getVerboseLoggingLevel() { - throw new UnsupportedOperationException(); - } - - /** @deprecated use {@link #allowAutojoinGlobal(boolean)} instead */ - @Deprecated - public void enableWifiConnectivityManager(boolean enabled) { - throw new UnsupportedOperationException(); - } - - @Override - public void disableEphemeralNetwork(String SSID, String packageName) { - throw new UnsupportedOperationException(); - } - - @Override - public void factoryReset(String packageName) { - throw new UnsupportedOperationException(); - } - - @Override - public Network getCurrentNetwork() { - throw new UnsupportedOperationException(); - } - - @Override - public byte[] retrieveBackupData() { - throw new UnsupportedOperationException(); - } - - @Override - public void restoreBackupData(byte[] data) { - throw new UnsupportedOperationException(); - } - - @Override - public byte[] retrieveSoftApBackupData() { - throw new UnsupportedOperationException(); - } - - @Override - public SoftApConfiguration restoreSoftApBackupData(byte[] data) { - throw new UnsupportedOperationException(); - } - - @Override - public void restoreSupplicantBackupData(byte[] supplicantData, byte[] ipConfigData) { - throw new UnsupportedOperationException(); - } - - @Override - public void startSubscriptionProvisioning( - OsuProvider provider, IProvisioningCallback callback) { - throw new UnsupportedOperationException(); - } - - @Override - public void registerSoftApCallback( - IBinder binder, ISoftApCallback callback, int callbackIdentifier) { - throw new UnsupportedOperationException(); - } - - @Override - public void unregisterSoftApCallback(int callbackIdentifier) { - throw new UnsupportedOperationException(); - } - - @Override - public void registerTrafficStateCallback( - IBinder binder, ITrafficStateCallback callback, int callbackIdentifier) { - throw new UnsupportedOperationException(); - } - - @Override - public void unregisterTrafficStateCallback(int callbackIdentifier) { - throw new UnsupportedOperationException(); - } - - @Override - public void registerNetworkRequestMatchCallback( - IBinder binder, INetworkRequestMatchCallback callback, int callbackIdentifier) { - throw new UnsupportedOperationException(); - } - - @Override - public void unregisterNetworkRequestMatchCallback(int callbackIdentifier) { - throw new UnsupportedOperationException(); - } - - @Override - public int addNetworkSuggestions( - List networkSuggestions, String callingPackageName, - String callingFeatureId) { - throw new UnsupportedOperationException(); - } - - @Override - public int removeNetworkSuggestions( - List networkSuggestions, String callingPackageName) { - throw new UnsupportedOperationException(); - } - - @Override - public List getNetworkSuggestions(String packageName) { - throw new UnsupportedOperationException(); - } - - @Override - public String[] getFactoryMacAddresses() { - throw new UnsupportedOperationException(); - } - - @Override - public void setDeviceMobilityState(int state) { - throw new UnsupportedOperationException(); - } - - @Override - public void startDppAsConfiguratorInitiator(IBinder binder, String enrolleeUri, - int selectedNetworkId, int netRole, IDppCallback callback) { - throw new UnsupportedOperationException(); - } - - @Override - public void startDppAsEnrolleeInitiator(IBinder binder, String configuratorUri, - IDppCallback callback) { - throw new UnsupportedOperationException(); - } - - @Override - public void stopDppSession() throws RemoteException { - throw new UnsupportedOperationException(); - } - - @Override - public void addOnWifiUsabilityStatsListener( - IBinder binder, IOnWifiUsabilityStatsListener listener, int listenerIdentifier) { - throw new UnsupportedOperationException(); - } - - @Override - public void removeOnWifiUsabilityStatsListener(int listenerIdentifier) { - throw new UnsupportedOperationException(); - } - - @Override - public void updateWifiUsabilityScore(int seqNum, int score, int predictionHorizonSec) { - throw new UnsupportedOperationException(); - } - - @Override - public void connect(WifiConfiguration config, int netId, IBinder binder, - IActionListener callback, int callbackIdentifier) { - throw new UnsupportedOperationException(); - } - - @Override - public void save(WifiConfiguration config, IBinder binder, IActionListener callback, - int callbackIdentifier) { - throw new UnsupportedOperationException(); - } - - @Override - public void forget(int netId, IBinder binder, IActionListener callback, - int callbackIdentifier) { - throw new UnsupportedOperationException(); - } - - @Override - public void getTxPacketCount(String packageName, IBinder binder, - ITxPacketCountListener callback, int callbackIdentifier) { - throw new UnsupportedOperationException(); - } - - @Override - public void registerScanResultsCallback(IScanResultsCallback callback) { - throw new UnsupportedOperationException(); - } - - @Override - public void unregisterScanResultsCallback(IScanResultsCallback callback) { - throw new UnsupportedOperationException(); - } - - @Override - public void registerSuggestionConnectionStatusListener(IBinder binder, - ISuggestionConnectionStatusListener listener, - int listenerIdentifier, String packageName, String featureId) { - throw new UnsupportedOperationException(); - } - - @Override - public void unregisterSuggestionConnectionStatusListener(int listenerIdentifier, - String packageName) { - throw new UnsupportedOperationException(); - } - - @Override - public int calculateSignalLevel(int rssi) { - throw new UnsupportedOperationException(); - } - - @Override - public List getWifiConfigForMatchedNetworkSuggestionsSharedWithUser( - List scanResults) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean setWifiConnectedNetworkScorer(IBinder binder, - IWifiConnectedNetworkScorer scorer) { - throw new UnsupportedOperationException(); - } - - @Override - public void clearWifiConnectedNetworkScorer() { - throw new UnsupportedOperationException(); - } - - @Override - public Map> getMatchingScanResults( - List networkSuggestions, - List scanResults, - String callingPackage, String callingFeatureId) { - throw new UnsupportedOperationException(); - } -} -- cgit v1.2.3 From e38acab53ea3d821e9d935efb78eb3cf63dd6e3e Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Thu, 16 Jan 2020 12:17:17 -0800 Subject: NetworkRequest: Embed requestor uid & packageName Add the requestorUid & requestorPackageName fields to NetworkCapabilities. This is populated by CS when a new network request is received. These 2 requestor fields are also optionally used for network matching. All of the regular app initiated requests will have the requestor uid and package name set by connectivity service. Network agents can optionally set the requestorUid and requestorPackageName to restrict the network created only to the app that requested the network. This will help removing the necessity for the various specifiers to embed the uid & package name info in the specifier for network matching. Note: NetworkSpecifier.assertValidFromUid() is deprecated & removed in favor of setting the uid/package name on the agent to restrict the network to a certain app (useful for wifi peer to peer API & wifi aware). Bug: 144102365 Test: Verified that wifi network request related CTS verifier tests pass. Test: Device boots up and connects to wifi networks Change-Id: I207c446108afdac7ee2c25e6bbcbc37c4e3f6529 --- wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java | 6 ------ wifi/java/android/net/wifi/WifiNetworkSpecifier.java | 8 -------- .../android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java | 6 ------ wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java | 8 -------- 4 files changed, 28 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java index 04d2e1a8b5dd..d4ac67ed2a21 100644 --- a/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java +++ b/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java @@ -198,12 +198,6 @@ public final class WifiNetworkAgentSpecifier extends NetworkSpecifier implements return sb.toString(); } - @Override - public void assertValidFromUid(int requestorUid) { - throw new IllegalStateException("WifiNetworkAgentSpecifier should never be used " - + "for requests."); - } - @Override public NetworkSpecifier redact() { return null; diff --git a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java index 444e1ef041e8..53778cf69665 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java +++ b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java @@ -618,12 +618,4 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc // not make much sense! return equals(other); } - - /** @hide */ - @Override - public void assertValidFromUid(int requestorUid) { - if (this.requestorUid != requestorUid) { - throw new SecurityException("mismatched UIDs"); - } - } } diff --git a/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java b/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java index c66733472d0e..a4b3e86398a8 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareAgentNetworkSpecifier.java @@ -142,12 +142,6 @@ public class WifiAwareAgentNetworkSpecifier extends NetworkSpecifier implements return mNetworkSpecifiers.contains(nsBytes); } - @Override - public void assertValidFromUid(int requestorUid) { - throw new SecurityException( - "WifiAwareAgentNetworkSpecifier should not be used in network requests"); - } - @Override public NetworkSpecifier redact() { return null; diff --git a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java index 5a4ed3c2f5e3..a4881850cf2c 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java @@ -288,14 +288,6 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements return sb.toString(); } - /** @hide */ - @Override - public void assertValidFromUid(int requestorUid) { - if (this.requestorUid != requestorUid) { - throw new SecurityException("mismatched UIDs"); - } - } - /** * A builder class for a Wi-Fi Aware network specifier to set up an Aware connection with a * peer. -- cgit v1.2.3 From cb3d65281bd6ce0949a74f4ffa41344a899abd1c Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Thu, 16 Jan 2020 12:53:01 -0800 Subject: Wifi/WifiAware NetworkSpecifier: Stop storing uid/packageName The uid/packageName is stored in the container NetworkRequest object. Hence, this info will still be available to WifiNetworkFactory for it's usages. Note: Setting the uid/package name in the capabilities of the network agent will restrict access to the created networks. Bug: 144102365 Test: atest android.net.wifi Test: Verified that wifi network request related CTS verifier tests pass. Change-Id: Ibb2ca652fa510343efd0352578c3d0b2b6f2dbb0 --- .../net/wifi/WifiNetworkAgentSpecifier.java | 50 +----------- .../android/net/wifi/WifiNetworkSpecifier.java | 63 ++------------- .../android/net/wifi/aware/WifiAwareManager.java | 7 +- .../net/wifi/aware/WifiAwareNetworkSpecifier.java | 27 ++----- .../net/wifi/WifiNetworkAgentSpecifierTest.java | 94 ++++------------------ .../android/net/wifi/WifiNetworkSpecifierTest.java | 63 +++------------ .../aware/WifiAwareAgentNetworkSpecifierTest.java | 13 +-- .../net/wifi/aware/WifiAwareManagerTest.java | 2 +- 8 files changed, 47 insertions(+), 272 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java index d4ac67ed2a21..6632c162fcf9 100644 --- a/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java +++ b/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java @@ -27,7 +27,6 @@ import android.net.NetworkRequest; import android.net.NetworkSpecifier; import android.os.Parcel; import android.os.Parcelable; -import android.text.TextUtils; import java.util.Objects; @@ -41,33 +40,10 @@ public final class WifiNetworkAgentSpecifier extends NetworkSpecifier implements */ private final WifiConfiguration mWifiConfiguration; - /** - * The UID of the app that requested a specific wifi network using {@link WifiNetworkSpecifier}. - * - * Will only be filled when the device connects to a wifi network as a result of a - * {@link NetworkRequest} with {@link WifiNetworkSpecifier}. Will be set to -1 if the device - * auto-connected to a wifi network. - */ - private final int mOriginalRequestorUid; - - /** - * The package name of the app that requested a specific wifi network using - * {@link WifiNetworkSpecifier}. - * - * Will only be filled when the device connects to a wifi network as a result of a - * {@link NetworkRequest} with {@link WifiNetworkSpecifier}. Will be set to null if the device - * auto-connected to a wifi network. - */ - private final String mOriginalRequestorPackageName; - - public WifiNetworkAgentSpecifier(@NonNull WifiConfiguration wifiConfiguration, - int originalRequestorUid, - @Nullable String originalRequestorPackageName) { + public WifiNetworkAgentSpecifier(@NonNull WifiConfiguration wifiConfiguration) { checkNotNull(wifiConfiguration); mWifiConfiguration = wifiConfiguration; - mOriginalRequestorUid = originalRequestorUid; - mOriginalRequestorPackageName = originalRequestorPackageName; } /** @@ -78,10 +54,7 @@ public final class WifiNetworkAgentSpecifier extends NetworkSpecifier implements @Override public WifiNetworkAgentSpecifier createFromParcel(@NonNull Parcel in) { WifiConfiguration wifiConfiguration = in.readParcelable(null); - int originalRequestorUid = in.readInt(); - String originalRequestorPackageName = in.readString(); - return new WifiNetworkAgentSpecifier( - wifiConfiguration, originalRequestorUid, originalRequestorPackageName); + return new WifiNetworkAgentSpecifier(wifiConfiguration); } @Override @@ -98,8 +71,6 @@ public final class WifiNetworkAgentSpecifier extends NetworkSpecifier implements @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeParcelable(mWifiConfiguration, flags); - dest.writeInt(mOriginalRequestorUid); - dest.writeString(mOriginalRequestorPackageName); } @Override @@ -149,12 +120,6 @@ public final class WifiNetworkAgentSpecifier extends NetworkSpecifier implements this.mWifiConfiguration.allowedKeyManagement)) { return false; } - if (ns.requestorUid != this.mOriginalRequestorUid) { - return false; - } - if (!TextUtils.equals(ns.requestorPackageName, this.mOriginalRequestorPackageName)) { - return false; - } return true; } @@ -163,9 +128,7 @@ public final class WifiNetworkAgentSpecifier extends NetworkSpecifier implements return Objects.hash( mWifiConfiguration.SSID, mWifiConfiguration.BSSID, - mWifiConfiguration.allowedKeyManagement, - mOriginalRequestorUid, - mOriginalRequestorPackageName); + mWifiConfiguration.allowedKeyManagement); } @Override @@ -180,10 +143,7 @@ public final class WifiNetworkAgentSpecifier extends NetworkSpecifier implements return Objects.equals(this.mWifiConfiguration.SSID, lhs.mWifiConfiguration.SSID) && Objects.equals(this.mWifiConfiguration.BSSID, lhs.mWifiConfiguration.BSSID) && Objects.equals(this.mWifiConfiguration.allowedKeyManagement, - lhs.mWifiConfiguration.allowedKeyManagement) - && mOriginalRequestorUid == lhs.mOriginalRequestorUid - && TextUtils.equals(mOriginalRequestorPackageName, - lhs.mOriginalRequestorPackageName); + lhs.mWifiConfiguration.allowedKeyManagement); } @Override @@ -192,8 +152,6 @@ public final class WifiNetworkAgentSpecifier extends NetworkSpecifier implements sb.append("WifiConfiguration=") .append(", SSID=").append(mWifiConfiguration.SSID) .append(", BSSID=").append(mWifiConfiguration.BSSID) - .append(", mOriginalRequestorUid=").append(mOriginalRequestorUid) - .append(", mOriginalRequestorPackageName=").append(mOriginalRequestorPackageName) .append("]"); return sb.toString(); } diff --git a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java index 53778cf69665..3d946c9f887d 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java +++ b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java @@ -20,7 +20,6 @@ import static com.android.internal.util.Preconditions.checkNotNull; import android.annotation.NonNull; import android.annotation.Nullable; -import android.app.Application; import android.net.MacAddress; import android.net.MatchAllNetworkSpecifier; import android.net.NetworkRequest; @@ -28,13 +27,9 @@ import android.net.NetworkSpecifier; import android.os.Parcel; import android.os.Parcelable; import android.os.PatternMatcher; -import android.os.Process; import android.text.TextUtils; -import android.util.Log; import android.util.Pair; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.nio.charset.CharsetEncoder; import java.nio.charset.StandardCharsets; import java.util.Objects; @@ -438,24 +433,7 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc return new WifiNetworkSpecifier( mSsidPatternMatcher, mBssidPatternMatcher, - buildWifiConfiguration(), - Process.myUid(), - getCurrentApplicationReflectively().getApplicationContext().getOpPackageName()); - } - - // TODO(b/144102365): Remove once refactor is complete - private static Application getCurrentApplicationReflectively() { - try { - // reflection for static method android.app.ActivityThread#currentApplication() - Class klass = Class.forName("android.app.ActivityThread"); - Method currentApplicationMethod = klass.getDeclaredMethod("currentApplication"); - Object result = currentApplicationMethod.invoke(null); - return (Application) result; - } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException - | InvocationTargetException e) { - Log.e(TAG, "Failed to call ActivityThread#currentApplication() reflectively!", e); - throw new RuntimeException(e); - } + buildWifiConfiguration()); } } @@ -483,20 +461,6 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc */ public final WifiConfiguration wifiConfiguration; - /** - * The UID of the process initializing this network specifier. Validated by receiver using - * checkUidIfNecessary() and is used by satisfiedBy() to determine whether the specifier - * matches the offered network. - * @hide - */ - public final int requestorUid; - - /** - * The package name of the app initializing this network specifier. - * @hide - */ - public final String requestorPackageName; - /** @hide */ public WifiNetworkSpecifier() throws IllegalAccessException { throw new IllegalAccessException("Use the builder to create an instance"); @@ -505,18 +469,14 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc /** @hide */ public WifiNetworkSpecifier(@NonNull PatternMatcher ssidPatternMatcher, @NonNull Pair bssidPatternMatcher, - @NonNull WifiConfiguration wifiConfiguration, - int requestorUid, @NonNull String requestorPackageName) { + @NonNull WifiConfiguration wifiConfiguration) { checkNotNull(ssidPatternMatcher); checkNotNull(bssidPatternMatcher); checkNotNull(wifiConfiguration); - checkNotNull(requestorPackageName); this.ssidPatternMatcher = ssidPatternMatcher; this.bssidPatternMatcher = bssidPatternMatcher; this.wifiConfiguration = wifiConfiguration; - this.requestorUid = requestorUid; - this.requestorPackageName = requestorPackageName; } public static final @NonNull Creator CREATOR = @@ -529,10 +489,8 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc Pair bssidPatternMatcher = Pair.create(baseAddress, mask); WifiConfiguration wifiConfiguration = in.readParcelable(null); - int requestorUid = in.readInt(); - String requestorPackageName = in.readString(); return new WifiNetworkSpecifier(ssidPatternMatcher, bssidPatternMatcher, - wifiConfiguration, requestorUid, requestorPackageName); + wifiConfiguration); } @Override @@ -552,18 +510,13 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc dest.writeParcelable(bssidPatternMatcher.first, flags); dest.writeParcelable(bssidPatternMatcher.second, flags); dest.writeParcelable(wifiConfiguration, flags); - dest.writeInt(requestorUid); - dest.writeString(requestorPackageName); } @Override public int hashCode() { return Objects.hash( - ssidPatternMatcher.getPath(), - ssidPatternMatcher.getType(), - bssidPatternMatcher, - wifiConfiguration.allowedKeyManagement, - requestorUid, requestorPackageName); + ssidPatternMatcher.getPath(), ssidPatternMatcher.getType(), bssidPatternMatcher, + wifiConfiguration.allowedKeyManagement); } @Override @@ -582,9 +535,7 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc && Objects.equals(this.bssidPatternMatcher, lhs.bssidPatternMatcher) && Objects.equals(this.wifiConfiguration.allowedKeyManagement, - lhs.wifiConfiguration.allowedKeyManagement) - && requestorUid == lhs.requestorUid - && TextUtils.equals(requestorPackageName, lhs.requestorPackageName); + lhs.wifiConfiguration.allowedKeyManagement); } @Override @@ -595,8 +546,6 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc .append(", BSSID Match pattern=").append(bssidPatternMatcher) .append(", SSID=").append(wifiConfiguration.SSID) .append(", BSSID=").append(wifiConfiguration.BSSID) - .append(", requestorUid=").append(requestorUid) - .append(", requestorPackageName=").append(requestorPackageName) .append("]") .toString(); } diff --git a/wifi/java/android/net/wifi/aware/WifiAwareManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java index 81bf81e40199..2ebaa1805b2b 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java @@ -34,7 +34,6 @@ import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; -import android.os.Process; import android.os.RemoteException; import android.util.Log; @@ -447,8 +446,7 @@ public class WifiAwareManager { pmk, passphrase, 0, // no port info for deprecated IB APIs - -1, // no transport info for deprecated IB APIs - Process.myUid()); + -1); // no transport info for deprecated IB APIs } /** @hide */ @@ -488,8 +486,7 @@ public class WifiAwareManager { pmk, passphrase, 0, // no port info for OOB APIs - -1, // no transport protocol info for OOB APIs - Process.myUid()); + -1); // no transport protocol info for OOB APIs } private static class WifiAwareEventCallbackProxy extends IWifiAwareEventCallback.Stub { diff --git a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java index a4881850cf2c..65ac1ab26064 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java @@ -23,7 +23,6 @@ import android.annotation.NonNull; import android.net.NetworkSpecifier; import android.os.Parcel; import android.os.Parcelable; -import android.os.Process; import android.text.TextUtils; import java.util.Arrays; @@ -144,19 +143,9 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements */ public final int transportProtocol; - /** - * The UID of the process initializing this network specifier. Validated by receiver using - * checkUidIfNecessary() and is used by satisfiedBy() to determine whether matches the - * offered network. - * - * @hide - */ - public final int requestorUid; - /** @hide */ public WifiAwareNetworkSpecifier(int type, int role, int clientId, int sessionId, int peerId, - byte[] peerMac, byte[] pmk, String passphrase, int port, int transportProtocol, - int requestorUid) { + byte[] peerMac, byte[] pmk, String passphrase, int port, int transportProtocol) { this.type = type; this.role = role; this.clientId = clientId; @@ -167,7 +156,6 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements this.passphrase = passphrase; this.port = port; this.transportProtocol = transportProtocol; - this.requestorUid = requestorUid; } public static final @android.annotation.NonNull Creator CREATOR = @@ -184,8 +172,7 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements in.createByteArray(), // pmk in.readString(), // passphrase in.readInt(), // port - in.readInt(), // transportProtocol - in.readInt()); // requestorUid + in.readInt()); // transportProtocol } @Override @@ -221,7 +208,6 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements dest.writeString(passphrase); dest.writeInt(port); dest.writeInt(transportProtocol); - dest.writeInt(requestorUid); } /** @hide */ @@ -238,7 +224,7 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements @Override public int hashCode() { return Objects.hash(type, role, clientId, sessionId, peerId, Arrays.hashCode(peerMac), - Arrays.hashCode(pmk), passphrase, port, transportProtocol, requestorUid); + Arrays.hashCode(pmk), passphrase, port, transportProtocol); } /** @hide */ @@ -263,8 +249,7 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements && Arrays.equals(pmk, lhs.pmk) && Objects.equals(passphrase, lhs.passphrase) && port == lhs.port - && transportProtocol == lhs.transportProtocol - && requestorUid == lhs.requestorUid; + && transportProtocol == lhs.transportProtocol; } /** @hide */ @@ -283,7 +268,7 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements // masking PII .append(", passphrase=").append((passphrase == null) ? "" : "") .append(", port=").append(port).append(", transportProtocol=") - .append(transportProtocol).append(", requestorUid=").append(requestorUid) + .append(transportProtocol) .append("]"); return sb.toString(); } @@ -455,7 +440,7 @@ public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements return new WifiAwareNetworkSpecifier( WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB, role, mDiscoverySession.mClientId, mDiscoverySession.mSessionId, mPeerHandle.peerId, - null, mPmk, mPskPassphrase, mPort, mTransportProtocol, Process.myUid()); + null, mPmk, mPskPassphrase, mPort, mTransportProtocol); } } } diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java index adc41f0df4b4..0233ee2e2785 100644 --- a/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java +++ b/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java @@ -22,7 +22,6 @@ import static org.junit.Assert.assertTrue; import android.net.MacAddress; import android.net.MatchAllNetworkSpecifier; -import android.net.NetworkRequest; import android.os.Parcel; import android.os.PatternMatcher; import android.util.Pair; @@ -36,10 +35,6 @@ import org.junit.Test; */ @SmallTest public class WifiNetworkAgentSpecifierTest { - private static final int TEST_UID = 5; - private static final int TEST_UID_1 = 8; - private static final String TEST_PACKAGE = "com.test"; - private static final String TEST_PACKAGE_1 = "com.test.1"; private static final String TEST_SSID = "Test123"; private static final String TEST_SSID_PATTERN = "Test"; private static final String TEST_SSID_1 = "456test"; @@ -70,16 +65,6 @@ public class WifiNetworkAgentSpecifierTest { assertEquals(specifier, parcelSpecifier); } - /** - * Validate that the NetworkAgentSpecifier cannot be used in a {@link NetworkRequest} by apps. - */ - @Test(expected = IllegalStateException.class) - public void testWifiNetworkAgentSpecifierNotUsedInNetworkRequest() { - WifiNetworkAgentSpecifier specifier = createDefaultNetworkAgentSpecifier(); - - specifier.assertValidFromUid(TEST_UID); - } - /** * Validate NetworkAgentSpecifier equals with itself. * a) Create network agent specifier 1 for WPA_PSK network @@ -105,15 +90,13 @@ public class WifiNetworkAgentSpecifierTest { WifiConfiguration wifiConfiguration1 = createDefaultWifiConfiguration(); WifiNetworkAgentSpecifier specifier1 = new WifiNetworkAgentSpecifier( - wifiConfiguration1, - TEST_UID, TEST_PACKAGE); + wifiConfiguration1); WifiConfiguration wifiConfiguration2 = new WifiConfiguration(wifiConfiguration1); wifiConfiguration2.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkAgentSpecifier specifier2 = new WifiNetworkAgentSpecifier( - wifiConfiguration2, - TEST_UID, TEST_PACKAGE); + wifiConfiguration2); assertFalse(specifier2.equals(specifier1)); } @@ -129,15 +112,13 @@ public class WifiNetworkAgentSpecifierTest { WifiConfiguration wifiConfiguration1 = createDefaultWifiConfiguration(); WifiNetworkAgentSpecifier specifier1 = new WifiNetworkAgentSpecifier( - wifiConfiguration1, - TEST_UID, TEST_PACKAGE); + wifiConfiguration1); WifiConfiguration wifiConfiguration2 = new WifiConfiguration(wifiConfiguration1); wifiConfiguration2.SSID = TEST_SSID_1; WifiNetworkAgentSpecifier specifier2 = new WifiNetworkAgentSpecifier( - wifiConfiguration2, - TEST_UID, TEST_PACKAGE); + wifiConfiguration2); assertFalse(specifier2.equals(specifier1)); } @@ -153,15 +134,13 @@ public class WifiNetworkAgentSpecifierTest { WifiConfiguration wifiConfiguration1 = createDefaultWifiConfiguration(); WifiNetworkAgentSpecifier specifier1 = new WifiNetworkAgentSpecifier( - wifiConfiguration1, - TEST_UID, TEST_PACKAGE); + wifiConfiguration1); WifiConfiguration wifiConfiguration2 = new WifiConfiguration(wifiConfiguration1); wifiConfiguration2.BSSID = TEST_BSSID_1; WifiNetworkAgentSpecifier specifier2 = new WifiNetworkAgentSpecifier( - wifiConfiguration2, - TEST_UID, TEST_PACKAGE); + wifiConfiguration2); assertFalse(specifier2.equals(specifier1)); } @@ -215,8 +194,7 @@ public class WifiNetworkAgentSpecifierTest { WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier( ssidPattern, bssidPattern, - wificonfigurationNetworkSpecifier, - TEST_UID, TEST_PACKAGE); + wificonfigurationNetworkSpecifier); assertTrue(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier)); assertTrue(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier)); @@ -244,8 +222,7 @@ public class WifiNetworkAgentSpecifierTest { WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier( ssidPattern, bssidPattern, - wificonfigurationNetworkSpecifier, - TEST_UID, TEST_PACKAGE); + wificonfigurationNetworkSpecifier); assertTrue(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier)); assertTrue(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier)); @@ -273,8 +250,7 @@ public class WifiNetworkAgentSpecifierTest { WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier( ssidPattern, bssidPattern, - wificonfigurationNetworkSpecifier, - TEST_UID, TEST_PACKAGE); + wificonfigurationNetworkSpecifier); assertTrue(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier)); assertTrue(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier)); @@ -293,8 +269,7 @@ public class WifiNetworkAgentSpecifierTest { wifiConfigurationNetworkAgent.SSID = "\"" + TEST_SSID_1 + "\""; WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = new WifiNetworkAgentSpecifier( - wifiConfigurationNetworkAgent, - TEST_UID, TEST_PACKAGE); + wifiConfigurationNetworkAgent); PatternMatcher ssidPattern = new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX); @@ -306,8 +281,7 @@ public class WifiNetworkAgentSpecifierTest { WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier( ssidPattern, bssidPattern, - wificonfigurationNetworkSpecifier, - TEST_UID, TEST_PACKAGE); + wificonfigurationNetworkSpecifier); assertFalse(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier)); assertFalse(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier)); @@ -326,8 +300,7 @@ public class WifiNetworkAgentSpecifierTest { wifiConfigurationNetworkAgent.BSSID = TEST_BSSID_1; WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = new WifiNetworkAgentSpecifier( - wifiConfigurationNetworkAgent, - TEST_UID, TEST_PACKAGE); + wifiConfigurationNetworkAgent); PatternMatcher ssidPattern = new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB); @@ -340,8 +313,7 @@ public class WifiNetworkAgentSpecifierTest { WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier( ssidPattern, bssidPattern, - wificonfigurationNetworkSpecifier, - TEST_UID, TEST_PACKAGE); + wificonfigurationNetworkSpecifier); assertFalse(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier)); assertFalse(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier)); @@ -360,8 +332,7 @@ public class WifiNetworkAgentSpecifierTest { wifiConfigurationNetworkAgent.BSSID = TEST_BSSID_1; WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = new WifiNetworkAgentSpecifier( - wifiConfigurationNetworkAgent, - TEST_UID, TEST_PACKAGE); + wifiConfigurationNetworkAgent); PatternMatcher ssidPattern = new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX); @@ -374,8 +345,7 @@ public class WifiNetworkAgentSpecifierTest { WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier( ssidPattern, bssidPattern, - wificonfigurationNetworkSpecifier, - TEST_UID, TEST_PACKAGE); + wificonfigurationNetworkSpecifier); assertFalse(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier)); assertFalse(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier)); @@ -402,41 +372,12 @@ public class WifiNetworkAgentSpecifierTest { WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier( ssidPattern, bssidPattern, - wificonfigurationNetworkSpecifier, - TEST_UID, TEST_PACKAGE); + wificonfigurationNetworkSpecifier); assertFalse(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier)); assertFalse(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier)); } - /** - * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching. - * a) Create network agent specifier for WPA_PSK network - * b) Create network specifier with matching SSID and BSSID pattern, but different UID. - * c) Ensure that the agent specifier is not satisfied by specifier. - */ - @Test - public void - testWifiNetworkAgentSpecifierDoesNotSatisfyNetworkSpecifierWithDifferentUid() { - WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = createDefaultNetworkAgentSpecifier(); - - PatternMatcher ssidPattern = - new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX); - Pair bssidPattern = - Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS), - MacAddress.fromString(TEST_BSSID_OUI_MASK)); - WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration(); - wificonfigurationNetworkSpecifier.allowedKeyManagement - .set(WifiConfiguration.KeyMgmt.WPA_PSK); - WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier( - ssidPattern, - bssidPattern, - wificonfigurationNetworkSpecifier, - TEST_UID_1, TEST_PACKAGE_1); - - assertFalse(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier)); - assertFalse(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier)); - } private WifiConfiguration createDefaultWifiConfiguration() { WifiConfiguration wifiConfiguration = new WifiConfiguration(); @@ -448,8 +389,7 @@ public class WifiNetworkAgentSpecifierTest { } private WifiNetworkAgentSpecifier createDefaultNetworkAgentSpecifier() { - return new WifiNetworkAgentSpecifier(createDefaultWifiConfiguration(), TEST_UID, - TEST_PACKAGE); + return new WifiNetworkAgentSpecifier(createDefaultWifiConfiguration()); } } diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java index 16197443b9d9..3b6723613c50 100644 --- a/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java +++ b/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java @@ -29,7 +29,6 @@ import android.net.MatchAllNetworkSpecifier; import android.net.NetworkSpecifier; import android.os.Parcel; import android.os.PatternMatcher; -import android.os.Process; import android.util.Pair; import androidx.test.filters.SmallTest; @@ -41,8 +40,6 @@ import org.junit.Test; */ @SmallTest public class WifiNetworkSpecifierTest { - private static final int TEST_UID = 5; - private static final String TEST_PACKAGE_NAME = "com.test"; private static final String TEST_SSID = "Test123"; private static final String TEST_BSSID_OUI_BASE_ADDRESS = "12:12:12:00:00:00"; private static final String TEST_BSSID_OUI_MASK = "ff:ff:ff:00:00:00"; @@ -62,7 +59,6 @@ public class WifiNetworkSpecifierTest { assertTrue(specifier instanceof WifiNetworkSpecifier); WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier; - assertEquals(Process.myUid(), wifiNetworkSpecifier.requestorUid); assertEquals(TEST_SSID, wifiNetworkSpecifier.ssidPatternMatcher.getPath()); assertEquals(PATTERN_PREFIX, wifiNetworkSpecifier.ssidPatternMatcher.getType()); assertEquals(WifiManager.ALL_ZEROS_MAC_ADDRESS, @@ -367,8 +363,7 @@ public class WifiNetworkSpecifierTest { new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL), Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS), MacAddress.fromString(TEST_BSSID_OUI_MASK)), - wifiConfiguration, - TEST_UID, TEST_PACKAGE_NAME); + wifiConfiguration); Parcel parcelW = Parcel.obtain(); specifier.writeToParcel(parcelW, 0); @@ -399,8 +394,7 @@ public class WifiNetworkSpecifierTest { new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL), Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS), MacAddress.fromString(TEST_BSSID_OUI_MASK)), - wifiConfiguration, - TEST_UID, TEST_PACKAGE_NAME); + wifiConfiguration); assertTrue(specifier.satisfiedBy(null)); assertTrue(specifier.satisfiedBy(new MatchAllNetworkSpecifier())); @@ -422,15 +416,13 @@ public class WifiNetworkSpecifierTest { new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL), Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS), MacAddress.fromString(TEST_BSSID_OUI_MASK)), - wifiConfiguration, - TEST_UID, TEST_PACKAGE_NAME); + wifiConfiguration); WifiNetworkSpecifier specifier2 = new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL), Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS), MacAddress.fromString(TEST_BSSID_OUI_MASK)), - wifiConfiguration, - TEST_UID, TEST_PACKAGE_NAME); + wifiConfiguration); assertTrue(specifier2.satisfiedBy(specifier1)); } @@ -451,8 +443,7 @@ public class WifiNetworkSpecifierTest { new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL), Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS), MacAddress.fromString(TEST_BSSID_OUI_MASK)), - wifiConfiguration1, - TEST_UID, TEST_PACKAGE_NAME); + wifiConfiguration1); WifiConfiguration wifiConfiguration2 = new WifiConfiguration(); wifiConfiguration2.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); @@ -460,8 +451,7 @@ public class WifiNetworkSpecifierTest { new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL), Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS), MacAddress.fromString(TEST_BSSID_OUI_MASK)), - wifiConfiguration2, - TEST_UID, TEST_PACKAGE_NAME); + wifiConfiguration2); assertFalse(specifier2.satisfiedBy(specifier1)); } @@ -482,15 +472,13 @@ public class WifiNetworkSpecifierTest { new WifiNetworkSpecifier(new PatternMatcher("", PATTERN_LITERAL), Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS), MacAddress.fromString(TEST_BSSID_OUI_MASK)), - wifiConfiguration, - TEST_UID, TEST_PACKAGE_NAME); + wifiConfiguration); WifiNetworkSpecifier specifier2 = new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL), Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS), MacAddress.fromString(TEST_BSSID_OUI_MASK)), - wifiConfiguration, - TEST_UID, TEST_PACKAGE_NAME); + wifiConfiguration); assertFalse(specifier2.satisfiedBy(specifier1)); } @@ -511,44 +499,13 @@ public class WifiNetworkSpecifierTest { new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL), Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS), MacAddress.fromString(TEST_BSSID_OUI_MASK)), - wifiConfiguration, - TEST_UID, TEST_PACKAGE_NAME); + wifiConfiguration); WifiNetworkSpecifier specifier2 = new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL), Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS), - wifiConfiguration, - TEST_UID, TEST_PACKAGE_NAME); - - assertFalse(specifier2.satisfiedBy(specifier1)); - } - - /** - * Validate NetworkSpecifier matching. - * a) Create network specifier 1 for WPA_PSK network - * b) Create network specifier 2 with different package name . - * c) Ensure that the specifier 2 is not satisfied by specifier 1. - */ - @Test - public void testWifiNetworkSpecifierDoesNotSatisfyWhenPackageNameDifferent() { - WifiConfiguration wifiConfiguration = new WifiConfiguration(); - wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); - wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY; - - WifiNetworkSpecifier specifier1 = - new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL), - Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS), - MacAddress.fromString(TEST_BSSID_OUI_MASK)), - wifiConfiguration, - TEST_UID, TEST_PACKAGE_NAME); - - WifiNetworkSpecifier specifier2 = - new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL), - Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS), - MacAddress.fromString(TEST_BSSID_OUI_MASK)), - wifiConfiguration, - TEST_UID, TEST_PACKAGE_NAME + "blah"); + wifiConfiguration); assertFalse(specifier2.satisfiedBy(specifier1)); } diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareAgentNetworkSpecifierTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareAgentNetworkSpecifierTest.java index c3b62854f12c..81b02fa5f801 100644 --- a/wifi/tests/src/android/net/wifi/aware/WifiAwareAgentNetworkSpecifierTest.java +++ b/wifi/tests/src/android/net/wifi/aware/WifiAwareAgentNetworkSpecifierTest.java @@ -162,17 +162,6 @@ public class WifiAwareAgentNetworkSpecifierTest { collector.checkThat("Match unexpected", oldNs.satisfiedBy(newNs), equalTo(false)); } - /** - * Validate that agent network specifier cannot be used as in network requests - i.e. that - * throws an exception when queried for UID validity. - */ - @Test(expected = SecurityException.class) - public void testNoUsageInRequest() { - WifiAwareAgentNetworkSpecifier dut = new WifiAwareAgentNetworkSpecifier(); - - dut.assertValidFromUid(0); - } - // utilities /** @@ -182,6 +171,6 @@ public class WifiAwareAgentNetworkSpecifierTest { WifiAwareNetworkSpecifier getDummyNetworkSpecifier(int clientId) { return new WifiAwareNetworkSpecifier(WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB, WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, clientId, 0, 0, new byte[6], - null, null, 10, 5, 0); + null, null, 10, 5); } } diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java index 65fbf5b099d4..c5f98045082b 100644 --- a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java +++ b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java @@ -1564,7 +1564,7 @@ public class WifiAwareManagerTest { WifiAwareNetworkSpecifier ns = new WifiAwareNetworkSpecifier(NETWORK_SPECIFIER_TYPE_IB, WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER, 5, 568, 334, HexEncoding.decode("000102030405".toCharArray(), false), - "01234567890123456789012345678901".getBytes(), "blah blah", 666, 4, 10001); + "01234567890123456789012345678901".getBytes(), "blah blah", 666, 4); Parcel parcelW = Parcel.obtain(); ns.writeToParcel(parcelW, 0); -- cgit v1.2.3 From d5ab2797ffd493a39bcca8eee47c2ac59285db4a Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 6 Feb 2020 10:45:22 -0800 Subject: Update WifiInfo#getSSID() doc to refer to UNKNOWN_SSID Use newly defined constant WifiManager#UNKNOWN_SSID instead of a raw string in the API doc. Bug: 145745815 Test: compiles Change-Id: If3ec88706275aedb66c7bdfb70b1a3a9109e1a4c --- wifi/java/android/net/wifi/WifiInfo.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java index 7c031eaaeaf4..24b2a8e8994f 100644 --- a/wifi/java/android/net/wifi/WifiInfo.java +++ b/wifi/java/android/net/wifi/WifiInfo.java @@ -449,9 +449,8 @@ public class WifiInfo implements Parcelable { *

    * If the SSID can be decoded as UTF-8, it will be returned surrounded by double * quotation marks. Otherwise, it is returned as a string of hex digits. - * The SSID may be - * <unknown ssid>, if there is no network currently connected or if the caller has - * insufficient permissions to access the SSID. + * The SSID may be {@link WifiManager#UNKNOWN_SSID}, if there is no network currently connected + * or if the caller has insufficient permissions to access the SSID. *

    *

    * Prior to {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}, this method -- cgit v1.2.3 From 4745564251358a29d59d95cbe41c50649f80750d Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 6 Feb 2020 11:26:10 -0800 Subject: getWifiActivityEnergyInfoAsync: throw NPE instead of IAE Null check should throw NullPointerException instead of IllegalArgumentException. Bug: 149015294 Test: atest WifiManagerTest Change-Id: I6d6f495a1e2e56d02c0709e1b7160e7b1ffb5737 --- wifi/java/android/net/wifi/WifiManager.java | 4 ++-- wifi/tests/src/android/net/wifi/WifiManagerTest.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 1dc4a069fe2f..a3cce7c00b3a 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -2625,8 +2625,8 @@ public class WifiManager { public void getWifiActivityEnergyInfoAsync( @NonNull @CallbackExecutor Executor executor, @NonNull OnWifiActivityEnergyInfoListener listener) { - if (executor == null) throw new IllegalArgumentException("executor cannot be null"); - if (listener == null) throw new IllegalArgumentException("listener cannot be null"); + Objects.requireNonNull(executor, "executor cannot be null"); + Objects.requireNonNull(listener, "listener cannot be null"); try { mService.getWifiActivityEnergyInfoAsync( new OnWifiActivityEnergyInfoProxy(executor, listener)); diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index a189d507a32a..6320f85eb974 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -1867,7 +1867,7 @@ public class WifiManagerTest { * Tests that passing a null Executor to {@link WifiManager#getWifiActivityEnergyInfoAsync} * throws an exception. */ - @Test(expected = IllegalArgumentException.class) + @Test(expected = NullPointerException.class) public void testGetWifiActivityInfoNullExecutor() throws Exception { mWifiManager.getWifiActivityEnergyInfoAsync(null, mOnWifiActivityEnergyInfoListener); } @@ -1876,7 +1876,7 @@ public class WifiManagerTest { * Tests that passing a null listener to {@link WifiManager#getWifiActivityEnergyInfoAsync} * throws an exception. */ - @Test(expected = IllegalArgumentException.class) + @Test(expected = NullPointerException.class) public void testGetWifiActivityInfoNullListener() throws Exception { mWifiManager.getWifiActivityEnergyInfoAsync(mExecutor, null); } -- cgit v1.2.3 From 368b170af6e71ec135c8513618bf791c22c0c179 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Wed, 5 Feb 2020 14:22:14 -0800 Subject: WifiManager: Add API for scan throttling Needed for moving away from using Settings.Global values as pseudo APIs. Bug: 148514485 Test: atest android.net.wifi Test: Verified wifi scan throttle toggle in Developer options Change-Id: I2e6e2d1fde22baeaddab18cf558e442d49c138dd --- wifi/java/android/net/wifi/IWifiManager.aidl | 4 ++ wifi/java/android/net/wifi/WifiManager.java | 44 ++++++++++++++++++++++ .../src/android/net/wifi/WifiManagerTest.java | 10 +++++ 3 files changed, 58 insertions(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 1f1c0c12cf21..221f64440969 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -266,4 +266,8 @@ interface IWifiManager * Return the Map of {@link WifiNetworkSuggestion} and the list of */ Map getMatchingScanResults(in List networkSuggestions, in List scanResults, String callingPackage, String callingFeatureId); + + void setScanThrottleEnabled(boolean enable); + + boolean isScanThrottleEnabled(); } diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index a3cce7c00b3a..1682023c3312 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -6118,4 +6118,48 @@ public class WifiManager { throw e.rethrowFromSystemServer(); } } + + /** + * Enable/disable wifi scan throttling from 3rd party apps. + * + *

    + * The throttling limits for apps are described in + * + * https://developer.android.com/guide/topics/connectivity/wifi-scan#wifi-scan-throttling + *

    + * + * @param enable true to allow scan throttling, false to disallow scan throttling. + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) + public void setScanThrottleEnabled(boolean enable) { + try { + mService.setScanThrottleEnabled(enable); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Get the persisted Wi-Fi scan throttle state. Defaults to true, unless changed by the user via + * Developer options. + * + *

    + * The throttling limits for apps are described in + * + * https://developer.android.com/guide/topics/connectivity/wifi-scan#wifi-scan-throttling + *

    + * + * @return true to indicate that scan throttling is enabled, false to indicate that scan + * throttling is disabled. + */ + @RequiresPermission(ACCESS_WIFI_STATE) + public boolean isScanThrottleEnabled() { + try { + return mService.isScanThrottleEnabled(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } } diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 6320f85eb974..53e9755eaf52 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -2380,4 +2380,14 @@ public class WifiManagerTest { verify(mWifiConnectedNetworkScorer).start(0); verify(mWifiConnectedNetworkScorer).stop(10); } + + @Test + public void testScanThrottle() throws Exception { + mWifiManager.setScanThrottleEnabled(true); + verify(mWifiService).setScanThrottleEnabled(true); + + when(mWifiService.isScanThrottleEnabled()).thenReturn(false); + assertFalse(mWifiManager.isScanThrottleEnabled()); + verify(mWifiService).isScanThrottleEnabled(); + } } -- cgit v1.2.3 From 0ebf6f17efd3b43a761cd945834ac726c6e9d1e8 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Thu, 6 Feb 2020 10:14:07 -0800 Subject: WifiOemMigrationHook: Rename class & methods to be more generic This class will hold all the mainline related migration logic. Currently, includes the config store migration hook. Will be adding the Settings migration hook here in a future CL. Bug: 148514485 Test: Compiles Change-Id: Ie66abbdaa720c0fe0deabc4e3de55e97ccac416e --- wifi/Android.bp | 2 +- .../net/wifi/WifiOemConfigStoreMigrationHook.java | 180 -------------------- .../android/net/wifi/WifiOemMigrationHook.java | 181 +++++++++++++++++++++ 3 files changed, 182 insertions(+), 181 deletions(-) delete mode 100755 wifi/java/android/net/wifi/WifiOemConfigStoreMigrationHook.java create mode 100755 wifi/java/android/net/wifi/WifiOemMigrationHook.java (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 6a29b1c36052..1763975e7770 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -47,7 +47,7 @@ filegroup { // framework-wifi.jar. This is not a good idea, should move WifiNetworkScoreCache // to a separate package. "java/android/net/wifi/WifiNetworkScoreCache.java", - "java/android/net/wifi/WifiOemConfigStoreMigrationHook.java", + "java/android/net/wifi/WifiOemMigrationHook.java", "java/android/net/wifi/wificond/*.java", ":libwificond_ipc_aidl", ], diff --git a/wifi/java/android/net/wifi/WifiOemConfigStoreMigrationHook.java b/wifi/java/android/net/wifi/WifiOemConfigStoreMigrationHook.java deleted file mode 100755 index 642dcb9211ae..000000000000 --- a/wifi/java/android/net/wifi/WifiOemConfigStoreMigrationHook.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (C) 2020 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 com.android.internal.util.Preconditions.checkNotNull; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.List; - -/** - * Class used to provide one time hooks for existing OEM devices to migrate their config store - * data to the wifi mainline module. - *

    - * Note: - *

  • OEM's need to implement {@link #load()} only if their - * existing config store format or file locations differs from the vanilla AOSP implementation ( - * which is what the wifi mainline module understands). - *
  • - *
  • The wifi mainline module will invoke {@link #load()} method on every bootup, its - * the responsibility of the OEM implementation to ensure that this method returns non-null data - * only on the first bootup. Once the migration is done, the OEM can safely delete their config - * store files and then return null on any subsequent reboots. The first & only relevant invocation - * of {@link #load()} occurs when a previously released device upgrades to the wifi - * mainline module from an OEM implementation of the wifi stack. - *
  • - * @hide - */ -@SystemApi -public final class WifiOemConfigStoreMigrationHook { - /** - * Container for all the wifi config data to migrate. - */ - public static final class MigrationData implements Parcelable { - /** - * Builder to create instance of {@link MigrationData}. - */ - public static final class Builder { - private List mUserSavedNetworkConfigurations; - private SoftApConfiguration mUserSoftApConfiguration; - - public Builder() { - mUserSavedNetworkConfigurations = null; - mUserSoftApConfiguration = null; - } - - /** - * Sets the list of all user's saved network configurations parsed from OEM config - * store files. - * - * @param userSavedNetworkConfigurations List of {@link WifiConfiguration} representing - * the list of user's saved networks - * @return Instance of {@link Builder} to enable chaining of the builder method. - */ - public @NonNull Builder setUserSavedNetworkConfigurations( - @NonNull List userSavedNetworkConfigurations) { - checkNotNull(userSavedNetworkConfigurations); - mUserSavedNetworkConfigurations = userSavedNetworkConfigurations; - return this; - } - - /** - * Sets the user's softap configuration parsed from OEM config store files. - * - * @param userSoftApConfiguration {@link SoftApConfiguration} representing user's - * SoftAp configuration - * @return Instance of {@link Builder} to enable chaining of the builder method. - */ - public @NonNull Builder setUserSoftApConfiguration( - @NonNull SoftApConfiguration userSoftApConfiguration) { - checkNotNull(userSoftApConfiguration); - mUserSoftApConfiguration = userSoftApConfiguration; - return this; - } - - /** - * Build an instance of {@link MigrationData}. - * - * @return Instance of {@link MigrationData}. - */ - public @NonNull MigrationData build() { - return new MigrationData(mUserSavedNetworkConfigurations, mUserSoftApConfiguration); - } - } - - private final List mUserSavedNetworkConfigurations; - private final SoftApConfiguration mUserSoftApConfiguration; - - private MigrationData( - @Nullable List userSavedNetworkConfigurations, - @Nullable SoftApConfiguration userSoftApConfiguration) { - mUserSavedNetworkConfigurations = userSavedNetworkConfigurations; - mUserSoftApConfiguration = userSoftApConfiguration; - } - - public static final @NonNull Parcelable.Creator CREATOR = - new Parcelable.Creator() { - @Override - public MigrationData createFromParcel(Parcel in) { - List userSavedNetworkConfigurations = - in.readArrayList(null); - SoftApConfiguration userSoftApConfiguration = in.readParcelable(null); - return new MigrationData( - userSavedNetworkConfigurations, userSoftApConfiguration); - } - - @Override - public MigrationData[] newArray(int size) { - return new MigrationData[size]; - } - }; - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(@NonNull Parcel dest, int flags) { - dest.writeList(mUserSavedNetworkConfigurations); - dest.writeParcelable(mUserSoftApConfiguration, flags); - } - - /** - * Returns list of all user's saved network configurations. - * - * Note: Only to be returned if there is any format change in how OEM persisted this info. - * @return List of {@link WifiConfiguration} representing the list of user's saved networks, - * or null if no migration necessary. - */ - @Nullable - public List getUserSavedNetworkConfigurations() { - return mUserSavedNetworkConfigurations; - } - - /** - * Returns user's softap configuration. - * - * Note: Only to be returned if there is any format change in how OEM persisted this info. - * @return {@link SoftApConfiguration} representing user's SoftAp configuration, - * or null if no migration necessary. - */ - @Nullable - public SoftApConfiguration getUserSoftApConfiguration() { - return mUserSoftApConfiguration; - } - } - - private WifiOemConfigStoreMigrationHook() { } - - /** - * Load data from OEM's config store. - * - * @return Instance of {@link MigrationData} for migrating data, null if no - * migration is necessary. - */ - @Nullable - public static MigrationData load() { - // Note: OEM's should add code to parse data from their config store format here! - return null; - } -} diff --git a/wifi/java/android/net/wifi/WifiOemMigrationHook.java b/wifi/java/android/net/wifi/WifiOemMigrationHook.java new file mode 100755 index 000000000000..22d778637101 --- /dev/null +++ b/wifi/java/android/net/wifi/WifiOemMigrationHook.java @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2020 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 com.android.internal.util.Preconditions.checkNotNull; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.List; + +/** + * Class used to provide one time hooks for existing OEM devices to migrate their config store + * data and other settings to the wifi mainline module. + * @hide + */ +@SystemApi +public final class WifiOemMigrationHook { + /** + * Container for all the wifi config data to migrate. + */ + public static final class ConfigStoreMigrationData implements Parcelable { + /** + * Builder to create instance of {@link ConfigStoreMigrationData}. + */ + public static final class Builder { + private List mUserSavedNetworkConfigurations; + private SoftApConfiguration mUserSoftApConfiguration; + + public Builder() { + mUserSavedNetworkConfigurations = null; + mUserSoftApConfiguration = null; + } + + /** + * Sets the list of all user's saved network configurations parsed from OEM config + * store files. + * + * @param userSavedNetworkConfigurations List of {@link WifiConfiguration} representing + * the list of user's saved networks + * @return Instance of {@link Builder} to enable chaining of the builder method. + */ + public @NonNull Builder setUserSavedNetworkConfigurations( + @NonNull List userSavedNetworkConfigurations) { + checkNotNull(userSavedNetworkConfigurations); + mUserSavedNetworkConfigurations = userSavedNetworkConfigurations; + return this; + } + + /** + * Sets the user's softap configuration parsed from OEM config store files. + * + * @param userSoftApConfiguration {@link SoftApConfiguration} representing user's + * SoftAp configuration + * @return Instance of {@link Builder} to enable chaining of the builder method. + */ + public @NonNull Builder setUserSoftApConfiguration( + @NonNull SoftApConfiguration userSoftApConfiguration) { + checkNotNull(userSoftApConfiguration); + mUserSoftApConfiguration = userSoftApConfiguration; + return this; + } + + /** + * Build an instance of {@link ConfigStoreMigrationData}. + * + * @return Instance of {@link ConfigStoreMigrationData}. + */ + public @NonNull ConfigStoreMigrationData build() { + return new ConfigStoreMigrationData( + mUserSavedNetworkConfigurations, mUserSoftApConfiguration); + } + } + + private final List mUserSavedNetworkConfigurations; + private final SoftApConfiguration mUserSoftApConfiguration; + + private ConfigStoreMigrationData( + @Nullable List userSavedNetworkConfigurations, + @Nullable SoftApConfiguration userSoftApConfiguration) { + mUserSavedNetworkConfigurations = userSavedNetworkConfigurations; + mUserSoftApConfiguration = userSoftApConfiguration; + } + + public static final @NonNull Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @Override + public ConfigStoreMigrationData createFromParcel(Parcel in) { + List userSavedNetworkConfigurations = + in.readArrayList(null); + SoftApConfiguration userSoftApConfiguration = in.readParcelable(null); + return new ConfigStoreMigrationData( + userSavedNetworkConfigurations, userSoftApConfiguration); + } + + @Override + public ConfigStoreMigrationData[] newArray(int size) { + return new ConfigStoreMigrationData[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeList(mUserSavedNetworkConfigurations); + dest.writeParcelable(mUserSoftApConfiguration, flags); + } + + /** + * Returns list of all user's saved network configurations. + * + * Note: Only to be returned if there is any format change in how OEM persisted this info. + * @return List of {@link WifiConfiguration} representing the list of user's saved networks, + * or null if no migration necessary. + */ + @Nullable + public List getUserSavedNetworkConfigurations() { + return mUserSavedNetworkConfigurations; + } + + /** + * Returns user's softap configuration. + * + * Note: Only to be returned if there is any format change in how OEM persisted this info. + * @return {@link SoftApConfiguration} representing user's SoftAp configuration, + * or null if no migration necessary. + */ + @Nullable + public SoftApConfiguration getUserSoftApConfiguration() { + return mUserSoftApConfiguration; + } + } + + private WifiOemMigrationHook() { } + + /** + * Load data from OEM's config store. + *

    + * Note: + *

  • OEM's need to implement {@link #loadFromConfigStore()} ()} only if their + * existing config store format or file locations differs from the vanilla AOSP implementation ( + * which is what the wifi mainline module understands). + *
  • + *
  • The wifi mainline module will invoke {@link #loadFromConfigStore()} method on every + * bootup, its the responsibility of the OEM implementation to ensure that this method returns + * non-null data only on the first bootup. Once the migration is done, the OEM can safely delete + * their config store files and then return null on any subsequent reboots. The first & only + * relevant invocation of {@link #loadFromConfigStore()} occurs when a previously released + * device upgrades to the wifi mainline module from an OEM implementation of the wifi stack. + *
  • + * + * @return Instance of {@link ConfigStoreMigrationData} for migrating data, null if no + * migration is necessary. + */ + @Nullable + public static ConfigStoreMigrationData loadFromConfigStore() { + // Note: OEM's should add code to parse data from their config store format here! + return null; + } +} -- cgit v1.2.3 From 869ef26936552e2cd536846810fec68a53b4faab Mon Sep 17 00:00:00 2001 From: lesl Date: Fri, 7 Feb 2020 15:20:51 +0800 Subject: softap: Add band (2 + 5)G convert when convert to WifiConfiguration Bug: 149116596 Test: atest frameworks/base/wifi/tests/ Test: atest android.net.wifi.cts.WifiManagerTest (convert will happen when run LOHS test) Change-Id: Ibd9df687f966cc864555503c9bb1776061da350d --- .../java/android/net/wifi/SoftApConfiguration.java | 3 ++ .../android/net/wifi/SoftApConfigurationTest.java | 40 ++++++++++++++++++---- 2 files changed, 36 insertions(+), 7 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java index c8fd2434e64f..0db3313ae137 100644 --- a/wifi/java/android/net/wifi/SoftApConfiguration.java +++ b/wifi/java/android/net/wifi/SoftApConfiguration.java @@ -519,6 +519,9 @@ public final class SoftApConfiguration implements Parcelable { case BAND_5GHZ: wifiConfig.apBand = WifiConfiguration.AP_BAND_5GHZ; break; + case BAND_2GHZ | BAND_5GHZ: + wifiConfig.apBand = WifiConfiguration.AP_BAND_ANY; + break; case BAND_ANY: wifiConfig.apBand = WifiConfiguration.AP_BAND_ANY; break; diff --git a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java index 2efdd97543a9..d9584885a045 100644 --- a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java @@ -287,17 +287,43 @@ public class SoftApConfigurationTest { @Test public void testToWifiConfigurationWithSupportedParameter() { - SoftApConfiguration softApConfig = new SoftApConfiguration.Builder() + SoftApConfiguration softApConfig_2g = new SoftApConfiguration.Builder() + .setPassphrase("secretsecret", + SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) + .setChannel(11, SoftApConfiguration.BAND_2GHZ) + .setHiddenSsid(true) + .build(); + WifiConfiguration wifiConfig_2g = softApConfig_2g.toWifiConfiguration(); + assertThat(wifiConfig_2g.getAuthType()).isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK); + assertThat(wifiConfig_2g.preSharedKey).isEqualTo("secretsecret"); + assertThat(wifiConfig_2g.apBand).isEqualTo(WifiConfiguration.AP_BAND_2GHZ); + assertThat(wifiConfig_2g.apChannel).isEqualTo(11); + assertThat(wifiConfig_2g.hiddenSSID).isEqualTo(true); + + SoftApConfiguration softApConfig_5g = new SoftApConfiguration.Builder() .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) .setChannel(149, SoftApConfiguration.BAND_5GHZ) .setHiddenSsid(true) .build(); - WifiConfiguration wifiConfig = softApConfig.toWifiConfiguration(); - assertThat(wifiConfig.getAuthType()).isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK); - assertThat(wifiConfig.preSharedKey).isEqualTo("secretsecret"); - assertThat(wifiConfig.apBand).isEqualTo(WifiConfiguration.AP_BAND_5GHZ); - assertThat(wifiConfig.apChannel).isEqualTo(149); - assertThat(wifiConfig.hiddenSSID).isEqualTo(true); + WifiConfiguration wifiConfig_5g = softApConfig_5g.toWifiConfiguration(); + assertThat(wifiConfig_5g.getAuthType()).isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK); + assertThat(wifiConfig_5g.preSharedKey).isEqualTo("secretsecret"); + assertThat(wifiConfig_5g.apBand).isEqualTo(WifiConfiguration.AP_BAND_5GHZ); + assertThat(wifiConfig_5g.apChannel).isEqualTo(149); + assertThat(wifiConfig_5g.hiddenSSID).isEqualTo(true); + + SoftApConfiguration softApConfig_2g5g = new SoftApConfiguration.Builder() + .setPassphrase("secretsecret", + SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) + .setBand(SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ) + .setHiddenSsid(true) + .build(); + WifiConfiguration wifiConfig_2g5g = softApConfig_2g5g.toWifiConfiguration(); + assertThat(wifiConfig_2g5g.getAuthType()).isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK); + assertThat(wifiConfig_2g5g.preSharedKey).isEqualTo("secretsecret"); + assertThat(wifiConfig_2g5g.apBand).isEqualTo(WifiConfiguration.AP_BAND_ANY); + assertThat(wifiConfig_2g5g.apChannel).isEqualTo(0); + assertThat(wifiConfig_2g5g.hiddenSSID).isEqualTo(true); } } -- cgit v1.2.3 From d1d95ec678571eb88f89f38fcab47c86c5d67b2f Mon Sep 17 00:00:00 2001 From: lesl Date: Fri, 7 Feb 2020 16:43:59 +0800 Subject: wifi: Correct java document description There are tethered mode and local mode API for softap. Update API description which only provide function for tethered mode. Test: make docs frameworks/base/wifi/ Bug: 137675368 Change-Id: I1719be50b78bc258606eac3bf5595aca59d7a9f4 --- wifi/java/android/net/wifi/WifiManager.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 1682023c3312..5ccc3aa429c6 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -2982,7 +2982,7 @@ public class WifiManager { } /** - * Start Soft AP (hotspot) mode with the specified configuration. + * Start Soft AP (hotspot) mode for tethering purposes with the specified configuration. * Note that starting Soft AP mode may disable station mode operation if the device does not * support concurrency. * @param wifiConfig SSID, security and channel details as part of WifiConfiguration, or null to @@ -3278,7 +3278,7 @@ public class WifiManager { } /** - * Gets the Wi-Fi enabled state. + * Gets the tethered Wi-Fi hotspot enabled state. * @return One of {@link #WIFI_AP_STATE_DISABLED}, * {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED}, * {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED} @@ -3297,8 +3297,8 @@ public class WifiManager { } /** - * Return whether Wi-Fi AP is enabled or disabled. - * @return {@code true} if Wi-Fi AP is enabled + * Return whether tethered Wi-Fi AP is enabled or disabled. + * @return {@code true} if tethered Wi-Fi AP is enabled * @see #getWifiApState() * * @hide @@ -3310,7 +3310,7 @@ public class WifiManager { } /** - * Gets the Wi-Fi AP Configuration. + * Gets the tethered Wi-Fi AP Configuration. * @return AP details in WifiConfiguration * * Note that AP detail may contain configuration which is cannot be represented @@ -3332,7 +3332,7 @@ public class WifiManager { } /** - * Gets the Wi-Fi AP Configuration. + * Gets the Wi-Fi tethered AP Configuration. * @return AP details in {@link SoftApConfiguration} * * @hide @@ -3349,7 +3349,7 @@ public class WifiManager { } /** - * Sets the Wi-Fi AP Configuration. + * Sets the tethered Wi-Fi AP Configuration. * @return {@code true} if the operation succeeded, {@code false} otherwise * * @deprecated This API is deprecated. Use {@link #setSoftApConfiguration(SoftApConfiguration)} @@ -3368,9 +3368,9 @@ public class WifiManager { } /** - * Sets the Wi-Fi AP Configuration. + * Sets the tethered Wi-Fi AP Configuration. * - * If the API is called while the soft AP is enabled, the configuration will apply to + * If the API is called while the tethered soft AP is enabled, the configuration will apply to * the current soft AP if the new configuration only includes * {@link SoftApConfiguration.Builder#setMaxNumberOfClients(int)} * or {@link SoftApConfiguration.Builder#setShutdownTimeoutMillis(int)} -- cgit v1.2.3 From 3d3138f06332614cbce268cb0d59e508869d767d Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Sat, 8 Feb 2020 17:46:44 -0800 Subject: Revert "[WIFICOND][API] Update channel API from array to list" This reverts commit 98b1d8d5a25249b64432746b18e40b084201cef8. [API council request] Bug: 148680192 Test: atest android.net.wifi Change-Id: Id532feaa0b18d681bda317a68c0ebbd43761d183 --- .../android/net/wifi/wificond/WifiCondManager.java | 17 +++++----- .../net/wifi/wificond/WifiCondManagerTest.java | 36 +--------------------- 2 files changed, 8 insertions(+), 45 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/wificond/WifiCondManager.java b/wifi/java/android/net/wifi/wificond/WifiCondManager.java index 7a31a5afab05..d542e64d496d 100644 --- a/wifi/java/android/net/wifi/wificond/WifiCondManager.java +++ b/wifi/java/android/net/wifi/wificond/WifiCondManager.java @@ -41,19 +41,16 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.stream.Collectors; /** - * This class encapsulates the interface the wificond (Wi-Fi Conductor) daemon presents to the - * Wi-Fi framework. The interface is only for use by the Wi-Fi framework and access is protected - * by SELinux permissions: only the system server and wpa_supplicant can use WifiCondManager. + * This class encapsulates the interface the wificond daemon presents to the Wi-Fi framework. The + * interface is only for use by the Wi-Fi framework and access is protected by SELinux permissions. * * @hide */ @@ -1046,13 +1043,13 @@ public class WifiCondManager { * WifiScanner.WIFI_BAND_5_GHZ * WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY * WifiScanner.WIFI_BAND_6_GHZ - * @return frequencies List of valid frequencies (MHz), or an empty list for error. + * @return frequencies vector of valid frequencies (MHz), or an empty array for error. * @throws IllegalArgumentException if band is not recognized. */ - public @NonNull List getChannelsMhzForBand(@WifiAnnotations.WifiBandBasic int band) { + public @NonNull int[] getChannelsMhzForBand(@WifiAnnotations.WifiBandBasic int band) { if (mWificond == null) { Log.e(TAG, "No valid wificond scanner interface handler"); - return Collections.emptyList(); + return new int[0]; } int[] result = null; try { @@ -1076,9 +1073,9 @@ public class WifiCondManager { Log.e(TAG, "Failed to request getChannelsForBand due to remote exception"); } if (result == null) { - return Collections.emptyList(); + result = new int[0]; } - return Arrays.stream(result).boxed().collect(Collectors.toList()); + return result; } /** Helper function to look up the interface handle using name */ diff --git a/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java b/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java index 32105be6ae4c..603cec695e1d 100644 --- a/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java +++ b/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java @@ -65,8 +65,6 @@ import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; import java.nio.charset.StandardCharsets; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -742,42 +740,10 @@ public class WifiCondManagerTest { verify(deathHandler).run(); // The handles should be cleared after death. - assertEquals(0, mWificondControl.getChannelsMhzForBand(WifiScanner.WIFI_BAND_5_GHZ).size()); + assertEquals(0, mWificondControl.getChannelsMhzForBand(WifiScanner.WIFI_BAND_5_GHZ).length); verify(mWificond, never()).getAvailable5gNonDFSChannels(); } - /** - * Verify primitive array to list translation of channel API. - */ - @Test - public void testGetChannels() throws Exception { - int[] resultsEmpty = new int[0]; - int[] resultsSingle = new int[]{100}; - int[] resultsMore = new int[]{100, 200}; - - List emptyList = Collections.emptyList(); - List singleList = Arrays.asList(100); - List moreList = Arrays.asList(100, 200); - - when(mWificond.getAvailable2gChannels()).thenReturn(null); - assertEquals(mWificondControl.getChannelsMhzForBand(WifiScanner.WIFI_BAND_24_GHZ), - emptyList); - assertEquals(mWificondControl.getChannelsMhzForBand(WifiScanner.WIFI_BAND_5_GHZ), - emptyList); - - when(mWificond.getAvailable2gChannels()).thenReturn(resultsEmpty); - assertEquals(mWificondControl.getChannelsMhzForBand(WifiScanner.WIFI_BAND_24_GHZ), - emptyList); - - when(mWificond.getAvailable2gChannels()).thenReturn(resultsSingle); - assertEquals(mWificondControl.getChannelsMhzForBand(WifiScanner.WIFI_BAND_24_GHZ), - singleList); - - when(mWificond.getAvailable2gChannels()).thenReturn(resultsMore); - assertEquals(mWificondControl.getChannelsMhzForBand(WifiScanner.WIFI_BAND_24_GHZ), - moreList); - } - /** * sendMgmtFrame() should fail if a null callback is passed in. */ -- cgit v1.2.3 From 623e9afbf25caadd78ba928aa458a5d274f988a4 Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Fri, 7 Feb 2020 09:30:41 -0800 Subject: [Passpoint] Allow multiple profiles w/identical FQDN Allow to install multiple Passpoint profiles with identical FQDN. The FQDN is not used as a key for profiles. Existing Passpoint APIs that require FQDN (e.g. remove, allow auto-join) , will apply the request to all matching profiles with the same FQDN. Bug: 148556276 Test: atest android.net.wifi Test: atest com.android.server.wifi Change-Id: Ife57367ea974ae361478ff66b2bd9ac1af0fd6ee --- wifi/java/android/net/wifi/IWifiManager.aidl | 2 + wifi/java/android/net/wifi/WifiConfiguration.java | 41 +++++++++++++++-- wifi/java/android/net/wifi/WifiInfo.java | 29 ++++++++++++ wifi/java/android/net/wifi/WifiManager.java | 15 ++++--- .../android/net/wifi/WifiNetworkSuggestion.java | 6 ++- .../net/wifi/hotspot2/PasspointConfiguration.java | 5 ++- .../java/android/net/wifi/hotspot2/pps/HomeSp.java | 8 ++-- .../src/android/net/wifi/WifiManagerTest.java | 9 ++-- .../wifi/hotspot2/PasspointConfigurationTest.java | 52 +++++++++++++++++++--- 9 files changed, 141 insertions(+), 26 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 221f64440969..d4e024dbe0c7 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -270,4 +270,6 @@ interface IWifiManager void setScanThrottleEnabled(boolean enable); boolean isScanThrottleEnabled(); + + Map getAllMatchingPasspointProfilesForScanResults(in List scanResult); } diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 7c3d0b92dd0a..a720236689d3 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -2112,7 +2112,8 @@ public class WifiConfiguration implements Parcelable { return !TextUtils.isEmpty(FQDN) && !TextUtils.isEmpty(providerFriendlyName) && enterpriseConfig != null - && enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE; + && enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE + && !TextUtils.isEmpty(mPasspointUniqueId); } /** @@ -2494,12 +2495,17 @@ public class WifiConfiguration implements Parcelable { */ @NonNull public String getKey() { - String key = providerFriendlyName == null - ? getSsidAndSecurityTypeString() - : FQDN + KeyMgmt.strings[KeyMgmt.WPA_EAP]; + // Passpoint ephemeral networks have their unique identifier set. Return it as is to be + // able to match internally. + if (mPasspointUniqueId != null) { + return mPasspointUniqueId; + } + + String key = getSsidAndSecurityTypeString(); if (!shared) { key += "-" + UserHandle.getUserHandleForUid(creatorUid).getIdentifier(); } + return key; } @@ -2754,6 +2760,7 @@ public class WifiConfiguration implements Parcelable { requirePMF = source.requirePMF; updateIdentifier = source.updateIdentifier; carrierId = source.carrierId; + mPasspointUniqueId = source.mPasspointUniqueId; } } @@ -2826,6 +2833,7 @@ public class WifiConfiguration implements Parcelable { dest.writeInt(osu ? 1 : 0); dest.writeLong(randomizedMacExpirationTimeMs); dest.writeInt(carrierId); + dest.writeString(mPasspointUniqueId); } /** Implement the Parcelable interface {@hide} */ @@ -2900,6 +2908,7 @@ public class WifiConfiguration implements Parcelable { config.osu = in.readInt() != 0; config.randomizedMacExpirationTimeMs = in.readLong(); config.carrierId = in.readInt(); + config.mPasspointUniqueId = in.readString(); return config; } @@ -2907,4 +2916,28 @@ public class WifiConfiguration implements Parcelable { return new WifiConfiguration[size]; } }; + + /** + * Passpoint Unique identifier + * @hide + */ + private String mPasspointUniqueId = null; + + /** + * Set the Passpoint unique identifier + * @param uniqueId Passpoint unique identifier to be set + * @hide + */ + public void setPasspointUniqueId(String uniqueId) { + mPasspointUniqueId = uniqueId; + } + + /** + * Set the Passpoint unique identifier + * @hide + */ + public String getPasspointUniqueId() { + return mPasspointUniqueId; + } + } diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java index 24b2a8e8994f..0c306b4fb8cc 100644 --- a/wifi/java/android/net/wifi/WifiInfo.java +++ b/wifi/java/android/net/wifi/WifiInfo.java @@ -291,6 +291,11 @@ public class WifiInfo implements Parcelable { */ private boolean mMeteredHint; + /** + * Passpoint unique key + */ + private String mPasspointUniqueId; + /** @hide */ @UnsupportedAppUsage public WifiInfo() { @@ -322,6 +327,7 @@ public class WifiInfo implements Parcelable { setRequestingPackageName(null); setFQDN(null); setProviderFriendlyName(null); + setPasspointUniqueId(null); txBad = 0; txSuccess = 0; rxSuccess = 0; @@ -370,6 +376,7 @@ public class WifiInfo implements Parcelable { mWifiStandard = source.mWifiStandard; mMaxSupportedTxLinkSpeed = source.mMaxSupportedTxLinkSpeed; mMaxSupportedRxLinkSpeed = source.mMaxSupportedRxLinkSpeed; + mPasspointUniqueId = source.mPasspointUniqueId; } } @@ -977,6 +984,7 @@ public class WifiInfo implements Parcelable { dest.writeInt(mWifiStandard); dest.writeInt(mMaxSupportedTxLinkSpeed); dest.writeInt(mMaxSupportedRxLinkSpeed); + dest.writeString(mPasspointUniqueId); } /** Implement the Parcelable interface {@hide} */ @@ -1021,6 +1029,7 @@ public class WifiInfo implements Parcelable { info.mWifiStandard = in.readInt(); info.mMaxSupportedTxLinkSpeed = in.readInt(); info.mMaxSupportedRxLinkSpeed = in.readInt(); + info.mPasspointUniqueId = in.readString(); return info; } @@ -1028,4 +1037,24 @@ public class WifiInfo implements Parcelable { return new WifiInfo[size]; } }; + + /** + * Set the Passpoint unique identifier for the current connection + * + * @param passpointUniqueId Unique identifier + * @hide + */ + public void setPasspointUniqueId(@Nullable String passpointUniqueId) { + mPasspointUniqueId = passpointUniqueId; + } + + /** + * Get the Passpoint unique identifier for the current connection + * + * @return Passpoint unique identifier + * @hide + */ + public @Nullable String getPasspointUniqueId() { + return mPasspointUniqueId; + } } diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 1682023c3312..0b30f0946bf3 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1400,8 +1400,7 @@ public class WifiManager { List>>> configs = new ArrayList<>(); try { Map>> results = - mService.getAllMatchingFqdnsForScanResults( - scanResults); + mService.getAllMatchingPasspointProfilesForScanResults(scanResults); if (results.isEmpty()) { return configs; } @@ -1409,8 +1408,8 @@ public class WifiManager { mService.getWifiConfigsForPasspointProfiles( new ArrayList<>(results.keySet())); for (WifiConfiguration configuration : wifiConfigurations) { - Map> scanResultsPerNetworkType = results.get( - configuration.FQDN); + Map> scanResultsPerNetworkType = + results.get(configuration.getKey()); if (scanResultsPerNetworkType != null) { configs.add(Pair.create(configuration, scanResultsPerNetworkType)); } @@ -1962,9 +1961,11 @@ public class WifiManager { * for connecting to Passpoint networks that are operated by the Passpoint * service provider specified in the configuration. * - * Each configuration is uniquely identified by its FQDN (Fully Qualified Domain - * Name). In the case when there is an existing configuration with the same - * FQDN, the new configuration will replace the existing configuration. + * Each configuration is uniquely identified by a unique key which depends on the contents of + * the configuration. This allows the caller to install multiple profiles with the same FQDN + * (Fully qualified domain name). Therefore, in order to update an existing profile, it is + * first required to remove it using {@link WifiManager#removePasspointConfiguration(String)}. + * Otherwise, a new profile will be added with both configuration. * * @param config The Passpoint configuration to be added * @throws IllegalArgumentException if configuration is invalid or Passpoint is not enabled on diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java index 720149695abc..a854a4ba3ae5 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java +++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java @@ -569,6 +569,7 @@ public final class WifiNetworkSuggestion implements Parcelable { private WifiConfiguration buildWifiConfigurationForPasspoint() { WifiConfiguration wifiConfiguration = new WifiConfiguration(); wifiConfiguration.FQDN = mPasspointConfiguration.getHomeSp().getFqdn(); + wifiConfiguration.setPasspointUniqueId(mPasspointConfiguration.getUniqueId()); wifiConfiguration.priority = mPriority; wifiConfiguration.meteredOverride = mIsMetered ? WifiConfiguration.METERED_OVERRIDE_METERED @@ -804,7 +805,7 @@ public final class WifiNetworkSuggestion implements Parcelable { @Override public int hashCode() { return Objects.hash(wifiConfiguration.SSID, wifiConfiguration.BSSID, - wifiConfiguration.allowedKeyManagement, wifiConfiguration.FQDN); + wifiConfiguration.allowedKeyManagement, wifiConfiguration.getKey()); } /** @@ -827,7 +828,8 @@ public final class WifiNetworkSuggestion implements Parcelable { && TextUtils.equals(this.wifiConfiguration.BSSID, lhs.wifiConfiguration.BSSID) && Objects.equals(this.wifiConfiguration.allowedKeyManagement, lhs.wifiConfiguration.allowedKeyManagement) - && TextUtils.equals(this.wifiConfiguration.FQDN, lhs.wifiConfiguration.FQDN); + && TextUtils.equals(this.wifiConfiguration.getKey(), + lhs.wifiConfiguration.getKey()); } @Override diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java index 615331f65258..9f581849efca 100644 --- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java +++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java @@ -908,6 +908,9 @@ public final class PasspointConfiguration implements Parcelable { throw new IllegalStateException("Credential or HomeSP are not initialized"); } - return mHomeSp.getFqdn(); + StringBuilder sb = new StringBuilder(); + sb.append(String.format("%s_%x%x", mHomeSp.getFqdn(), mHomeSp.hashCode(), + mCredential.hashCode())); + return sb.toString(); } } diff --git a/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java b/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java index 49a76c33d209..a5de3318f454 100644 --- a/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java +++ b/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java @@ -16,8 +16,8 @@ package android.net.wifi.hotspot2.pps; -import android.os.Parcelable; import android.os.Parcel; +import android.os.Parcelable; import android.text.TextUtils; import android.util.Log; @@ -299,8 +299,10 @@ public final class HomeSp implements Parcelable { @Override public int hashCode() { - return Objects.hash(mFqdn, mFriendlyName, mIconUrl, mHomeNetworkIds, mMatchAllOis, - mMatchAnyOis, mOtherHomePartners, mRoamingConsortiumOis); + return Objects.hash(mFqdn, mFriendlyName, mIconUrl, + mHomeNetworkIds, Arrays.hashCode(mMatchAllOis), + Arrays.hashCode(mMatchAnyOis), Arrays.hashCode(mOtherHomePartners), + Arrays.hashCode(mRoamingConsortiumOis)); } @Override diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 53e9755eaf52..847040ca914a 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -1551,14 +1551,15 @@ public class WifiManagerTest { */ @Test public void testGetAllMatchingWifiConfigs() throws Exception { - Map> fqdns = new HashMap<>(); - fqdns.put("www.test.com", new ArrayList<>()); - when(mWifiService.getAllMatchingFqdnsForScanResults(any(List.class))).thenReturn(fqdns); + Map> passpointProfiles = new HashMap<>(); + passpointProfiles.put("www.test.com_987a69bca26", new ArrayList<>()); + when(mWifiService.getAllMatchingPasspointProfilesForScanResults( + any(List.class))).thenReturn(passpointProfiles); InOrder inOrder = inOrder(mWifiService); mWifiManager.getAllMatchingWifiConfigs(new ArrayList<>()); - inOrder.verify(mWifiService).getAllMatchingFqdnsForScanResults(any(List.class)); + inOrder.verify(mWifiService).getAllMatchingPasspointProfilesForScanResults(any(List.class)); inOrder.verify(mWifiService).getWifiConfigsForPasspointProfiles(any(List.class)); } diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java index ce542c2bc4e9..8f6beb19091b 100644 --- a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java @@ -20,8 +20,11 @@ import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_NONE; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; +import android.net.wifi.hotspot2.pps.Credential; +import android.net.wifi.hotspot2.pps.HomeSp; import android.os.Parcel; import androidx.test.filters.SmallTest; @@ -367,16 +370,55 @@ public class PasspointConfigurationTest { } /** - * Verify that the unique identifier generated is correct. + * Verify that the unique identifier generated is identical for two instances * * @throws Exception */ @Test public void validateUniqueId() throws Exception { - PasspointConfiguration config = PasspointTestUtils.createConfig(); - String uniqueId; - uniqueId = config.getUniqueId(); - assertEquals(uniqueId, config.getHomeSp().getFqdn()); + PasspointConfiguration config1 = PasspointTestUtils.createConfig(); + PasspointConfiguration config2 = PasspointTestUtils.createConfig(); + + assertEquals(config1.getUniqueId(), config2.getUniqueId()); + } + + /** + * Verify that the unique identifier generated is different for two instances with different + * HomeSp node + * + * @throws Exception + */ + @Test + public void validateUniqueIdDifferentHomeSp() throws Exception { + PasspointConfiguration config1 = PasspointTestUtils.createConfig(); + + // Modify config2's RCOIs to a different set of values + PasspointConfiguration config2 = PasspointTestUtils.createConfig(); + HomeSp homeSp = config2.getHomeSp(); + homeSp.setRoamingConsortiumOis(new long[] {0xaa, 0xbb}); + config2.setHomeSp(homeSp); + + assertNotEquals(config1.getUniqueId(), config2.getUniqueId()); + } + + /** + * Verify that the unique identifier generated is different for two instances with different + * Credential node + * + * @throws Exception + */ + @Test + public void validateUniqueIdDifferentCredential() throws Exception { + PasspointConfiguration config1 = PasspointTestUtils.createConfig(); + + // Modify config2's RCOIs to a different set of values + PasspointConfiguration config2 = PasspointTestUtils.createConfig(); + Credential credential = config2.getCredential(); + credential.setRealm("realm2.example.com"); + credential.getSimCredential().setImsi("350460*"); + config2.setCredential(credential); + + assertNotEquals(config1.getUniqueId(), config2.getUniqueId()); } /** -- cgit v1.2.3 From 3df4c8942fcc54b44c70de76f71baea02cc989ad Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Sun, 9 Feb 2020 10:47:57 -0800 Subject: [WIFICOND][API] MacAddress + capability flags Per API council feedback: - Convert: byte[] -> MacAddress - Formalize capability bit flags Bug: 149105833 Test: atest android.net.wifi Test: atest com.android.server.wifi Change-Id: I3e65511eec9b8d5ebc829de34b386b600ed67e82 --- .../net/wifi/wificond/NativeScanResult.java | 134 +++++++++++++++++---- .../net/wifi/wificond/NativeWifiClient.java | 31 +++-- .../android/net/wifi/wificond/WifiCondManager.java | 2 +- .../net/wifi/wificond/WifiCondManagerTest.java | 4 +- 4 files changed, 133 insertions(+), 38 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/wificond/NativeScanResult.java b/wifi/java/android/net/wifi/wificond/NativeScanResult.java index 7cc617d61b00..bd99476afe43 100644 --- a/wifi/java/android/net/wifi/wificond/NativeScanResult.java +++ b/wifi/java/android/net/wifi/wificond/NativeScanResult.java @@ -16,14 +16,21 @@ package android.net.wifi.wificond; +import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.SystemApi; +import android.net.MacAddress; import android.os.Parcel; import android.os.Parcelable; +import android.util.Log; import com.android.internal.annotations.VisibleForTesting; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; /** @@ -33,6 +40,8 @@ import java.util.List; */ @SystemApi public final class NativeScanResult implements Parcelable { + private static final String TAG = "NativeScanResult"; + /** @hide */ @VisibleForTesting public byte[] ssid; @@ -53,7 +62,7 @@ public final class NativeScanResult implements Parcelable { public long tsf; /** @hide */ @VisibleForTesting - public int capability; + @BssCapabilityBits public int capability; /** @hide */ @VisibleForTesting public boolean associated; @@ -71,14 +80,17 @@ public final class NativeScanResult implements Parcelable { } /** - * Returns raw bytes representing the MAC address (BSSID) of the AP represented by this scan - * result. + * Returns the MAC address (BSSID) of the AP represented by this scan result. * - * @return a byte array, possibly null or containing the incorrect number of bytes for a MAC - * address. + * @return a MacAddress or null on error. */ - @NonNull public byte[] getBssid() { - return bssid; + @Nullable public MacAddress getBssid() { + try { + return MacAddress.fromBytes(bssid); + } catch (IllegalArgumentException e) { + Log.e(TAG, "Illegal argument " + Arrays.toString(bssid), e); + return null; + } } /** @@ -127,31 +139,103 @@ public final class NativeScanResult implements Parcelable { return associated; } + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(flag = true, prefix = {"BSS_CAPABILITY_"}, + value = {BSS_CAPABILITY_ESS, + BSS_CAPABILITY_IBSS, + BSS_CAPABILITY_CF_POLLABLE, + BSS_CAPABILITY_CF_POLL_REQUEST, + BSS_CAPABILITY_PRIVACY, + BSS_CAPABILITY_SHORT_PREAMBLE, + BSS_CAPABILITY_PBCC, + BSS_CAPABILITY_CHANNEL_AGILITY, + BSS_CAPABILITY_SPECTRUM_MANAGEMENT, + BSS_CAPABILITY_QOS, + BSS_CAPABILITY_SHORT_SLOT_TIME, + BSS_CAPABILITY_APSD, + BSS_CAPABILITY_RADIO_MANAGEMENT, + BSS_CAPABILITY_DSSS_OFDM, + BSS_CAPABILITY_DELAYED_BLOCK_ACK, + BSS_CAPABILITY_IMMEDIATE_BLOCK_ACK + }) + public @interface BssCapabilityBits { } + + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): ESS. + */ + public static final int BSS_CAPABILITY_ESS = 0x1 << 0; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): IBSS. + */ + public static final int BSS_CAPABILITY_IBSS = 0x1 << 1; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): CF Pollable. + */ + public static final int BSS_CAPABILITY_CF_POLLABLE = 0x1 << 2; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): CF-Poll Request. + */ + public static final int BSS_CAPABILITY_CF_POLL_REQUEST = 0x1 << 3; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Privacy. + */ + public static final int BSS_CAPABILITY_PRIVACY = 0x1 << 4; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Short Preamble. + */ + public static final int BSS_CAPABILITY_SHORT_PREAMBLE = 0x1 << 5; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): PBCC. + */ + public static final int BSS_CAPABILITY_PBCC = 0x1 << 6; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Channel Agility. + */ + public static final int BSS_CAPABILITY_CHANNEL_AGILITY = 0x1 << 7; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Spectrum Management. + */ + public static final int BSS_CAPABILITY_SPECTRUM_MANAGEMENT = 0x1 << 8; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): QoS. + */ + public static final int BSS_CAPABILITY_QOS = 0x1 << 9; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Short Slot Time. + */ + public static final int BSS_CAPABILITY_SHORT_SLOT_TIME = 0x1 << 10; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): APSD. + */ + public static final int BSS_CAPABILITY_APSD = 0x1 << 11; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Radio Management. + */ + public static final int BSS_CAPABILITY_RADIO_MANAGEMENT = 0x1 << 12; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): DSSS-OFDM. + */ + public static final int BSS_CAPABILITY_DSSS_OFDM = 0x1 << 13; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Delayed Block Ack. + */ + public static final int BSS_CAPABILITY_DELAYED_BLOCK_ACK = 0x1 << 14; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Immediate Block Ack. + */ + public static final int BSS_CAPABILITY_IMMEDIATE_BLOCK_ACK = 0x1 << 15; + /** * Returns the capabilities of the AP repseresented by this scan result as advertised in the * received probe response or beacon. * - * This is a bit mask describing the capabilities of a BSS. See IEEE Std 802.11: 9.4.1.4: - * Bit 0 - ESS - * Bit 1 - IBSS - * Bit 2 - CF Pollable - * Bit 3 - CF-Poll Request - * Bit 4 - Privacy - * Bit 5 - Short Preamble - * Bit 6 - PBCC - * Bit 7 - Channel Agility - * Bit 8 - Spectrum Management - * Bit 9 - QoS - * Bit 10 - Short Slot Time - * Bit 11 - APSD - * Bit 12 - Radio Measurement - * Bit 13 - DSSS-OFDM - * Bit 14 - Delayed Block Ack - * Bit 15 - Immediate Block Ack + * This is a bit mask describing the capabilities of a BSS. See IEEE Std 802.11: 9.4.1.4: one + * of the {@code BSS_CAPABILITY_*} flags. * * @return a bit mask of capabilities. */ - @NonNull public int getCapabilities() { + @BssCapabilityBits public int getCapabilities() { return capability; } diff --git a/wifi/java/android/net/wifi/wificond/NativeWifiClient.java b/wifi/java/android/net/wifi/wificond/NativeWifiClient.java index 916c11579075..9ad2a2769add 100644 --- a/wifi/java/android/net/wifi/wificond/NativeWifiClient.java +++ b/wifi/java/android/net/wifi/wificond/NativeWifiClient.java @@ -17,11 +17,13 @@ package android.net.wifi.wificond; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.SystemApi; +import android.net.MacAddress; import android.os.Parcel; import android.os.Parcelable; -import java.util.Arrays; +import java.util.Objects; /** * Structure providing information about clients (STAs) associated with a SoftAp. @@ -30,16 +32,21 @@ import java.util.Arrays; */ @SystemApi public final class NativeWifiClient implements Parcelable { + private final MacAddress mMacAddress; + /** - * The raw bytes of the MAC address of the client (STA) represented by this object. + * The MAC address of the client (STA) represented by this object. The MAC address may be null + * in case of an error. */ - @NonNull public final byte[] macAddress; + @Nullable public MacAddress getMacAddress() { + return mMacAddress; + } /** * Construct a native Wi-Fi client. */ - public NativeWifiClient(@NonNull byte[] macAddress) { - this.macAddress = macAddress; + public NativeWifiClient(@Nullable MacAddress macAddress) { + this.mMacAddress = macAddress; } /** override comparator */ @@ -50,13 +57,13 @@ public final class NativeWifiClient implements Parcelable { return false; } NativeWifiClient other = (NativeWifiClient) rhs; - return Arrays.equals(macAddress, other.macAddress); + return Objects.equals(mMacAddress, other.mMacAddress); } /** override hash code */ @Override public int hashCode() { - return Arrays.hashCode(macAddress); + return mMacAddress.hashCode(); } /** implement Parcelable interface */ @@ -71,7 +78,7 @@ public final class NativeWifiClient implements Parcelable { */ @Override public void writeToParcel(@NonNull Parcel out, int flags) { - out.writeByteArray(macAddress); + out.writeByteArray(mMacAddress.toByteArray()); } /** implement Parcelable interface */ @@ -79,9 +86,11 @@ public final class NativeWifiClient implements Parcelable { new Parcelable.Creator() { @Override public NativeWifiClient createFromParcel(Parcel in) { - byte[] macAddress = in.createByteArray(); - if (macAddress == null) { - macAddress = new byte[0]; + MacAddress macAddress; + try { + macAddress = MacAddress.fromBytes(in.createByteArray()); + } catch (IllegalArgumentException e) { + macAddress = null; } return new NativeWifiClient(macAddress); } diff --git a/wifi/java/android/net/wifi/wificond/WifiCondManager.java b/wifi/java/android/net/wifi/wificond/WifiCondManager.java index d542e64d496d..61f18e0b7191 100644 --- a/wifi/java/android/net/wifi/wificond/WifiCondManager.java +++ b/wifi/java/android/net/wifi/wificond/WifiCondManager.java @@ -368,7 +368,7 @@ public class WifiCondManager { public void onConnectedClientsChanged(NativeWifiClient client, boolean isConnected) { if (mVerboseLoggingEnabled) { Log.d(TAG, "onConnectedClientsChanged called with " - + client.macAddress + " isConnected: " + isConnected); + + client.getMacAddress() + " isConnected: " + isConnected); } Binder.clearCallingIdentity(); diff --git a/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java b/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java index 603cec695e1d..b745a341b459 100644 --- a/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java +++ b/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java @@ -38,6 +38,7 @@ import static org.mockito.Mockito.when; import android.app.AlarmManager; import android.app.test.TestAlarmManager; import android.content.Context; +import android.net.MacAddress; import android.net.wifi.ScanResult; import android.net.wifi.SoftApInfo; import android.net.wifi.WifiConfiguration; @@ -119,7 +120,8 @@ public class WifiCondManagerTest { private static final String TEST_QUOTED_SSID_2 = "\"testSsid2\""; private static final int[] TEST_FREQUENCIES_1 = {}; private static final int[] TEST_FREQUENCIES_2 = {2500, 5124}; - private static final byte[] TEST_RAW_MAC_BYTES = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05}; + private static final MacAddress TEST_RAW_MAC_BYTES = MacAddress.fromBytes( + new byte[]{0x00, 0x01, 0x02, 0x03, 0x04, 0x05}); private static final List SCAN_HIDDEN_NETWORK_SSID_LIST = new ArrayList() {{ -- cgit v1.2.3 From 9acc2db5d6b2497c798427ac81877e77c01d7924 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Fri, 7 Feb 2020 08:02:51 -0800 Subject: WifiManager: Add API for auto wakeup feature toggle Needed for moving away from using Settings.Global values as pseudo APIs. Bug: 148514485 Test: atest android.net.wifi Test: Verified wifi wakeup feature toggle in wifi settings. Change-Id: I999d1cf835743e6e56e9bdeeeb67579c8ba48c1c --- wifi/java/android/net/wifi/IWifiManager.aidl | 4 ++ wifi/java/android/net/wifi/WifiManager.java | 46 ++++++++++++++++++++++ .../src/android/net/wifi/WifiManagerTest.java | 10 +++++ 3 files changed, 60 insertions(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index d4e024dbe0c7..1c330e263d7e 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -272,4 +272,8 @@ interface IWifiManager boolean isScanThrottleEnabled(); Map getAllMatchingPasspointProfilesForScanResults(in List scanResult); + + void setAutoWakeupEnabled(boolean enable); + + boolean isAutoWakeupEnabled(); } diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index fb30910c17b1..b6f4490a1872 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -6163,4 +6163,50 @@ public class WifiManager { throw e.rethrowFromSystemServer(); } } + + /** + * Enable/disable wifi auto wakeup feature. + * + *

    + * The feature is described in + * + * https://source.android.com/devices/tech/connect/wifi-infrastructure + * #turn_on_wi-fi_automatically + * + * + * @param enable true to enable, false to disable. + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) + public void setAutoWakeupEnabled(boolean enable) { + try { + mService.setAutoWakeupEnabled(enable); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Get the persisted Wi-Fi auto wakeup feature state. Defaults to false, unless changed by the + * user via Settings. + * + *

    + * The feature is described in + * + * https://source.android.com/devices/tech/connect/wifi-infrastructure + * #turn_on_wi-fi_automatically + * + * + * @return true to indicate that wakeup feature is enabled, false to indicate that wakeup + * feature is disabled. + */ + @RequiresPermission(ACCESS_WIFI_STATE) + public boolean isAutoWakeupEnabled() { + try { + return mService.isAutoWakeupEnabled(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } } diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 847040ca914a..853212aafcdf 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -2391,4 +2391,14 @@ public class WifiManagerTest { assertFalse(mWifiManager.isScanThrottleEnabled()); verify(mWifiService).isScanThrottleEnabled(); } + + @Test + public void testAutoWakeup() throws Exception { + mWifiManager.setAutoWakeupEnabled(true); + verify(mWifiService).setAutoWakeupEnabled(true); + + when(mWifiService.isAutoWakeupEnabled()).thenReturn(false); + assertFalse(mWifiManager.isAutoWakeupEnabled()); + verify(mWifiService).isAutoWakeupEnabled(); + } } -- cgit v1.2.3 From a180ec7766f2fcdf6e6679f979b4f07a7c9b3ee1 Mon Sep 17 00:00:00 2001 From: "Nate(Qiang) Jiang" Date: Mon, 10 Feb 2020 13:50:04 -0800 Subject: Make untrusted consistent Bug: 148781288 Test: atest android.net.wifi Change-Id: If8840b0f91ffcb438bbf08a7a188f794d479a62f --- wifi/java/android/net/wifi/WifiConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index a720236689d3..0cce23d196cf 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -951,7 +951,7 @@ public class WifiConfiguration implements Parcelable { * Indicate whether the network is trusted or not. Networks are considered trusted * if the user explicitly allowed this network connection. * This bit can be used by suggestion network, see - * {@link WifiNetworkSuggestion.Builder#setUnTrusted(boolean)} + * {@link WifiNetworkSuggestion.Builder#setUntrusted(boolean)} * @hide */ public boolean trusted; -- cgit v1.2.3 From d2348e128b94ac71108d35daeb6064934f968bc9 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Tue, 11 Feb 2020 11:08:32 +0800 Subject: wifi: add WAPI-CERT case for enterprise netowrk Bug: 139257562 Test: atest FrameworksWifiApiTests Change-Id: Iec704314a082fe5c664336f3e802ef701fffc2aa --- wifi/java/android/net/wifi/WifiConfiguration.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index a720236689d3..a7de59e6c03d 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -2140,7 +2140,8 @@ public class WifiConfiguration implements Parcelable { public boolean isEnterprise() { return (allowedKeyManagement.get(KeyMgmt.WPA_EAP) || allowedKeyManagement.get(KeyMgmt.IEEE8021X) - || allowedKeyManagement.get(KeyMgmt.SUITE_B_192)) + || allowedKeyManagement.get(KeyMgmt.SUITE_B_192) + || allowedKeyManagement.get(KeyMgmt.WAPI_CERT)) && enterpriseConfig != null && enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE; } @@ -2416,6 +2417,9 @@ public class WifiConfiguration implements Parcelable { if (allowedKeyManagement.get(KeyMgmt.SUITE_B_192)) { keyMgmt += KeyMgmt.strings[KeyMgmt.SUITE_B_192]; } + if (allowedKeyManagement.get(KeyMgmt.WAPI_CERT)) { + keyMgmt += KeyMgmt.strings[KeyMgmt.WAPI_CERT]; + } if (TextUtils.isEmpty(keyMgmt)) { throw new IllegalStateException("Not an EAP network"); -- cgit v1.2.3 From b9f28bc805e69cbb7943c1ef45d462f3d231372f Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Sun, 9 Feb 2020 12:06:56 -0800 Subject: [WIFICOND] Rename to nl80211 per API council feedback. Bug: 149105833 Bug: 148680192 Test: atest android.net.wifi Test: atest com.android.server.wifi Change-Id: I1d6bbd126ae0eb06068ff962573021fdec590735 --- .../android/net/wifi/wificond/WifiCondManager.java | 1286 ------------------- .../net/wifi/wificond/WifiNl80211Manager.java | 1287 ++++++++++++++++++++ .../net/wifi/wificond/WifiCondManagerTest.java | 1263 ------------------- .../net/wifi/wificond/WifiNl80211ManagerTest.java | 1265 +++++++++++++++++++ 4 files changed, 2552 insertions(+), 2549 deletions(-) delete mode 100644 wifi/java/android/net/wifi/wificond/WifiCondManager.java create mode 100644 wifi/java/android/net/wifi/wificond/WifiNl80211Manager.java delete mode 100644 wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java create mode 100644 wifi/tests/src/android/net/wifi/wificond/WifiNl80211ManagerTest.java (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/wificond/WifiCondManager.java b/wifi/java/android/net/wifi/wificond/WifiCondManager.java deleted file mode 100644 index 61f18e0b7191..000000000000 --- a/wifi/java/android/net/wifi/wificond/WifiCondManager.java +++ /dev/null @@ -1,1286 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.wifi.wificond; - -import android.annotation.CallbackExecutor; -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.annotation.SystemService; -import android.app.AlarmManager; -import android.content.Context; -import android.net.wifi.SoftApInfo; -import android.net.wifi.WifiAnnotations; -import android.net.wifi.WifiScanner; -import android.os.Binder; -import android.os.Handler; -import android.os.IBinder; -import android.os.RemoteException; -import android.os.ServiceManager; -import android.os.SystemClock; -import android.util.Log; - -import com.android.internal.annotations.VisibleForTesting; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.Executor; -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * This class encapsulates the interface the wificond daemon presents to the Wi-Fi framework. The - * interface is only for use by the Wi-Fi framework and access is protected by SELinux permissions. - * - * @hide - */ -@SystemApi -@SystemService(Context.WIFI_COND_SERVICE) -public class WifiCondManager { - private static final String TAG = "WifiCondManager"; - private boolean mVerboseLoggingEnabled = false; - - /** - * The {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} - * timeout, in milliseconds, after which - * {@link SendMgmtFrameCallback#onFailure(int)} will be called with reason - * {@link #SEND_MGMT_FRAME_ERROR_TIMEOUT}. - */ - private static final int SEND_MGMT_FRAME_TIMEOUT_MS = 1000; - - private static final String TIMEOUT_ALARM_TAG = TAG + " Send Management Frame Timeout"; - - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = {"SCAN_TYPE_"}, - value = {SCAN_TYPE_SINGLE_SCAN, - SCAN_TYPE_PNO_SCAN}) - public @interface ScanResultType {} - - /** - * Specifies a scan type: single scan initiated by the framework. Can be used in - * {@link #getScanResults(String, int)} to specify the type of scan result to fetch. - */ - public static final int SCAN_TYPE_SINGLE_SCAN = 0; - - /** - * Specifies a scan type: PNO scan. Can be used in {@link #getScanResults(String, int)} to - * specify the type of scan result to fetch. - */ - public static final int SCAN_TYPE_PNO_SCAN = 1; - - private AlarmManager mAlarmManager; - private Handler mEventHandler; - - // Cached wificond binder handlers. - private IWificond mWificond; - private HashMap mClientInterfaces = new HashMap<>(); - private HashMap mApInterfaces = new HashMap<>(); - private HashMap mWificondScanners = new HashMap<>(); - private HashMap mScanEventHandlers = new HashMap<>(); - private HashMap mPnoScanEventHandlers = new HashMap<>(); - private HashMap mApInterfaceListeners = new HashMap<>(); - private Runnable mDeathEventHandler; - /** - * Ensures that no more than one sendMgmtFrame operation runs concurrently. - */ - private AtomicBoolean mSendMgmtFrameInProgress = new AtomicBoolean(false); - - /** - * Interface used when waiting for scans to be completed (with results). - */ - public interface ScanEventCallback { - /** - * Called when scan results are available. Scans results should then be obtained from - * {@link #getScanResults(String, int)}. - */ - void onScanResultReady(); - - /** - * Called when a scan has failed. - */ - void onScanFailed(); - } - - /** - * Interface for a callback to provide information about PNO scan request requested with - * {@link #startPnoScan(String, PnoSettings, Executor, PnoScanRequestCallback)}. Note that the - * callback are for the status of the request - not the scan itself. The results of the scan - * are returned with {@link ScanEventCallback}. - */ - public interface PnoScanRequestCallback { - /** - * Called when a PNO scan request has been successfully submitted. - */ - void onPnoRequestSucceeded(); - - /** - * Called when a PNO scan request fails. - */ - void onPnoRequestFailed(); - } - - private class ScanEventHandler extends IScanEvent.Stub { - private Executor mExecutor; - private ScanEventCallback mCallback; - - ScanEventHandler(@NonNull Executor executor, @NonNull ScanEventCallback callback) { - mExecutor = executor; - mCallback = callback; - } - - @Override - public void OnScanResultReady() { - Log.d(TAG, "Scan result ready event"); - Binder.clearCallingIdentity(); - mExecutor.execute(() -> mCallback.onScanResultReady()); - } - - @Override - public void OnScanFailed() { - Log.d(TAG, "Scan failed event"); - Binder.clearCallingIdentity(); - mExecutor.execute(() -> mCallback.onScanFailed()); - } - } - - /** - * Result of a signal poll requested using {@link #signalPoll(String)}. - */ - public static class SignalPollResult { - /** @hide */ - public SignalPollResult(int currentRssiDbm, int txBitrateMbps, int rxBitrateMbps, - int associationFrequencyMHz) { - this.currentRssiDbm = currentRssiDbm; - this.txBitrateMbps = txBitrateMbps; - this.rxBitrateMbps = rxBitrateMbps; - this.associationFrequencyMHz = associationFrequencyMHz; - } - - /** - * RSSI value in dBM. - */ - public final int currentRssiDbm; - - /** - * Transmission bit rate in Mbps. - */ - public final int txBitrateMbps; - - /** - * Last received packet bit rate in Mbps. - */ - public final int rxBitrateMbps; - - /** - * Association frequency in MHz. - */ - public final int associationFrequencyMHz; - } - - /** - * Transmission counters obtained using {@link #getTxPacketCounters(String)}. - */ - public static class TxPacketCounters { - /** @hide */ - public TxPacketCounters(int txPacketSucceeded, int txPacketFailed) { - this.txPacketSucceeded = txPacketSucceeded; - this.txPacketFailed = txPacketFailed; - } - - /** - * Number of successfully transmitted packets. - */ - public final int txPacketSucceeded; - - /** - * Number of packet transmission failures. - */ - public final int txPacketFailed; - } - - /** - * Callbacks for SoftAp interface registered using - * {@link #registerApCallback(String, Executor, SoftApCallback)}. - */ - public interface SoftApCallback { - /** - * Invoked when there is a fatal failure and the SoftAp is shutdown. - */ - void onFailure(); - - /** - * Invoked when there is a change in the associated station (STA). - * @param client Information about the client whose status has changed. - * @param isConnected Indication as to whether the client is connected (true), or - * disconnected (false). - */ - void onConnectedClientsChanged(@NonNull NativeWifiClient client, boolean isConnected); - - /** - * Invoked when a channel switch event happens - i.e. the SoftAp is moved to a different - * channel. Also called on initial registration. - * @param frequencyMhz The new frequency of the SoftAp. A value of 0 is invalid and is an - * indication that the SoftAp is not enabled. - * @param bandwidth The new bandwidth of the SoftAp. - */ - void onSoftApChannelSwitched(int frequencyMhz, @WifiAnnotations.Bandwidth int bandwidth); - } - - /** - * Callback to notify the results of a - * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} call. - * Note: no callbacks will be triggered if the interface dies while sending a frame. - */ - public interface SendMgmtFrameCallback { - /** - * Called when the management frame was successfully sent and ACKed by the recipient. - * @param elapsedTimeMs The elapsed time between when the management frame was sent and when - * the ACK was processed, in milliseconds, as measured by wificond. - * This includes the time that the send frame spent queuing before it - * was sent, any firmware retries, and the time the received ACK spent - * queuing before it was processed. - */ - void onAck(int elapsedTimeMs); - - /** - * Called when the send failed. - * @param reason The error code for the failure. - */ - void onFailure(@SendMgmtFrameError int reason); - } - - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = {"SEND_MGMT_FRAME_ERROR_"}, - value = {SEND_MGMT_FRAME_ERROR_UNKNOWN, - SEND_MGMT_FRAME_ERROR_MCS_UNSUPPORTED, - SEND_MGMT_FRAME_ERROR_NO_ACK, - SEND_MGMT_FRAME_ERROR_TIMEOUT, - SEND_MGMT_FRAME_ERROR_ALREADY_STARTED}) - public @interface SendMgmtFrameError {} - - // Send management frame error codes - - /** - * Unknown error occurred during call to - * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)}. - */ - public static final int SEND_MGMT_FRAME_ERROR_UNKNOWN = 1; - - /** - * Specifying the MCS rate in - * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} is not - * supported by this device. - */ - public static final int SEND_MGMT_FRAME_ERROR_MCS_UNSUPPORTED = 2; - - /** - * Driver reported that no ACK was received for the frame transmitted using - * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)}. - */ - public static final int SEND_MGMT_FRAME_ERROR_NO_ACK = 3; - - /** - * Error code for when the driver fails to report on the status of the frame sent by - * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} - * after {@link #SEND_MGMT_FRAME_TIMEOUT_MS} milliseconds. - */ - public static final int SEND_MGMT_FRAME_ERROR_TIMEOUT = 4; - - /** - * An existing call to - * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} - * is in progress. Another frame cannot be sent until the first call completes. - */ - public static final int SEND_MGMT_FRAME_ERROR_ALREADY_STARTED = 5; - - /** @hide */ - public WifiCondManager(Context context) { - mAlarmManager = context.getSystemService(AlarmManager.class); - mEventHandler = new Handler(context.getMainLooper()); - } - - /** @hide */ - @VisibleForTesting - public WifiCondManager(Context context, IWificond wificond) { - this(context); - mWificond = wificond; - } - - private class PnoScanEventHandler extends IPnoScanEvent.Stub { - private Executor mExecutor; - private ScanEventCallback mCallback; - - PnoScanEventHandler(@NonNull Executor executor, @NonNull ScanEventCallback callback) { - mExecutor = executor; - mCallback = callback; - } - - @Override - public void OnPnoNetworkFound() { - Log.d(TAG, "Pno scan result event"); - Binder.clearCallingIdentity(); - mExecutor.execute(() -> mCallback.onScanResultReady()); - } - - @Override - public void OnPnoScanFailed() { - Log.d(TAG, "Pno Scan failed event"); - Binder.clearCallingIdentity(); - mExecutor.execute(() -> mCallback.onScanFailed()); - } - } - - /** - * Listener for AP Interface events. - */ - private class ApInterfaceEventCallback extends IApInterfaceEventCallback.Stub { - private Executor mExecutor; - private SoftApCallback mSoftApListener; - - ApInterfaceEventCallback(Executor executor, SoftApCallback listener) { - mExecutor = executor; - mSoftApListener = listener; - } - - @Override - public void onConnectedClientsChanged(NativeWifiClient client, boolean isConnected) { - if (mVerboseLoggingEnabled) { - Log.d(TAG, "onConnectedClientsChanged called with " - + client.getMacAddress() + " isConnected: " + isConnected); - } - - Binder.clearCallingIdentity(); - mExecutor.execute(() -> mSoftApListener.onConnectedClientsChanged(client, isConnected)); - } - - @Override - public void onSoftApChannelSwitched(int frequency, int bandwidth) { - Binder.clearCallingIdentity(); - mExecutor.execute(() -> mSoftApListener.onSoftApChannelSwitched(frequency, - toFrameworkBandwidth(bandwidth))); - } - - private @WifiAnnotations.Bandwidth int toFrameworkBandwidth(int bandwidth) { - switch(bandwidth) { - case IApInterfaceEventCallback.BANDWIDTH_INVALID: - return SoftApInfo.CHANNEL_WIDTH_INVALID; - case IApInterfaceEventCallback.BANDWIDTH_20_NOHT: - return SoftApInfo.CHANNEL_WIDTH_20MHZ_NOHT; - case IApInterfaceEventCallback.BANDWIDTH_20: - return SoftApInfo.CHANNEL_WIDTH_20MHZ; - case IApInterfaceEventCallback.BANDWIDTH_40: - return SoftApInfo.CHANNEL_WIDTH_40MHZ; - case IApInterfaceEventCallback.BANDWIDTH_80: - return SoftApInfo.CHANNEL_WIDTH_80MHZ; - case IApInterfaceEventCallback.BANDWIDTH_80P80: - return SoftApInfo.CHANNEL_WIDTH_80MHZ_PLUS_MHZ; - case IApInterfaceEventCallback.BANDWIDTH_160: - return SoftApInfo.CHANNEL_WIDTH_160MHZ; - default: - return SoftApInfo.CHANNEL_WIDTH_INVALID; - } - } - } - - /** - * Callback triggered by wificond. - */ - private class SendMgmtFrameEvent extends ISendMgmtFrameEvent.Stub { - private Executor mExecutor; - private SendMgmtFrameCallback mCallback; - private AlarmManager.OnAlarmListener mTimeoutCallback; - /** - * ensures that mCallback is only called once - */ - private boolean mWasCalled; - - private void runIfFirstCall(Runnable r) { - if (mWasCalled) return; - mWasCalled = true; - - mSendMgmtFrameInProgress.set(false); - r.run(); - } - - SendMgmtFrameEvent(@NonNull Executor executor, @NonNull SendMgmtFrameCallback callback) { - mExecutor = executor; - mCallback = callback; - // called in main thread - mTimeoutCallback = () -> runIfFirstCall(() -> { - if (mVerboseLoggingEnabled) { - Log.e(TAG, "Timed out waiting for ACK"); - } - Binder.clearCallingIdentity(); - mExecutor.execute(() -> mCallback.onFailure(SEND_MGMT_FRAME_ERROR_TIMEOUT)); - }); - mWasCalled = false; - - mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, - SystemClock.elapsedRealtime() + SEND_MGMT_FRAME_TIMEOUT_MS, - TIMEOUT_ALARM_TAG, mTimeoutCallback, mEventHandler); - } - - // called in binder thread - @Override - public void OnAck(int elapsedTimeMs) { - // post to main thread - mEventHandler.post(() -> runIfFirstCall(() -> { - mAlarmManager.cancel(mTimeoutCallback); - Binder.clearCallingIdentity(); - mExecutor.execute(() -> mCallback.onAck(elapsedTimeMs)); - })); - } - - // called in binder thread - @Override - public void OnFailure(int reason) { - // post to main thread - mEventHandler.post(() -> runIfFirstCall(() -> { - mAlarmManager.cancel(mTimeoutCallback); - Binder.clearCallingIdentity(); - mExecutor.execute(() -> mCallback.onFailure(reason)); - })); - } - } - - /** - * Called by the binder subsystem upon remote object death. - * Invoke all the register death handlers and clear state. - * @hide - */ - @VisibleForTesting - public void binderDied() { - mEventHandler.post(() -> { - Log.e(TAG, "Wificond died!"); - clearState(); - // Invalidate the global wificond handle on death. Will be refreshed - // on the next setup call. - mWificond = null; - if (mDeathEventHandler != null) { - mDeathEventHandler.run(); - } - }); - } - - /** - * Enable or disable verbose logging of the WifiCondManager module. - * @param enable True to enable verbose logging. False to disable verbose logging. - */ - public void enableVerboseLogging(boolean enable) { - mVerboseLoggingEnabled = enable; - } - - /** - * Register a death notification for the WifiCondManager which acts as a proxy for the - * wificond daemon (i.e. the death listener will be called when and if the wificond daemon - * dies). - * - * @param deathEventHandler A {@link Runnable} to be called whenever the wificond daemon dies. - */ - public void setOnServiceDeadCallback(@NonNull Runnable deathEventHandler) { - if (mDeathEventHandler != null) { - Log.e(TAG, "Death handler already present"); - } - mDeathEventHandler = deathEventHandler; - } - - /** - * Helper method to retrieve the global wificond handle and register for - * death notifications. - */ - private boolean retrieveWificondAndRegisterForDeath() { - if (mWificond != null) { - if (mVerboseLoggingEnabled) { - Log.d(TAG, "Wificond handle already retrieved"); - } - // We already have a wificond handle. - return true; - } - IBinder binder = ServiceManager.getService(Context.WIFI_COND_SERVICE); - mWificond = IWificond.Stub.asInterface(binder); - if (mWificond == null) { - Log.e(TAG, "Failed to get reference to wificond"); - return false; - } - try { - mWificond.asBinder().linkToDeath(() -> binderDied(), 0); - } catch (RemoteException e) { - Log.e(TAG, "Failed to register death notification for wificond"); - // The remote has already died. - return false; - } - return true; - } - - /** - * Set up an interface for client (STA) mode. - * - * @param ifaceName Name of the interface to configure. - * @param executor The Executor on which to execute the callbacks. - * @param scanCallback A callback for framework initiated scans. - * @param pnoScanCallback A callback for PNO (offloaded) scans. - * @return true on success. - */ - public boolean setupInterfaceForClientMode(@NonNull String ifaceName, - @NonNull @CallbackExecutor Executor executor, - @NonNull ScanEventCallback scanCallback, @NonNull ScanEventCallback pnoScanCallback) { - Log.d(TAG, "Setting up interface for client mode"); - if (!retrieveWificondAndRegisterForDeath()) { - return false; - } - - if (scanCallback == null || pnoScanCallback == null || executor == null) { - Log.e(TAG, "setupInterfaceForClientMode invoked with null callbacks"); - return false; - } - - IClientInterface clientInterface = null; - try { - clientInterface = mWificond.createClientInterface(ifaceName); - } catch (RemoteException e1) { - Log.e(TAG, "Failed to get IClientInterface due to remote exception"); - return false; - } - - if (clientInterface == null) { - Log.e(TAG, "Could not get IClientInterface instance from wificond"); - return false; - } - Binder.allowBlocking(clientInterface.asBinder()); - - // Refresh Handlers - mClientInterfaces.put(ifaceName, clientInterface); - try { - IWifiScannerImpl wificondScanner = clientInterface.getWifiScannerImpl(); - if (wificondScanner == null) { - Log.e(TAG, "Failed to get WificondScannerImpl"); - return false; - } - mWificondScanners.put(ifaceName, wificondScanner); - Binder.allowBlocking(wificondScanner.asBinder()); - ScanEventHandler scanEventHandler = new ScanEventHandler(executor, scanCallback); - mScanEventHandlers.put(ifaceName, scanEventHandler); - wificondScanner.subscribeScanEvents(scanEventHandler); - PnoScanEventHandler pnoScanEventHandler = new PnoScanEventHandler(executor, - pnoScanCallback); - mPnoScanEventHandlers.put(ifaceName, pnoScanEventHandler); - wificondScanner.subscribePnoScanEvents(pnoScanEventHandler); - } catch (RemoteException e) { - Log.e(TAG, "Failed to refresh wificond scanner due to remote exception"); - } - - return true; - } - - /** - * Tear down a specific client (STA) interface configured using - * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}. - * - * @param ifaceName Name of the interface to tear down. - * @return Returns true on success, false on failure (e.g. when called before an interface was - * set up). - */ - public boolean tearDownClientInterface(@NonNull String ifaceName) { - if (getClientInterface(ifaceName) == null) { - Log.e(TAG, "No valid wificond client interface handler"); - return false; - } - try { - IWifiScannerImpl scannerImpl = mWificondScanners.get(ifaceName); - if (scannerImpl != null) { - scannerImpl.unsubscribeScanEvents(); - scannerImpl.unsubscribePnoScanEvents(); - } - } catch (RemoteException e) { - Log.e(TAG, "Failed to unsubscribe wificond scanner due to remote exception"); - return false; - } - - if (mWificond == null) { - Log.e(TAG, "Reference to wifiCond is null"); - return false; - } - - boolean success; - try { - success = mWificond.tearDownClientInterface(ifaceName); - } catch (RemoteException e1) { - Log.e(TAG, "Failed to teardown client interface due to remote exception"); - return false; - } - if (!success) { - Log.e(TAG, "Failed to teardown client interface"); - return false; - } - - mClientInterfaces.remove(ifaceName); - mWificondScanners.remove(ifaceName); - mScanEventHandlers.remove(ifaceName); - mPnoScanEventHandlers.remove(ifaceName); - return true; - } - - /** - * Set up interface as a Soft AP. - * - * @param ifaceName Name of the interface to configure. - * @return true on success. - */ - public boolean setupInterfaceForSoftApMode(@NonNull String ifaceName) { - Log.d(TAG, "Setting up interface for soft ap mode"); - if (!retrieveWificondAndRegisterForDeath()) { - return false; - } - - IApInterface apInterface = null; - try { - apInterface = mWificond.createApInterface(ifaceName); - } catch (RemoteException e1) { - Log.e(TAG, "Failed to get IApInterface due to remote exception"); - return false; - } - - if (apInterface == null) { - Log.e(TAG, "Could not get IApInterface instance from wificond"); - return false; - } - Binder.allowBlocking(apInterface.asBinder()); - - // Refresh Handlers - mApInterfaces.put(ifaceName, apInterface); - return true; - } - - /** - * Tear down a Soft AP interface configured using - * {@link #setupInterfaceForSoftApMode(String)}. - * - * @param ifaceName Name of the interface to tear down. - * @return Returns true on success, false on failure (e.g. when called before an interface was - * set up). - */ - public boolean tearDownSoftApInterface(@NonNull String ifaceName) { - if (getApInterface(ifaceName) == null) { - Log.e(TAG, "No valid wificond ap interface handler"); - return false; - } - - if (mWificond == null) { - Log.e(TAG, "Reference to wifiCond is null"); - return false; - } - - boolean success; - try { - success = mWificond.tearDownApInterface(ifaceName); - } catch (RemoteException e1) { - Log.e(TAG, "Failed to teardown AP interface due to remote exception"); - return false; - } - if (!success) { - Log.e(TAG, "Failed to teardown AP interface"); - return false; - } - mApInterfaces.remove(ifaceName); - mApInterfaceListeners.remove(ifaceName); - return true; - } - - /** - * Tear down all interfaces, whether clients (STA) or Soft AP. - * - * @return Returns true on success. - */ - public boolean tearDownInterfaces() { - Log.d(TAG, "tearing down interfaces in wificond"); - // Explicitly refresh the wificodn handler because |tearDownInterfaces()| - // could be used to cleanup before we setup any interfaces. - if (!retrieveWificondAndRegisterForDeath()) { - return false; - } - - try { - for (Map.Entry entry : mWificondScanners.entrySet()) { - entry.getValue().unsubscribeScanEvents(); - entry.getValue().unsubscribePnoScanEvents(); - } - mWificond.tearDownInterfaces(); - clearState(); - return true; - } catch (RemoteException e) { - Log.e(TAG, "Failed to tear down interfaces due to remote exception"); - } - - return false; - } - - /** Helper function to look up the interface handle using name */ - private IClientInterface getClientInterface(@NonNull String ifaceName) { - return mClientInterfaces.get(ifaceName); - } - - /** - * Request signal polling. - * - * @param ifaceName Name of the interface on which to poll. The interface must have been - * already set up using - *{@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} - * or {@link #setupInterfaceForSoftApMode(String)}. - * - * @return A {@link SignalPollResult} object containing interface statistics, or a null on - * error (e.g. the interface hasn't been set up yet). - */ - @Nullable public SignalPollResult signalPoll(@NonNull String ifaceName) { - IClientInterface iface = getClientInterface(ifaceName); - if (iface == null) { - Log.e(TAG, "No valid wificond client interface handler"); - return null; - } - - int[] resultArray; - try { - resultArray = iface.signalPoll(); - if (resultArray == null || resultArray.length != 4) { - Log.e(TAG, "Invalid signal poll result from wificond"); - return null; - } - } catch (RemoteException e) { - Log.e(TAG, "Failed to do signal polling due to remote exception"); - return null; - } - return new SignalPollResult(resultArray[0], resultArray[1], resultArray[3], resultArray[2]); - } - - /** - * Get current transmit (Tx) packet counters of the specified interface. The interface must - * have been already set up using - * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} - * or {@link #setupInterfaceForSoftApMode(String)}. - * - * @param ifaceName Name of the interface. - * @return {@link TxPacketCounters} of the current interface or null on error (e.g. when - * called before the interface has been set up). - */ - @Nullable public TxPacketCounters getTxPacketCounters(@NonNull String ifaceName) { - IClientInterface iface = getClientInterface(ifaceName); - if (iface == null) { - Log.e(TAG, "No valid wificond client interface handler"); - return null; - } - - int[] resultArray; - try { - resultArray = iface.getPacketCounters(); - if (resultArray == null || resultArray.length != 2) { - Log.e(TAG, "Invalid signal poll result from wificond"); - return null; - } - } catch (RemoteException e) { - Log.e(TAG, "Failed to do signal polling due to remote exception"); - return null; - } - return new TxPacketCounters(resultArray[0], resultArray[1]); - } - - /** Helper function to look up the scanner impl handle using name */ - private IWifiScannerImpl getScannerImpl(@NonNull String ifaceName) { - return mWificondScanners.get(ifaceName); - } - - /** - * Fetch the latest scan results of the indicated type for the specified interface. Note that - * this method fetches the latest results - it does not initiate a scan. Initiating a scan can - * be done using {@link #startScan(String, int, Set, List)} or - * {@link #startPnoScan(String, PnoSettings, Executor, PnoScanRequestCallback)}. - * - * Note: The interface must have been already set up using - * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} - * or {@link #setupInterfaceForSoftApMode(String)}. - * - * @param ifaceName Name of the interface. - * @param scanType The type of scan result to be returned, can be - * {@link #SCAN_TYPE_SINGLE_SCAN} or {@link #SCAN_TYPE_PNO_SCAN}. - * @return Returns an array of {@link NativeScanResult} or an empty array on failure (e.g. when - * called before the interface has been set up). - */ - @NonNull public List getScanResults(@NonNull String ifaceName, - @ScanResultType int scanType) { - IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); - if (scannerImpl == null) { - Log.e(TAG, "No valid wificond scanner interface handler"); - return new ArrayList<>(); - } - List results = null; - try { - if (scanType == SCAN_TYPE_SINGLE_SCAN) { - results = Arrays.asList(scannerImpl.getScanResults()); - } else { - results = Arrays.asList(scannerImpl.getPnoScanResults()); - } - } catch (RemoteException e1) { - Log.e(TAG, "Failed to create ScanDetail ArrayList"); - } - if (results == null) { - results = new ArrayList<>(); - } - if (mVerboseLoggingEnabled) { - Log.d(TAG, "get " + results.size() + " scan results from wificond"); - } - - return results; - } - - /** - * Return scan type for the parcelable {@link SingleScanSettings} - */ - private static int getScanType(@WifiAnnotations.ScanType int scanType) { - switch (scanType) { - case WifiScanner.SCAN_TYPE_LOW_LATENCY: - return IWifiScannerImpl.SCAN_TYPE_LOW_SPAN; - case WifiScanner.SCAN_TYPE_LOW_POWER: - return IWifiScannerImpl.SCAN_TYPE_LOW_POWER; - case WifiScanner.SCAN_TYPE_HIGH_ACCURACY: - return IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY; - default: - throw new IllegalArgumentException("Invalid scan type " + scanType); - } - } - - /** - * Start a scan using the specified parameters. A scan is an asynchronous operation. The - * result of the operation is returned in the {@link ScanEventCallback} registered when - * setting up an interface using - * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}. - * The latest scans can be obtained using {@link #getScanResults(String, int)} and using a - * {@link #SCAN_TYPE_SINGLE_SCAN} for the {@code scanType}. - * - * Note: The interface must have been already set up using - * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} - * or {@link #setupInterfaceForSoftApMode(String)}. - * - * @param ifaceName Name of the interface on which to initiate the scan. - * @param scanType Type of scan to perform, can be any of - * {@link WifiScanner#SCAN_TYPE_HIGH_ACCURACY}, {@link WifiScanner#SCAN_TYPE_LOW_POWER}, or - * {@link WifiScanner#SCAN_TYPE_LOW_LATENCY}. - * @param freqs list of frequencies to scan for, if null scan all supported channels. - * @param hiddenNetworkSSIDs List of hidden networks to be scanned for, a null indicates that - * no hidden frequencies will be scanned for. - * @return Returns true on success, false on failure (e.g. when called before the interface - * has been set up). - */ - public boolean startScan(@NonNull String ifaceName, @WifiAnnotations.ScanType int scanType, - @Nullable Set freqs, @Nullable List hiddenNetworkSSIDs) { - IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); - if (scannerImpl == null) { - Log.e(TAG, "No valid wificond scanner interface handler"); - return false; - } - SingleScanSettings settings = new SingleScanSettings(); - try { - settings.scanType = getScanType(scanType); - } catch (IllegalArgumentException e) { - Log.e(TAG, "Invalid scan type ", e); - return false; - } - settings.channelSettings = new ArrayList<>(); - settings.hiddenNetworks = new ArrayList<>(); - - if (freqs != null) { - for (Integer freq : freqs) { - ChannelSettings channel = new ChannelSettings(); - channel.frequency = freq; - settings.channelSettings.add(channel); - } - } - if (hiddenNetworkSSIDs != null) { - for (byte[] ssid : hiddenNetworkSSIDs) { - HiddenNetwork network = new HiddenNetwork(); - network.ssid = ssid; - - // settings.hiddenNetworks is expected to be very small, so this shouldn't cause - // any performance issues. - if (!settings.hiddenNetworks.contains(network)) { - settings.hiddenNetworks.add(network); - } - } - } - - try { - return scannerImpl.scan(settings); - } catch (RemoteException e1) { - Log.e(TAG, "Failed to request scan due to remote exception"); - } - return false; - } - - /** - * Request a PNO (Preferred Network Offload). The offload request and the scans are asynchronous - * operations. The result of the request are returned in the {@code callback} parameter which - * is an {@link PnoScanRequestCallback}. The scan results are are return in the - * {@link ScanEventCallback} which is registered when setting up an interface using - * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}. - * The latest PNO scans can be obtained using {@link #getScanResults(String, int)} with the - * {@code scanType} set to {@link #SCAN_TYPE_PNO_SCAN}. - * - * Note: The interface must have been already set up using - * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} - * or {@link #setupInterfaceForSoftApMode(String)}. - * - * @param ifaceName Name of the interface on which to request a PNO. - * @param pnoSettings PNO scan configuration. - * @param executor The Executor on which to execute the callback. - * @param callback Callback for the results of the offload request. - * @return true on success, false on failure (e.g. when called before the interface has been set - * up). - */ - public boolean startPnoScan(@NonNull String ifaceName, @NonNull PnoSettings pnoSettings, - @NonNull @CallbackExecutor Executor executor, - @NonNull PnoScanRequestCallback callback) { - IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); - if (scannerImpl == null) { - Log.e(TAG, "No valid wificond scanner interface handler"); - return false; - } - - if (callback == null || executor == null) { - Log.e(TAG, "startPnoScan called with a null callback"); - return false; - } - - try { - boolean success = scannerImpl.startPnoScan(pnoSettings); - if (success) { - executor.execute(callback::onPnoRequestSucceeded); - } else { - executor.execute(callback::onPnoRequestFailed); - } - return success; - } catch (RemoteException e1) { - Log.e(TAG, "Failed to start pno scan due to remote exception"); - } - return false; - } - - /** - * Stop PNO scan configured with - * {@link #startPnoScan(String, PnoSettings, Executor, PnoScanRequestCallback)}. - * - * Note: The interface must have been already set up using - * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} - * or {@link #setupInterfaceForSoftApMode(String)}. - * - * @param ifaceName Name of the interface on which the PNO scan was configured. - * @return true on success, false on failure (e.g. when called before the interface has been - * set up). - */ - public boolean stopPnoScan(@NonNull String ifaceName) { - IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); - if (scannerImpl == null) { - Log.e(TAG, "No valid wificond scanner interface handler"); - return false; - } - try { - return scannerImpl.stopPnoScan(); - } catch (RemoteException e1) { - Log.e(TAG, "Failed to stop pno scan due to remote exception"); - } - return false; - } - - /** - * Abort ongoing single scan started with {@link #startScan(String, int, Set, List)}. No failure - * callback, e.g. {@link ScanEventCallback#onScanFailed()}, is triggered by this operation. - * - * Note: The interface must have been already set up using - * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} - * or {@link #setupInterfaceForSoftApMode(String)}. If the interface has not been set up then - * this method has no impact. - * - * @param ifaceName Name of the interface on which the scan was started. - */ - public void abortScan(@NonNull String ifaceName) { - IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); - if (scannerImpl == null) { - Log.e(TAG, "No valid wificond scanner interface handler"); - return; - } - try { - scannerImpl.abortScan(); - } catch (RemoteException e1) { - Log.e(TAG, "Failed to request abortScan due to remote exception"); - } - } - - /** - * Query the list of valid frequencies (in MHz) for the provided band. - * The result depends on the on the country code that has been set. - * - * @param band as specified by one of the WifiScanner.WIFI_BAND_* constants. - * The following bands are supported {@link @WifiScanner.WifiBandBasic}: - * WifiScanner.WIFI_BAND_24_GHZ - * WifiScanner.WIFI_BAND_5_GHZ - * WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY - * WifiScanner.WIFI_BAND_6_GHZ - * @return frequencies vector of valid frequencies (MHz), or an empty array for error. - * @throws IllegalArgumentException if band is not recognized. - */ - public @NonNull int[] getChannelsMhzForBand(@WifiAnnotations.WifiBandBasic int band) { - if (mWificond == null) { - Log.e(TAG, "No valid wificond scanner interface handler"); - return new int[0]; - } - int[] result = null; - try { - switch (band) { - case WifiScanner.WIFI_BAND_24_GHZ: - result = mWificond.getAvailable2gChannels(); - break; - case WifiScanner.WIFI_BAND_5_GHZ: - result = mWificond.getAvailable5gNonDFSChannels(); - break; - case WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY: - result = mWificond.getAvailableDFSChannels(); - break; - case WifiScanner.WIFI_BAND_6_GHZ: - result = mWificond.getAvailable6gChannels(); - break; - default: - throw new IllegalArgumentException("unsupported band " + band); - } - } catch (RemoteException e1) { - Log.e(TAG, "Failed to request getChannelsForBand due to remote exception"); - } - if (result == null) { - result = new int[0]; - } - return result; - } - - /** Helper function to look up the interface handle using name */ - private IApInterface getApInterface(@NonNull String ifaceName) { - return mApInterfaces.get(ifaceName); - } - - /** - * Get the device phy capabilities for a given interface. - * - * Note: The interface must have been already set up using - * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} - * or {@link #setupInterfaceForSoftApMode(String)}. - * - * @return DeviceWiphyCapabilities or null on error (e.g. when called on an interface which has - * not been set up). - */ - @Nullable public DeviceWiphyCapabilities getDeviceWiphyCapabilities(@NonNull String ifaceName) { - if (mWificond == null) { - Log.e(TAG, "Can not query for device wiphy capabilities at this time"); - return null; - } - - try { - return mWificond.getDeviceWiphyCapabilities(ifaceName); - } catch (RemoteException e) { - return null; - } - } - - /** - * Register the provided callback handler for SoftAp events. The interface must first be created - * using {@link #setupInterfaceForSoftApMode(String)}. The callback registration is valid until - * the interface is deleted using {@link #tearDownSoftApInterface(String)} (no deregistration - * method is provided). - *

    - * Note that only one callback can be registered at a time - any registration overrides previous - * registrations. - * - * @param ifaceName Name of the interface on which to register the callback. - * @param executor The Executor on which to execute the callbacks. - * @param callback Callback for AP events. - * @return true on success, false on failure (e.g. when called on an interface which has not - * been set up). - */ - public boolean registerApCallback(@NonNull String ifaceName, - @NonNull @CallbackExecutor Executor executor, - @NonNull SoftApCallback callback) { - IApInterface iface = getApInterface(ifaceName); - if (iface == null) { - Log.e(TAG, "No valid ap interface handler"); - return false; - } - - if (callback == null || executor == null) { - Log.e(TAG, "registerApCallback called with a null callback"); - return false; - } - - try { - IApInterfaceEventCallback wificondCallback = new ApInterfaceEventCallback(executor, - callback); - mApInterfaceListeners.put(ifaceName, wificondCallback); - boolean success = iface.registerCallback(wificondCallback); - if (!success) { - Log.e(TAG, "Failed to register ap callback."); - return false; - } - } catch (RemoteException e) { - Log.e(TAG, "Exception in registering AP callback: " + e); - return false; - } - return true; - } - - /** - * Send a management frame on the specified interface at the specified rate. Useful for probing - * the link with arbitrary frames. - * - * Note: The interface must have been already set up using - * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} - * or {@link #setupInterfaceForSoftApMode(String)}. - * - * @param ifaceName The interface on which to send the frame. - * @param frame The raw byte array of the management frame to tramit. - * @param mcs The MCS (modulation and coding scheme), i.e. rate, at which to transmit the - * frame. Specified per IEEE 802.11. - * @param executor The Executor on which to execute the callbacks. - * @param callback A {@link SendMgmtFrameCallback} callback for results of the operation. - */ - public void sendMgmtFrame(@NonNull String ifaceName, @NonNull byte[] frame, int mcs, - @NonNull @CallbackExecutor Executor executor, - @NonNull SendMgmtFrameCallback callback) { - - if (callback == null || executor == null) { - Log.e(TAG, "callback cannot be null!"); - return; - } - - if (frame == null) { - Log.e(TAG, "frame cannot be null!"); - executor.execute(() -> callback.onFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN)); - return; - } - - // TODO (b/112029045) validate mcs - IClientInterface clientInterface = getClientInterface(ifaceName); - if (clientInterface == null) { - Log.e(TAG, "No valid wificond client interface handler"); - executor.execute(() -> callback.onFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN)); - return; - } - - if (!mSendMgmtFrameInProgress.compareAndSet(false, true)) { - Log.e(TAG, "An existing management frame transmission is in progress!"); - executor.execute(() -> callback.onFailure(SEND_MGMT_FRAME_ERROR_ALREADY_STARTED)); - return; - } - - SendMgmtFrameEvent sendMgmtFrameEvent = new SendMgmtFrameEvent(executor, callback); - try { - clientInterface.SendMgmtFrame(frame, sendMgmtFrameEvent, mcs); - } catch (RemoteException e) { - Log.e(TAG, "Exception while starting link probe: " + e); - // Call sendMgmtFrameEvent.OnFailure() instead of callback.onFailure() so that - // sendMgmtFrameEvent can clean up internal state, such as cancelling the timer. - sendMgmtFrameEvent.OnFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN); - } - } - - /** - * Clear all internal handles. - */ - private void clearState() { - // Refresh handlers - mClientInterfaces.clear(); - mWificondScanners.clear(); - mPnoScanEventHandlers.clear(); - mScanEventHandlers.clear(); - mApInterfaces.clear(); - mApInterfaceListeners.clear(); - mSendMgmtFrameInProgress.set(false); - } - - /** - * OEM parsed security type - */ - public static class OemSecurityType { - /** The protocol defined in {@link android.net.wifi.WifiAnnotations.Protocol}. */ - public final @WifiAnnotations.Protocol int protocol; - /** - * Supported key management types defined - * in {@link android.net.wifi.WifiAnnotations.KeyMgmt}. - */ - @NonNull public final List keyManagement; - /** - * Supported pairwise cipher types defined - * in {@link android.net.wifi.WifiAnnotations.Cipher}. - */ - @NonNull public final List pairwiseCipher; - /** The group cipher type defined in {@link android.net.wifi.WifiAnnotations.Cipher}. */ - public final @WifiAnnotations.Cipher int groupCipher; - /** - * Default constructor for OemSecurityType - * - * @param protocol The protocol defined in - * {@link android.net.wifi.WifiAnnotations.Protocol}. - * @param keyManagement Supported key management types defined - * in {@link android.net.wifi.WifiAnnotations.KeyMgmt}. - * @param pairwiseCipher Supported pairwise cipher types defined - * in {@link android.net.wifi.WifiAnnotations.Cipher}. - * @param groupCipher The group cipher type defined - * in {@link android.net.wifi.WifiAnnotations.Cipher}. - */ - public OemSecurityType( - @WifiAnnotations.Protocol int protocol, - @NonNull List keyManagement, - @NonNull List pairwiseCipher, - @WifiAnnotations.Cipher int groupCipher) { - this.protocol = protocol; - this.keyManagement = (keyManagement != null) - ? keyManagement : new ArrayList(); - this.pairwiseCipher = (pairwiseCipher != null) - ? pairwiseCipher : new ArrayList(); - this.groupCipher = groupCipher; - } - } - - /** - * OEM information element parser for security types not parsed by the framework. - * - * The OEM method should use the method inputs {@code id}, {@code idExt}, and {@code bytes} - * to perform the parsing. The method should place the results in an OemSecurityType objct. - * - * @param id The information element id. - * @param idExt The information element extension id. This is valid only when id is - * the extension id, {@code 255}. - * @param bytes The raw bytes of information element data, 'Element ID' and 'Length' are - * stripped off already. - * @return an OemSecurityType object if this IE is parsed successfully, null otherwise. - */ - @Nullable public static OemSecurityType parseOemSecurityTypeElement( - int id, - int idExt, - @NonNull byte[] bytes) { - return null; - } -} diff --git a/wifi/java/android/net/wifi/wificond/WifiNl80211Manager.java b/wifi/java/android/net/wifi/wificond/WifiNl80211Manager.java new file mode 100644 index 000000000000..89f642fdbb66 --- /dev/null +++ b/wifi/java/android/net/wifi/wificond/WifiNl80211Manager.java @@ -0,0 +1,1287 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.wificond; + +import android.annotation.CallbackExecutor; +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.annotation.SystemService; +import android.app.AlarmManager; +import android.content.Context; +import android.net.wifi.SoftApInfo; +import android.net.wifi.WifiAnnotations; +import android.net.wifi.WifiScanner; +import android.os.Binder; +import android.os.Handler; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.os.SystemClock; +import android.util.Log; + +import com.android.internal.annotations.VisibleForTesting; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * This class encapsulates the interface the wificond daemon presents to the Wi-Fi framework - used + * to encapsulate the Wi-Fi 80211nl management interface. The + * interface is only for use by the Wi-Fi framework and access is protected by SELinux permissions. + * + * @hide + */ +@SystemApi +@SystemService(Context.WIFI_NL80211_SERVICE) +public class WifiNl80211Manager { + private static final String TAG = "WifiNl80211Manager"; + private boolean mVerboseLoggingEnabled = false; + + /** + * The {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} + * timeout, in milliseconds, after which + * {@link SendMgmtFrameCallback#onFailure(int)} will be called with reason + * {@link #SEND_MGMT_FRAME_ERROR_TIMEOUT}. + */ + private static final int SEND_MGMT_FRAME_TIMEOUT_MS = 1000; + + private static final String TIMEOUT_ALARM_TAG = TAG + " Send Management Frame Timeout"; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"SCAN_TYPE_"}, + value = {SCAN_TYPE_SINGLE_SCAN, + SCAN_TYPE_PNO_SCAN}) + public @interface ScanResultType {} + + /** + * Specifies a scan type: single scan initiated by the framework. Can be used in + * {@link #getScanResults(String, int)} to specify the type of scan result to fetch. + */ + public static final int SCAN_TYPE_SINGLE_SCAN = 0; + + /** + * Specifies a scan type: PNO scan. Can be used in {@link #getScanResults(String, int)} to + * specify the type of scan result to fetch. + */ + public static final int SCAN_TYPE_PNO_SCAN = 1; + + private AlarmManager mAlarmManager; + private Handler mEventHandler; + + // Cached wificond binder handlers. + private IWificond mWificond; + private HashMap mClientInterfaces = new HashMap<>(); + private HashMap mApInterfaces = new HashMap<>(); + private HashMap mWificondScanners = new HashMap<>(); + private HashMap mScanEventHandlers = new HashMap<>(); + private HashMap mPnoScanEventHandlers = new HashMap<>(); + private HashMap mApInterfaceListeners = new HashMap<>(); + private Runnable mDeathEventHandler; + /** + * Ensures that no more than one sendMgmtFrame operation runs concurrently. + */ + private AtomicBoolean mSendMgmtFrameInProgress = new AtomicBoolean(false); + + /** + * Interface used when waiting for scans to be completed (with results). + */ + public interface ScanEventCallback { + /** + * Called when scan results are available. Scans results should then be obtained from + * {@link #getScanResults(String, int)}. + */ + void onScanResultReady(); + + /** + * Called when a scan has failed. + */ + void onScanFailed(); + } + + /** + * Interface for a callback to provide information about PNO scan request requested with + * {@link #startPnoScan(String, PnoSettings, Executor, PnoScanRequestCallback)}. Note that the + * callback are for the status of the request - not the scan itself. The results of the scan + * are returned with {@link ScanEventCallback}. + */ + public interface PnoScanRequestCallback { + /** + * Called when a PNO scan request has been successfully submitted. + */ + void onPnoRequestSucceeded(); + + /** + * Called when a PNO scan request fails. + */ + void onPnoRequestFailed(); + } + + private class ScanEventHandler extends IScanEvent.Stub { + private Executor mExecutor; + private ScanEventCallback mCallback; + + ScanEventHandler(@NonNull Executor executor, @NonNull ScanEventCallback callback) { + mExecutor = executor; + mCallback = callback; + } + + @Override + public void OnScanResultReady() { + Log.d(TAG, "Scan result ready event"); + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mCallback.onScanResultReady()); + } + + @Override + public void OnScanFailed() { + Log.d(TAG, "Scan failed event"); + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mCallback.onScanFailed()); + } + } + + /** + * Result of a signal poll requested using {@link #signalPoll(String)}. + */ + public static class SignalPollResult { + /** @hide */ + public SignalPollResult(int currentRssiDbm, int txBitrateMbps, int rxBitrateMbps, + int associationFrequencyMHz) { + this.currentRssiDbm = currentRssiDbm; + this.txBitrateMbps = txBitrateMbps; + this.rxBitrateMbps = rxBitrateMbps; + this.associationFrequencyMHz = associationFrequencyMHz; + } + + /** + * RSSI value in dBM. + */ + public final int currentRssiDbm; + + /** + * Transmission bit rate in Mbps. + */ + public final int txBitrateMbps; + + /** + * Last received packet bit rate in Mbps. + */ + public final int rxBitrateMbps; + + /** + * Association frequency in MHz. + */ + public final int associationFrequencyMHz; + } + + /** + * Transmission counters obtained using {@link #getTxPacketCounters(String)}. + */ + public static class TxPacketCounters { + /** @hide */ + public TxPacketCounters(int txPacketSucceeded, int txPacketFailed) { + this.txPacketSucceeded = txPacketSucceeded; + this.txPacketFailed = txPacketFailed; + } + + /** + * Number of successfully transmitted packets. + */ + public final int txPacketSucceeded; + + /** + * Number of packet transmission failures. + */ + public final int txPacketFailed; + } + + /** + * Callbacks for SoftAp interface registered using + * {@link #registerApCallback(String, Executor, SoftApCallback)}. + */ + public interface SoftApCallback { + /** + * Invoked when there is a fatal failure and the SoftAp is shutdown. + */ + void onFailure(); + + /** + * Invoked when there is a change in the associated station (STA). + * @param client Information about the client whose status has changed. + * @param isConnected Indication as to whether the client is connected (true), or + * disconnected (false). + */ + void onConnectedClientsChanged(@NonNull NativeWifiClient client, boolean isConnected); + + /** + * Invoked when a channel switch event happens - i.e. the SoftAp is moved to a different + * channel. Also called on initial registration. + * @param frequencyMhz The new frequency of the SoftAp. A value of 0 is invalid and is an + * indication that the SoftAp is not enabled. + * @param bandwidth The new bandwidth of the SoftAp. + */ + void onSoftApChannelSwitched(int frequencyMhz, @WifiAnnotations.Bandwidth int bandwidth); + } + + /** + * Callback to notify the results of a + * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} call. + * Note: no callbacks will be triggered if the interface dies while sending a frame. + */ + public interface SendMgmtFrameCallback { + /** + * Called when the management frame was successfully sent and ACKed by the recipient. + * @param elapsedTimeMs The elapsed time between when the management frame was sent and when + * the ACK was processed, in milliseconds, as measured by wificond. + * This includes the time that the send frame spent queuing before it + * was sent, any firmware retries, and the time the received ACK spent + * queuing before it was processed. + */ + void onAck(int elapsedTimeMs); + + /** + * Called when the send failed. + * @param reason The error code for the failure. + */ + void onFailure(@SendMgmtFrameError int reason); + } + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"SEND_MGMT_FRAME_ERROR_"}, + value = {SEND_MGMT_FRAME_ERROR_UNKNOWN, + SEND_MGMT_FRAME_ERROR_MCS_UNSUPPORTED, + SEND_MGMT_FRAME_ERROR_NO_ACK, + SEND_MGMT_FRAME_ERROR_TIMEOUT, + SEND_MGMT_FRAME_ERROR_ALREADY_STARTED}) + public @interface SendMgmtFrameError {} + + // Send management frame error codes + + /** + * Unknown error occurred during call to + * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)}. + */ + public static final int SEND_MGMT_FRAME_ERROR_UNKNOWN = 1; + + /** + * Specifying the MCS rate in + * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} is not + * supported by this device. + */ + public static final int SEND_MGMT_FRAME_ERROR_MCS_UNSUPPORTED = 2; + + /** + * Driver reported that no ACK was received for the frame transmitted using + * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)}. + */ + public static final int SEND_MGMT_FRAME_ERROR_NO_ACK = 3; + + /** + * Error code for when the driver fails to report on the status of the frame sent by + * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} + * after {@link #SEND_MGMT_FRAME_TIMEOUT_MS} milliseconds. + */ + public static final int SEND_MGMT_FRAME_ERROR_TIMEOUT = 4; + + /** + * An existing call to + * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} + * is in progress. Another frame cannot be sent until the first call completes. + */ + public static final int SEND_MGMT_FRAME_ERROR_ALREADY_STARTED = 5; + + /** @hide */ + public WifiNl80211Manager(Context context) { + mAlarmManager = context.getSystemService(AlarmManager.class); + mEventHandler = new Handler(context.getMainLooper()); + } + + /** @hide */ + @VisibleForTesting + public WifiNl80211Manager(Context context, IWificond wificond) { + this(context); + mWificond = wificond; + } + + private class PnoScanEventHandler extends IPnoScanEvent.Stub { + private Executor mExecutor; + private ScanEventCallback mCallback; + + PnoScanEventHandler(@NonNull Executor executor, @NonNull ScanEventCallback callback) { + mExecutor = executor; + mCallback = callback; + } + + @Override + public void OnPnoNetworkFound() { + Log.d(TAG, "Pno scan result event"); + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mCallback.onScanResultReady()); + } + + @Override + public void OnPnoScanFailed() { + Log.d(TAG, "Pno Scan failed event"); + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mCallback.onScanFailed()); + } + } + + /** + * Listener for AP Interface events. + */ + private class ApInterfaceEventCallback extends IApInterfaceEventCallback.Stub { + private Executor mExecutor; + private SoftApCallback mSoftApListener; + + ApInterfaceEventCallback(Executor executor, SoftApCallback listener) { + mExecutor = executor; + mSoftApListener = listener; + } + + @Override + public void onConnectedClientsChanged(NativeWifiClient client, boolean isConnected) { + if (mVerboseLoggingEnabled) { + Log.d(TAG, "onConnectedClientsChanged called with " + + client.getMacAddress() + " isConnected: " + isConnected); + } + + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mSoftApListener.onConnectedClientsChanged(client, isConnected)); + } + + @Override + public void onSoftApChannelSwitched(int frequency, int bandwidth) { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mSoftApListener.onSoftApChannelSwitched(frequency, + toFrameworkBandwidth(bandwidth))); + } + + private @WifiAnnotations.Bandwidth int toFrameworkBandwidth(int bandwidth) { + switch(bandwidth) { + case IApInterfaceEventCallback.BANDWIDTH_INVALID: + return SoftApInfo.CHANNEL_WIDTH_INVALID; + case IApInterfaceEventCallback.BANDWIDTH_20_NOHT: + return SoftApInfo.CHANNEL_WIDTH_20MHZ_NOHT; + case IApInterfaceEventCallback.BANDWIDTH_20: + return SoftApInfo.CHANNEL_WIDTH_20MHZ; + case IApInterfaceEventCallback.BANDWIDTH_40: + return SoftApInfo.CHANNEL_WIDTH_40MHZ; + case IApInterfaceEventCallback.BANDWIDTH_80: + return SoftApInfo.CHANNEL_WIDTH_80MHZ; + case IApInterfaceEventCallback.BANDWIDTH_80P80: + return SoftApInfo.CHANNEL_WIDTH_80MHZ_PLUS_MHZ; + case IApInterfaceEventCallback.BANDWIDTH_160: + return SoftApInfo.CHANNEL_WIDTH_160MHZ; + default: + return SoftApInfo.CHANNEL_WIDTH_INVALID; + } + } + } + + /** + * Callback triggered by wificond. + */ + private class SendMgmtFrameEvent extends ISendMgmtFrameEvent.Stub { + private Executor mExecutor; + private SendMgmtFrameCallback mCallback; + private AlarmManager.OnAlarmListener mTimeoutCallback; + /** + * ensures that mCallback is only called once + */ + private boolean mWasCalled; + + private void runIfFirstCall(Runnable r) { + if (mWasCalled) return; + mWasCalled = true; + + mSendMgmtFrameInProgress.set(false); + r.run(); + } + + SendMgmtFrameEvent(@NonNull Executor executor, @NonNull SendMgmtFrameCallback callback) { + mExecutor = executor; + mCallback = callback; + // called in main thread + mTimeoutCallback = () -> runIfFirstCall(() -> { + if (mVerboseLoggingEnabled) { + Log.e(TAG, "Timed out waiting for ACK"); + } + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mCallback.onFailure(SEND_MGMT_FRAME_ERROR_TIMEOUT)); + }); + mWasCalled = false; + + mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, + SystemClock.elapsedRealtime() + SEND_MGMT_FRAME_TIMEOUT_MS, + TIMEOUT_ALARM_TAG, mTimeoutCallback, mEventHandler); + } + + // called in binder thread + @Override + public void OnAck(int elapsedTimeMs) { + // post to main thread + mEventHandler.post(() -> runIfFirstCall(() -> { + mAlarmManager.cancel(mTimeoutCallback); + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mCallback.onAck(elapsedTimeMs)); + })); + } + + // called in binder thread + @Override + public void OnFailure(int reason) { + // post to main thread + mEventHandler.post(() -> runIfFirstCall(() -> { + mAlarmManager.cancel(mTimeoutCallback); + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mCallback.onFailure(reason)); + })); + } + } + + /** + * Called by the binder subsystem upon remote object death. + * Invoke all the register death handlers and clear state. + * @hide + */ + @VisibleForTesting + public void binderDied() { + mEventHandler.post(() -> { + Log.e(TAG, "Wificond died!"); + clearState(); + // Invalidate the global wificond handle on death. Will be refreshed + // on the next setup call. + mWificond = null; + if (mDeathEventHandler != null) { + mDeathEventHandler.run(); + } + }); + } + + /** + * Enable or disable verbose logging of the WifiNl80211Manager module. + * @param enable True to enable verbose logging. False to disable verbose logging. + */ + public void enableVerboseLogging(boolean enable) { + mVerboseLoggingEnabled = enable; + } + + /** + * Register a death notification for the WifiNl80211Manager which acts as a proxy for the + * wificond daemon (i.e. the death listener will be called when and if the wificond daemon + * dies). + * + * @param deathEventHandler A {@link Runnable} to be called whenever the wificond daemon dies. + */ + public void setOnServiceDeadCallback(@NonNull Runnable deathEventHandler) { + if (mDeathEventHandler != null) { + Log.e(TAG, "Death handler already present"); + } + mDeathEventHandler = deathEventHandler; + } + + /** + * Helper method to retrieve the global wificond handle and register for + * death notifications. + */ + private boolean retrieveWificondAndRegisterForDeath() { + if (mWificond != null) { + if (mVerboseLoggingEnabled) { + Log.d(TAG, "Wificond handle already retrieved"); + } + // We already have a wificond handle. + return true; + } + IBinder binder = ServiceManager.getService(Context.WIFI_NL80211_SERVICE); + mWificond = IWificond.Stub.asInterface(binder); + if (mWificond == null) { + Log.e(TAG, "Failed to get reference to wificond"); + return false; + } + try { + mWificond.asBinder().linkToDeath(() -> binderDied(), 0); + } catch (RemoteException e) { + Log.e(TAG, "Failed to register death notification for wificond"); + // The remote has already died. + return false; + } + return true; + } + + /** + * Set up an interface for client (STA) mode. + * + * @param ifaceName Name of the interface to configure. + * @param executor The Executor on which to execute the callbacks. + * @param scanCallback A callback for framework initiated scans. + * @param pnoScanCallback A callback for PNO (offloaded) scans. + * @return true on success. + */ + public boolean setupInterfaceForClientMode(@NonNull String ifaceName, + @NonNull @CallbackExecutor Executor executor, + @NonNull ScanEventCallback scanCallback, @NonNull ScanEventCallback pnoScanCallback) { + Log.d(TAG, "Setting up interface for client mode"); + if (!retrieveWificondAndRegisterForDeath()) { + return false; + } + + if (scanCallback == null || pnoScanCallback == null || executor == null) { + Log.e(TAG, "setupInterfaceForClientMode invoked with null callbacks"); + return false; + } + + IClientInterface clientInterface = null; + try { + clientInterface = mWificond.createClientInterface(ifaceName); + } catch (RemoteException e1) { + Log.e(TAG, "Failed to get IClientInterface due to remote exception"); + return false; + } + + if (clientInterface == null) { + Log.e(TAG, "Could not get IClientInterface instance from wificond"); + return false; + } + Binder.allowBlocking(clientInterface.asBinder()); + + // Refresh Handlers + mClientInterfaces.put(ifaceName, clientInterface); + try { + IWifiScannerImpl wificondScanner = clientInterface.getWifiScannerImpl(); + if (wificondScanner == null) { + Log.e(TAG, "Failed to get WificondScannerImpl"); + return false; + } + mWificondScanners.put(ifaceName, wificondScanner); + Binder.allowBlocking(wificondScanner.asBinder()); + ScanEventHandler scanEventHandler = new ScanEventHandler(executor, scanCallback); + mScanEventHandlers.put(ifaceName, scanEventHandler); + wificondScanner.subscribeScanEvents(scanEventHandler); + PnoScanEventHandler pnoScanEventHandler = new PnoScanEventHandler(executor, + pnoScanCallback); + mPnoScanEventHandlers.put(ifaceName, pnoScanEventHandler); + wificondScanner.subscribePnoScanEvents(pnoScanEventHandler); + } catch (RemoteException e) { + Log.e(TAG, "Failed to refresh wificond scanner due to remote exception"); + } + + return true; + } + + /** + * Tear down a specific client (STA) interface configured using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}. + * + * @param ifaceName Name of the interface to tear down. + * @return Returns true on success, false on failure (e.g. when called before an interface was + * set up). + */ + public boolean tearDownClientInterface(@NonNull String ifaceName) { + if (getClientInterface(ifaceName) == null) { + Log.e(TAG, "No valid wificond client interface handler"); + return false; + } + try { + IWifiScannerImpl scannerImpl = mWificondScanners.get(ifaceName); + if (scannerImpl != null) { + scannerImpl.unsubscribeScanEvents(); + scannerImpl.unsubscribePnoScanEvents(); + } + } catch (RemoteException e) { + Log.e(TAG, "Failed to unsubscribe wificond scanner due to remote exception"); + return false; + } + + if (mWificond == null) { + Log.e(TAG, "Reference to wifiCond is null"); + return false; + } + + boolean success; + try { + success = mWificond.tearDownClientInterface(ifaceName); + } catch (RemoteException e1) { + Log.e(TAG, "Failed to teardown client interface due to remote exception"); + return false; + } + if (!success) { + Log.e(TAG, "Failed to teardown client interface"); + return false; + } + + mClientInterfaces.remove(ifaceName); + mWificondScanners.remove(ifaceName); + mScanEventHandlers.remove(ifaceName); + mPnoScanEventHandlers.remove(ifaceName); + return true; + } + + /** + * Set up interface as a Soft AP. + * + * @param ifaceName Name of the interface to configure. + * @return true on success. + */ + public boolean setupInterfaceForSoftApMode(@NonNull String ifaceName) { + Log.d(TAG, "Setting up interface for soft ap mode"); + if (!retrieveWificondAndRegisterForDeath()) { + return false; + } + + IApInterface apInterface = null; + try { + apInterface = mWificond.createApInterface(ifaceName); + } catch (RemoteException e1) { + Log.e(TAG, "Failed to get IApInterface due to remote exception"); + return false; + } + + if (apInterface == null) { + Log.e(TAG, "Could not get IApInterface instance from wificond"); + return false; + } + Binder.allowBlocking(apInterface.asBinder()); + + // Refresh Handlers + mApInterfaces.put(ifaceName, apInterface); + return true; + } + + /** + * Tear down a Soft AP interface configured using + * {@link #setupInterfaceForSoftApMode(String)}. + * + * @param ifaceName Name of the interface to tear down. + * @return Returns true on success, false on failure (e.g. when called before an interface was + * set up). + */ + public boolean tearDownSoftApInterface(@NonNull String ifaceName) { + if (getApInterface(ifaceName) == null) { + Log.e(TAG, "No valid wificond ap interface handler"); + return false; + } + + if (mWificond == null) { + Log.e(TAG, "Reference to wifiCond is null"); + return false; + } + + boolean success; + try { + success = mWificond.tearDownApInterface(ifaceName); + } catch (RemoteException e1) { + Log.e(TAG, "Failed to teardown AP interface due to remote exception"); + return false; + } + if (!success) { + Log.e(TAG, "Failed to teardown AP interface"); + return false; + } + mApInterfaces.remove(ifaceName); + mApInterfaceListeners.remove(ifaceName); + return true; + } + + /** + * Tear down all interfaces, whether clients (STA) or Soft AP. + * + * @return Returns true on success. + */ + public boolean tearDownInterfaces() { + Log.d(TAG, "tearing down interfaces in wificond"); + // Explicitly refresh the wificodn handler because |tearDownInterfaces()| + // could be used to cleanup before we setup any interfaces. + if (!retrieveWificondAndRegisterForDeath()) { + return false; + } + + try { + for (Map.Entry entry : mWificondScanners.entrySet()) { + entry.getValue().unsubscribeScanEvents(); + entry.getValue().unsubscribePnoScanEvents(); + } + mWificond.tearDownInterfaces(); + clearState(); + return true; + } catch (RemoteException e) { + Log.e(TAG, "Failed to tear down interfaces due to remote exception"); + } + + return false; + } + + /** Helper function to look up the interface handle using name */ + private IClientInterface getClientInterface(@NonNull String ifaceName) { + return mClientInterfaces.get(ifaceName); + } + + /** + * Request signal polling. + * + * @param ifaceName Name of the interface on which to poll. The interface must have been + * already set up using + *{@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} + * or {@link #setupInterfaceForSoftApMode(String)}. + * + * @return A {@link SignalPollResult} object containing interface statistics, or a null on + * error (e.g. the interface hasn't been set up yet). + */ + @Nullable public SignalPollResult signalPoll(@NonNull String ifaceName) { + IClientInterface iface = getClientInterface(ifaceName); + if (iface == null) { + Log.e(TAG, "No valid wificond client interface handler"); + return null; + } + + int[] resultArray; + try { + resultArray = iface.signalPoll(); + if (resultArray == null || resultArray.length != 4) { + Log.e(TAG, "Invalid signal poll result from wificond"); + return null; + } + } catch (RemoteException e) { + Log.e(TAG, "Failed to do signal polling due to remote exception"); + return null; + } + return new SignalPollResult(resultArray[0], resultArray[1], resultArray[3], resultArray[2]); + } + + /** + * Get current transmit (Tx) packet counters of the specified interface. The interface must + * have been already set up using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} + * or {@link #setupInterfaceForSoftApMode(String)}. + * + * @param ifaceName Name of the interface. + * @return {@link TxPacketCounters} of the current interface or null on error (e.g. when + * called before the interface has been set up). + */ + @Nullable public TxPacketCounters getTxPacketCounters(@NonNull String ifaceName) { + IClientInterface iface = getClientInterface(ifaceName); + if (iface == null) { + Log.e(TAG, "No valid wificond client interface handler"); + return null; + } + + int[] resultArray; + try { + resultArray = iface.getPacketCounters(); + if (resultArray == null || resultArray.length != 2) { + Log.e(TAG, "Invalid signal poll result from wificond"); + return null; + } + } catch (RemoteException e) { + Log.e(TAG, "Failed to do signal polling due to remote exception"); + return null; + } + return new TxPacketCounters(resultArray[0], resultArray[1]); + } + + /** Helper function to look up the scanner impl handle using name */ + private IWifiScannerImpl getScannerImpl(@NonNull String ifaceName) { + return mWificondScanners.get(ifaceName); + } + + /** + * Fetch the latest scan results of the indicated type for the specified interface. Note that + * this method fetches the latest results - it does not initiate a scan. Initiating a scan can + * be done using {@link #startScan(String, int, Set, List)} or + * {@link #startPnoScan(String, PnoSettings, Executor, PnoScanRequestCallback)}. + * + * Note: The interface must have been already set up using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} + * or {@link #setupInterfaceForSoftApMode(String)}. + * + * @param ifaceName Name of the interface. + * @param scanType The type of scan result to be returned, can be + * {@link #SCAN_TYPE_SINGLE_SCAN} or {@link #SCAN_TYPE_PNO_SCAN}. + * @return Returns an array of {@link NativeScanResult} or an empty array on failure (e.g. when + * called before the interface has been set up). + */ + @NonNull public List getScanResults(@NonNull String ifaceName, + @ScanResultType int scanType) { + IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); + if (scannerImpl == null) { + Log.e(TAG, "No valid wificond scanner interface handler"); + return new ArrayList<>(); + } + List results = null; + try { + if (scanType == SCAN_TYPE_SINGLE_SCAN) { + results = Arrays.asList(scannerImpl.getScanResults()); + } else { + results = Arrays.asList(scannerImpl.getPnoScanResults()); + } + } catch (RemoteException e1) { + Log.e(TAG, "Failed to create ScanDetail ArrayList"); + } + if (results == null) { + results = new ArrayList<>(); + } + if (mVerboseLoggingEnabled) { + Log.d(TAG, "get " + results.size() + " scan results from wificond"); + } + + return results; + } + + /** + * Return scan type for the parcelable {@link SingleScanSettings} + */ + private static int getScanType(@WifiAnnotations.ScanType int scanType) { + switch (scanType) { + case WifiScanner.SCAN_TYPE_LOW_LATENCY: + return IWifiScannerImpl.SCAN_TYPE_LOW_SPAN; + case WifiScanner.SCAN_TYPE_LOW_POWER: + return IWifiScannerImpl.SCAN_TYPE_LOW_POWER; + case WifiScanner.SCAN_TYPE_HIGH_ACCURACY: + return IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY; + default: + throw new IllegalArgumentException("Invalid scan type " + scanType); + } + } + + /** + * Start a scan using the specified parameters. A scan is an asynchronous operation. The + * result of the operation is returned in the {@link ScanEventCallback} registered when + * setting up an interface using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}. + * The latest scans can be obtained using {@link #getScanResults(String, int)} and using a + * {@link #SCAN_TYPE_SINGLE_SCAN} for the {@code scanType}. + * + * Note: The interface must have been already set up using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} + * or {@link #setupInterfaceForSoftApMode(String)}. + * + * @param ifaceName Name of the interface on which to initiate the scan. + * @param scanType Type of scan to perform, can be any of + * {@link WifiScanner#SCAN_TYPE_HIGH_ACCURACY}, {@link WifiScanner#SCAN_TYPE_LOW_POWER}, or + * {@link WifiScanner#SCAN_TYPE_LOW_LATENCY}. + * @param freqs list of frequencies to scan for, if null scan all supported channels. + * @param hiddenNetworkSSIDs List of hidden networks to be scanned for, a null indicates that + * no hidden frequencies will be scanned for. + * @return Returns true on success, false on failure (e.g. when called before the interface + * has been set up). + */ + public boolean startScan(@NonNull String ifaceName, @WifiAnnotations.ScanType int scanType, + @Nullable Set freqs, @Nullable List hiddenNetworkSSIDs) { + IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); + if (scannerImpl == null) { + Log.e(TAG, "No valid wificond scanner interface handler"); + return false; + } + SingleScanSettings settings = new SingleScanSettings(); + try { + settings.scanType = getScanType(scanType); + } catch (IllegalArgumentException e) { + Log.e(TAG, "Invalid scan type ", e); + return false; + } + settings.channelSettings = new ArrayList<>(); + settings.hiddenNetworks = new ArrayList<>(); + + if (freqs != null) { + for (Integer freq : freqs) { + ChannelSettings channel = new ChannelSettings(); + channel.frequency = freq; + settings.channelSettings.add(channel); + } + } + if (hiddenNetworkSSIDs != null) { + for (byte[] ssid : hiddenNetworkSSIDs) { + HiddenNetwork network = new HiddenNetwork(); + network.ssid = ssid; + + // settings.hiddenNetworks is expected to be very small, so this shouldn't cause + // any performance issues. + if (!settings.hiddenNetworks.contains(network)) { + settings.hiddenNetworks.add(network); + } + } + } + + try { + return scannerImpl.scan(settings); + } catch (RemoteException e1) { + Log.e(TAG, "Failed to request scan due to remote exception"); + } + return false; + } + + /** + * Request a PNO (Preferred Network Offload). The offload request and the scans are asynchronous + * operations. The result of the request are returned in the {@code callback} parameter which + * is an {@link PnoScanRequestCallback}. The scan results are are return in the + * {@link ScanEventCallback} which is registered when setting up an interface using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}. + * The latest PNO scans can be obtained using {@link #getScanResults(String, int)} with the + * {@code scanType} set to {@link #SCAN_TYPE_PNO_SCAN}. + * + * Note: The interface must have been already set up using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} + * or {@link #setupInterfaceForSoftApMode(String)}. + * + * @param ifaceName Name of the interface on which to request a PNO. + * @param pnoSettings PNO scan configuration. + * @param executor The Executor on which to execute the callback. + * @param callback Callback for the results of the offload request. + * @return true on success, false on failure (e.g. when called before the interface has been set + * up). + */ + public boolean startPnoScan(@NonNull String ifaceName, @NonNull PnoSettings pnoSettings, + @NonNull @CallbackExecutor Executor executor, + @NonNull PnoScanRequestCallback callback) { + IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); + if (scannerImpl == null) { + Log.e(TAG, "No valid wificond scanner interface handler"); + return false; + } + + if (callback == null || executor == null) { + Log.e(TAG, "startPnoScan called with a null callback"); + return false; + } + + try { + boolean success = scannerImpl.startPnoScan(pnoSettings); + if (success) { + executor.execute(callback::onPnoRequestSucceeded); + } else { + executor.execute(callback::onPnoRequestFailed); + } + return success; + } catch (RemoteException e1) { + Log.e(TAG, "Failed to start pno scan due to remote exception"); + } + return false; + } + + /** + * Stop PNO scan configured with + * {@link #startPnoScan(String, PnoSettings, Executor, PnoScanRequestCallback)}. + * + * Note: The interface must have been already set up using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} + * or {@link #setupInterfaceForSoftApMode(String)}. + * + * @param ifaceName Name of the interface on which the PNO scan was configured. + * @return true on success, false on failure (e.g. when called before the interface has been + * set up). + */ + public boolean stopPnoScan(@NonNull String ifaceName) { + IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); + if (scannerImpl == null) { + Log.e(TAG, "No valid wificond scanner interface handler"); + return false; + } + try { + return scannerImpl.stopPnoScan(); + } catch (RemoteException e1) { + Log.e(TAG, "Failed to stop pno scan due to remote exception"); + } + return false; + } + + /** + * Abort ongoing single scan started with {@link #startScan(String, int, Set, List)}. No failure + * callback, e.g. {@link ScanEventCallback#onScanFailed()}, is triggered by this operation. + * + * Note: The interface must have been already set up using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} + * or {@link #setupInterfaceForSoftApMode(String)}. If the interface has not been set up then + * this method has no impact. + * + * @param ifaceName Name of the interface on which the scan was started. + */ + public void abortScan(@NonNull String ifaceName) { + IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); + if (scannerImpl == null) { + Log.e(TAG, "No valid wificond scanner interface handler"); + return; + } + try { + scannerImpl.abortScan(); + } catch (RemoteException e1) { + Log.e(TAG, "Failed to request abortScan due to remote exception"); + } + } + + /** + * Query the list of valid frequencies (in MHz) for the provided band. + * The result depends on the on the country code that has been set. + * + * @param band as specified by one of the WifiScanner.WIFI_BAND_* constants. + * The following bands are supported {@link @WifiScanner.WifiBandBasic}: + * WifiScanner.WIFI_BAND_24_GHZ + * WifiScanner.WIFI_BAND_5_GHZ + * WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY + * WifiScanner.WIFI_BAND_6_GHZ + * @return frequencies vector of valid frequencies (MHz), or an empty array for error. + * @throws IllegalArgumentException if band is not recognized. + */ + public @NonNull int[] getChannelsMhzForBand(@WifiAnnotations.WifiBandBasic int band) { + if (mWificond == null) { + Log.e(TAG, "No valid wificond scanner interface handler"); + return new int[0]; + } + int[] result = null; + try { + switch (band) { + case WifiScanner.WIFI_BAND_24_GHZ: + result = mWificond.getAvailable2gChannels(); + break; + case WifiScanner.WIFI_BAND_5_GHZ: + result = mWificond.getAvailable5gNonDFSChannels(); + break; + case WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY: + result = mWificond.getAvailableDFSChannels(); + break; + case WifiScanner.WIFI_BAND_6_GHZ: + result = mWificond.getAvailable6gChannels(); + break; + default: + throw new IllegalArgumentException("unsupported band " + band); + } + } catch (RemoteException e1) { + Log.e(TAG, "Failed to request getChannelsForBand due to remote exception"); + } + if (result == null) { + result = new int[0]; + } + return result; + } + + /** Helper function to look up the interface handle using name */ + private IApInterface getApInterface(@NonNull String ifaceName) { + return mApInterfaces.get(ifaceName); + } + + /** + * Get the device phy capabilities for a given interface. + * + * Note: The interface must have been already set up using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} + * or {@link #setupInterfaceForSoftApMode(String)}. + * + * @return DeviceWiphyCapabilities or null on error (e.g. when called on an interface which has + * not been set up). + */ + @Nullable public DeviceWiphyCapabilities getDeviceWiphyCapabilities(@NonNull String ifaceName) { + if (mWificond == null) { + Log.e(TAG, "Can not query for device wiphy capabilities at this time"); + return null; + } + + try { + return mWificond.getDeviceWiphyCapabilities(ifaceName); + } catch (RemoteException e) { + return null; + } + } + + /** + * Register the provided callback handler for SoftAp events. The interface must first be created + * using {@link #setupInterfaceForSoftApMode(String)}. The callback registration is valid until + * the interface is deleted using {@link #tearDownSoftApInterface(String)} (no deregistration + * method is provided). + *

    + * Note that only one callback can be registered at a time - any registration overrides previous + * registrations. + * + * @param ifaceName Name of the interface on which to register the callback. + * @param executor The Executor on which to execute the callbacks. + * @param callback Callback for AP events. + * @return true on success, false on failure (e.g. when called on an interface which has not + * been set up). + */ + public boolean registerApCallback(@NonNull String ifaceName, + @NonNull @CallbackExecutor Executor executor, + @NonNull SoftApCallback callback) { + IApInterface iface = getApInterface(ifaceName); + if (iface == null) { + Log.e(TAG, "No valid ap interface handler"); + return false; + } + + if (callback == null || executor == null) { + Log.e(TAG, "registerApCallback called with a null callback"); + return false; + } + + try { + IApInterfaceEventCallback wificondCallback = new ApInterfaceEventCallback(executor, + callback); + mApInterfaceListeners.put(ifaceName, wificondCallback); + boolean success = iface.registerCallback(wificondCallback); + if (!success) { + Log.e(TAG, "Failed to register ap callback."); + return false; + } + } catch (RemoteException e) { + Log.e(TAG, "Exception in registering AP callback: " + e); + return false; + } + return true; + } + + /** + * Send a management frame on the specified interface at the specified rate. Useful for probing + * the link with arbitrary frames. + * + * Note: The interface must have been already set up using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} + * or {@link #setupInterfaceForSoftApMode(String)}. + * + * @param ifaceName The interface on which to send the frame. + * @param frame The raw byte array of the management frame to tramit. + * @param mcs The MCS (modulation and coding scheme), i.e. rate, at which to transmit the + * frame. Specified per IEEE 802.11. + * @param executor The Executor on which to execute the callbacks. + * @param callback A {@link SendMgmtFrameCallback} callback for results of the operation. + */ + public void sendMgmtFrame(@NonNull String ifaceName, @NonNull byte[] frame, int mcs, + @NonNull @CallbackExecutor Executor executor, + @NonNull SendMgmtFrameCallback callback) { + + if (callback == null || executor == null) { + Log.e(TAG, "callback cannot be null!"); + return; + } + + if (frame == null) { + Log.e(TAG, "frame cannot be null!"); + executor.execute(() -> callback.onFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN)); + return; + } + + // TODO (b/112029045) validate mcs + IClientInterface clientInterface = getClientInterface(ifaceName); + if (clientInterface == null) { + Log.e(TAG, "No valid wificond client interface handler"); + executor.execute(() -> callback.onFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN)); + return; + } + + if (!mSendMgmtFrameInProgress.compareAndSet(false, true)) { + Log.e(TAG, "An existing management frame transmission is in progress!"); + executor.execute(() -> callback.onFailure(SEND_MGMT_FRAME_ERROR_ALREADY_STARTED)); + return; + } + + SendMgmtFrameEvent sendMgmtFrameEvent = new SendMgmtFrameEvent(executor, callback); + try { + clientInterface.SendMgmtFrame(frame, sendMgmtFrameEvent, mcs); + } catch (RemoteException e) { + Log.e(TAG, "Exception while starting link probe: " + e); + // Call sendMgmtFrameEvent.OnFailure() instead of callback.onFailure() so that + // sendMgmtFrameEvent can clean up internal state, such as cancelling the timer. + sendMgmtFrameEvent.OnFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN); + } + } + + /** + * Clear all internal handles. + */ + private void clearState() { + // Refresh handlers + mClientInterfaces.clear(); + mWificondScanners.clear(); + mPnoScanEventHandlers.clear(); + mScanEventHandlers.clear(); + mApInterfaces.clear(); + mApInterfaceListeners.clear(); + mSendMgmtFrameInProgress.set(false); + } + + /** + * OEM parsed security type + */ + public static class OemSecurityType { + /** The protocol defined in {@link android.net.wifi.WifiAnnotations.Protocol}. */ + public final @WifiAnnotations.Protocol int protocol; + /** + * Supported key management types defined + * in {@link android.net.wifi.WifiAnnotations.KeyMgmt}. + */ + @NonNull public final List keyManagement; + /** + * Supported pairwise cipher types defined + * in {@link android.net.wifi.WifiAnnotations.Cipher}. + */ + @NonNull public final List pairwiseCipher; + /** The group cipher type defined in {@link android.net.wifi.WifiAnnotations.Cipher}. */ + public final @WifiAnnotations.Cipher int groupCipher; + /** + * Default constructor for OemSecurityType + * + * @param protocol The protocol defined in + * {@link android.net.wifi.WifiAnnotations.Protocol}. + * @param keyManagement Supported key management types defined + * in {@link android.net.wifi.WifiAnnotations.KeyMgmt}. + * @param pairwiseCipher Supported pairwise cipher types defined + * in {@link android.net.wifi.WifiAnnotations.Cipher}. + * @param groupCipher The group cipher type defined + * in {@link android.net.wifi.WifiAnnotations.Cipher}. + */ + public OemSecurityType( + @WifiAnnotations.Protocol int protocol, + @NonNull List keyManagement, + @NonNull List pairwiseCipher, + @WifiAnnotations.Cipher int groupCipher) { + this.protocol = protocol; + this.keyManagement = (keyManagement != null) + ? keyManagement : new ArrayList(); + this.pairwiseCipher = (pairwiseCipher != null) + ? pairwiseCipher : new ArrayList(); + this.groupCipher = groupCipher; + } + } + + /** + * OEM information element parser for security types not parsed by the framework. + * + * The OEM method should use the method inputs {@code id}, {@code idExt}, and {@code bytes} + * to perform the parsing. The method should place the results in an OemSecurityType objct. + * + * @param id The information element id. + * @param idExt The information element extension id. This is valid only when id is + * the extension id, {@code 255}. + * @param bytes The raw bytes of information element data, 'Element ID' and 'Length' are + * stripped off already. + * @return an OemSecurityType object if this IE is parsed successfully, null otherwise. + */ + @Nullable public static OemSecurityType parseOemSecurityTypeElement( + int id, + int idExt, + @NonNull byte[] bytes) { + return null; + } +} diff --git a/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java b/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java deleted file mode 100644 index b745a341b459..000000000000 --- a/wifi/tests/src/android/net/wifi/wificond/WifiCondManagerTest.java +++ /dev/null @@ -1,1263 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.wifi.wificond; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Matchers.argThat; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyLong; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import android.app.AlarmManager; -import android.app.test.TestAlarmManager; -import android.content.Context; -import android.net.MacAddress; -import android.net.wifi.ScanResult; -import android.net.wifi.SoftApInfo; -import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiScanner; -import android.net.wifi.util.HexEncoding; -import android.os.Handler; -import android.os.IBinder; -import android.os.RemoteException; -import android.os.test.TestLooper; - -import androidx.test.filters.SmallTest; - -import org.junit.Before; -import org.junit.Test; -import org.mockito.AdditionalMatchers; -import org.mockito.ArgumentCaptor; -import org.mockito.ArgumentMatcher; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.charset.CharacterCodingException; -import java.nio.charset.CharsetDecoder; -import java.nio.charset.CharsetEncoder; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -/** - * Unit tests for {@link android.net.wifi.WifiCondManager}. - */ -@SmallTest -public class WifiCondManagerTest { - @Mock - private IWificond mWificond; - @Mock - private IBinder mWifiCondBinder; - @Mock - private IClientInterface mClientInterface; - @Mock - private IWifiScannerImpl mWifiScannerImpl; - @Mock - private IApInterface mApInterface; - @Mock - private WifiCondManager.SoftApCallback mSoftApListener; - @Mock - private WifiCondManager.SendMgmtFrameCallback mSendMgmtFrameCallback; - @Mock - private WifiCondManager.ScanEventCallback mNormalScanCallback; - @Mock - private WifiCondManager.ScanEventCallback mPnoScanCallback; - @Mock - private WifiCondManager.PnoScanRequestCallback mPnoScanRequestCallback; - @Mock - private Context mContext; - private TestLooper mLooper; - private TestAlarmManager mTestAlarmManager; - private AlarmManager mAlarmManager; - private WifiCondManager mWificondControl; - private static final String TEST_INTERFACE_NAME = "test_wlan_if"; - private static final String TEST_INTERFACE_NAME1 = "test_wlan_if1"; - private static final String TEST_INVALID_INTERFACE_NAME = "asdf"; - private static final byte[] TEST_SSID = - new byte[]{'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'}; - private static final byte[] TEST_PSK = - new byte[]{'T', 'e', 's', 't'}; - - private static final Set SCAN_FREQ_SET = - new HashSet() {{ - add(2410); - add(2450); - add(5050); - add(5200); - }}; - private static final String TEST_QUOTED_SSID_1 = "\"testSsid1\""; - private static final String TEST_QUOTED_SSID_2 = "\"testSsid2\""; - private static final int[] TEST_FREQUENCIES_1 = {}; - private static final int[] TEST_FREQUENCIES_2 = {2500, 5124}; - private static final MacAddress TEST_RAW_MAC_BYTES = MacAddress.fromBytes( - new byte[]{0x00, 0x01, 0x02, 0x03, 0x04, 0x05}); - - private static final List SCAN_HIDDEN_NETWORK_SSID_LIST = - new ArrayList() {{ - add(LocalNativeUtil.byteArrayFromArrayList( - LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_1))); - add(LocalNativeUtil.byteArrayFromArrayList( - LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_2))); - }}; - - private static final PnoSettings TEST_PNO_SETTINGS = new PnoSettings(); - static { - TEST_PNO_SETTINGS.setIntervalMillis(6000); - List initPnoNetworks = new ArrayList<>(); - PnoNetwork network = new PnoNetwork(); - network.setSsid(LocalNativeUtil.byteArrayFromArrayList( - LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_1))); - network.setHidden(true); - network.setFrequenciesMhz(TEST_FREQUENCIES_1); - initPnoNetworks.add(network); - network.setSsid(LocalNativeUtil.byteArrayFromArrayList( - LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_2))); - network.setHidden(false); - network.setFrequenciesMhz(TEST_FREQUENCIES_2); - initPnoNetworks.add(network); - TEST_PNO_SETTINGS.setPnoNetworks(initPnoNetworks); - } - - private static final int TEST_MCS_RATE = 5; - private static final int TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS = 100; - private static final byte[] TEST_PROBE_FRAME = { - 0x40, 0x00, 0x3c, 0x00, (byte) 0xa8, (byte) 0xbd, 0x27, 0x5b, - 0x33, 0x72, (byte) 0xf4, (byte) 0xf5, (byte) 0xe8, 0x51, (byte) 0x9e, 0x09, - (byte) 0xa8, (byte) 0xbd, 0x27, 0x5b, 0x33, 0x72, (byte) 0xb0, 0x66, - 0x00, 0x00 - }; - - @Before - public void setUp() throws Exception { - // Setup mocks for successful WificondControl operation. Failure case mocks should be - // created in specific tests - MockitoAnnotations.initMocks(this); - - mTestAlarmManager = new TestAlarmManager(); - mAlarmManager = mTestAlarmManager.getAlarmManager(); - when(mContext.getSystemServiceName(AlarmManager.class)).thenReturn(Context.ALARM_SERVICE); - when(mContext.getSystemService(AlarmManager.class)).thenReturn(mAlarmManager); - - mLooper = new TestLooper(); - when(mContext.getMainLooper()).thenReturn(mLooper.getLooper()); - - when(mWificond.asBinder()).thenReturn(mWifiCondBinder); - when(mClientInterface.getWifiScannerImpl()).thenReturn(mWifiScannerImpl); - when(mWificond.createClientInterface(any())).thenReturn(mClientInterface); - when(mWificond.createApInterface(any())).thenReturn(mApInterface); - when(mWificond.tearDownClientInterface(any())).thenReturn(true); - when(mWificond.tearDownApInterface(any())).thenReturn(true); - when(mClientInterface.getWifiScannerImpl()).thenReturn(mWifiScannerImpl); - when(mClientInterface.getInterfaceName()).thenReturn(TEST_INTERFACE_NAME); - mWificondControl = new WifiCondManager(mContext, mWificond); - assertEquals(true, - mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, Runnable::run, - mNormalScanCallback, mPnoScanCallback)); - } - - /** - * Verifies that setupInterfaceForClientMode(TEST_INTERFACE_NAME) calls Wificond. - */ - @Test - public void testSetupInterfaceForClientMode() throws Exception { - when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); - verify(mWificond).createClientInterface(TEST_INTERFACE_NAME); - } - - /** - * Verifies that setupInterfaceForClientMode(TEST_INTERFACE_NAME) calls subscribeScanEvents(). - */ - @Test - public void testSetupInterfaceForClientModeCallsScanEventSubscripiton() throws Exception { - verify(mWifiScannerImpl).subscribeScanEvents(any(IScanEvent.class)); - } - - /** - * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. - */ - @Test - public void testTeardownClientInterface() throws Exception { - when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(true); - - assertTrue(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); - verify(mWifiScannerImpl).unsubscribeScanEvents(); - verify(mWifiScannerImpl).unsubscribePnoScanEvents(); - verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME); - } - - /** - * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. - */ - @Test - public void testTeardownClientInterfaceOnInvalidIface() throws Exception { - when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME1)).thenReturn(true); - - assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME1)); - verify(mWifiScannerImpl, never()).unsubscribeScanEvents(); - verify(mWifiScannerImpl, never()).unsubscribePnoScanEvents(); - verify(mWificond, never()).tearDownClientInterface(any()); - } - - /** - * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. - */ - @Test - public void testTeardownClientInterfaceFailDueToExceptionScannerUnsubscribe() throws Exception { - when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(true); - doThrow(new RemoteException()).when(mWifiScannerImpl).unsubscribeScanEvents(); - - assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); - verify(mWifiScannerImpl).unsubscribeScanEvents(); - verify(mWifiScannerImpl, never()).unsubscribePnoScanEvents(); - verify(mWificond, never()).tearDownClientInterface(TEST_INTERFACE_NAME); - } - - /** - * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. - */ - @Test - public void testTeardownClientInterfaceErrorWhenWificondFailed() throws Exception { - when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(false); - - assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); - verify(mWifiScannerImpl).unsubscribeScanEvents(); - verify(mWifiScannerImpl).unsubscribePnoScanEvents(); - verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME); - } - - /** - * Verifies that the client handles are cleared after teardown. - */ - @Test - public void testTeardownClientInterfaceClearsHandles() throws Exception { - testTeardownClientInterface(); - - assertNull(mWificondControl.signalPoll(TEST_INTERFACE_NAME)); - verify(mClientInterface, never()).signalPoll(); - - assertFalse(mWificondControl.startScan( - TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_LATENCY, - SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); - verify(mWifiScannerImpl, never()).scan(any()); - } - - /** - * Verifies that setupInterfaceForSoftApMode(TEST_INTERFACE_NAME) calls wificond. - */ - @Test - public void testSetupInterfaceForSoftApMode() throws Exception { - when(mWificond.createApInterface(TEST_INTERFACE_NAME)).thenReturn(mApInterface); - - assertEquals(true, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME)); - verify(mWificond).createApInterface(TEST_INTERFACE_NAME); - } - - /** - * Verifies that setupInterfaceForSoftAp() returns null when wificond is not started. - */ - @Test - public void testSetupInterfaceForSoftApModeErrorWhenWificondIsNotStarted() throws Exception { - // Invoke wificond death handler to clear the handle. - mWificondControl.binderDied(); - mLooper.dispatchAll(); - - assertEquals(false, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME)); - } - - /** - * Verifies that setupInterfaceForSoftApMode(TEST_INTERFACE_NAME) returns null when wificond - * failed to setup AP interface. - */ - @Test - public void testSetupInterfaceForSoftApModeErrorWhenWificondFailedToSetupInterface() - throws Exception { - when(mWificond.createApInterface(TEST_INTERFACE_NAME)).thenReturn(null); - - assertEquals(false, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME)); - } - - /** - * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. - */ - @Test - public void testTeardownSoftApInterface() throws Exception { - testSetupInterfaceForSoftApMode(); - when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME)).thenReturn(true); - - assertTrue(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME)); - verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME); - } - - /** - * Verifies that tearDownSoftapInterface(TEST_INTERFACE_NAME) calls Wificond. - */ - @Test - public void testTeardownSoftApInterfaceOnInvalidIface() throws Exception { - testSetupInterfaceForSoftApMode(); - when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME1)).thenReturn(true); - - assertFalse(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME1)); - verify(mWificond, never()).tearDownApInterface(any()); - } - - /** - * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. - */ - @Test - public void testTeardownSoftApInterfaceErrorWhenWificondFailed() throws Exception { - testSetupInterfaceForSoftApMode(); - when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME)).thenReturn(false); - - assertFalse(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME)); - verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME); - } - - /** - * Verifies that the SoftAp handles are cleared after teardown. - */ - @Test - public void testTeardownSoftApInterfaceClearsHandles() throws Exception { - testTeardownSoftApInterface(); - - assertFalse(mWificondControl.registerApCallback( - TEST_INTERFACE_NAME, Runnable::run, mSoftApListener)); - verify(mApInterface, never()).registerCallback(any()); - } - - /** - * Verifies that we can setup concurrent interfaces. - */ - @Test - public void testSetupMultipleInterfaces() throws Exception { - when(mWificond.createApInterface(TEST_INTERFACE_NAME1)).thenReturn(mApInterface); - - assertEquals(true, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME1)); - - verify(mWificond).createClientInterface(TEST_INTERFACE_NAME); - verify(mWificond).createApInterface(TEST_INTERFACE_NAME1); - } - - /** - * Verifies that we can setup concurrent interfaces. - */ - @Test - public void testTeardownMultipleInterfaces() throws Exception { - testSetupMultipleInterfaces(); - assertTrue(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); - assertTrue(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME1)); - - verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME); - verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME1); - } - - /** - * Verifies that tearDownInterfaces() calls wificond. - */ - @Test - public void testTearDownInterfaces() throws Exception { - assertTrue(mWificondControl.tearDownInterfaces()); - verify(mWificond).tearDownInterfaces(); - } - - /** - * Verifies that tearDownInterfaces() calls unsubscribeScanEvents() when there was - * a configured client interface. - */ - @Test - public void testTearDownInterfacesRemovesScanEventSubscription() throws Exception { - assertTrue(mWificondControl.tearDownInterfaces()); - verify(mWifiScannerImpl).unsubscribeScanEvents(); - } - - /** - * Verifies that tearDownInterfaces() returns false when wificond is not started. - */ - @Test - public void testTearDownInterfacesErrorWhenWificondIsNotStarterd() throws Exception { - // Invoke wificond death handler to clear the handle. - mWificondControl.binderDied(); - mLooper.dispatchAll(); - assertFalse(mWificondControl.tearDownInterfaces()); - } - - /** - * Verifies that signalPoll() calls wificond. - */ - @Test - public void testSignalPoll() throws Exception { - when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); - - mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, Runnable::run, - mNormalScanCallback, mPnoScanCallback); - mWificondControl.signalPoll(TEST_INTERFACE_NAME); - verify(mClientInterface).signalPoll(); - } - - /** - * Verifies that signalPoll() returns null when there is no configured client interface. - */ - @Test - public void testSignalPollErrorWhenNoClientInterfaceConfigured() throws Exception { - when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); - - // Configure client interface. - assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, - Runnable::run, mNormalScanCallback, mPnoScanCallback)); - - // Tear down interfaces. - assertTrue(mWificondControl.tearDownInterfaces()); - - // Signal poll should fail. - assertEquals(null, mWificondControl.signalPoll(TEST_INTERFACE_NAME)); - } - - /** - * Verifies that getTxPacketCounters() calls wificond. - */ - @Test - public void testGetTxPacketCounters() throws Exception { - when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); - - mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, Runnable::run, - mNormalScanCallback, mPnoScanCallback); - mWificondControl.getTxPacketCounters(TEST_INTERFACE_NAME); - verify(mClientInterface).getPacketCounters(); - } - - /** - * Verifies that getTxPacketCounters() returns null when there is no configured client - * interface. - */ - @Test - public void testGetTxPacketCountersErrorWhenNoClientInterfaceConfigured() throws Exception { - when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); - - // Configure client interface. - assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, - Runnable::run, mNormalScanCallback, mPnoScanCallback)); - - // Tear down interfaces. - assertTrue(mWificondControl.tearDownInterfaces()); - - // Signal poll should fail. - assertEquals(null, mWificondControl.getTxPacketCounters(TEST_INTERFACE_NAME)); - } - - /** - * Verifies that getScanResults() returns null when there is no configured client - * interface. - */ - @Test - public void testGetScanResultsErrorWhenNoClientInterfaceConfigured() throws Exception { - when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); - - // Configure client interface. - assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, - Runnable::run, mNormalScanCallback, mPnoScanCallback)); - - // Tear down interfaces. - assertTrue(mWificondControl.tearDownInterfaces()); - - // getScanResults should fail. - assertEquals(0, - mWificondControl.getScanResults(TEST_INTERFACE_NAME, - WifiCondManager.SCAN_TYPE_SINGLE_SCAN).size()); - } - - /** - * Verifies that Scan() can convert input parameters to SingleScanSettings correctly. - */ - @Test - public void testScan() throws Exception { - when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true); - assertTrue(mWificondControl.startScan( - TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_POWER, - SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); - verify(mWifiScannerImpl).scan(argThat(new ScanMatcher( - IWifiScannerImpl.SCAN_TYPE_LOW_POWER, - SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST))); - } - - /** - * Verifies that Scan() removes duplicates hiddenSsids passed in from input. - */ - @Test - public void testScanWithDuplicateHiddenSsids() throws Exception { - when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true); - // Create a list of hiddenSsid that has a duplicate element - List hiddenSsidWithDup = new ArrayList<>(SCAN_HIDDEN_NETWORK_SSID_LIST); - hiddenSsidWithDup.add(SCAN_HIDDEN_NETWORK_SSID_LIST.get(0)); - assertEquals(hiddenSsidWithDup.get(0), - hiddenSsidWithDup.get(hiddenSsidWithDup.size() - 1)); - // Pass the List with duplicate elements into scan() - assertTrue(mWificondControl.startScan( - TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_POWER, - SCAN_FREQ_SET, hiddenSsidWithDup)); - // But the argument passed down should have the duplicate removed. - verify(mWifiScannerImpl).scan(argThat(new ScanMatcher( - IWifiScannerImpl.SCAN_TYPE_LOW_POWER, - SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST))); - } - - /** - * Verifies that Scan() can handle null input parameters correctly. - */ - @Test - public void testScanNullParameters() throws Exception { - when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true); - assertTrue(mWificondControl.startScan( - TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_HIGH_ACCURACY, null, null)); - verify(mWifiScannerImpl).scan(argThat(new ScanMatcher( - IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY, null, null))); - } - - /** - * Verifies that Scan() can handle wificond scan failure. - */ - @Test - public void testScanFailure() throws Exception { - when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(false); - assertFalse(mWificondControl.startScan( - TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_LATENCY, - SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); - verify(mWifiScannerImpl).scan(any(SingleScanSettings.class)); - } - - /** - * Verifies that Scan() can handle invalid type. - */ - @Test - public void testScanFailureDueToInvalidType() throws Exception { - assertFalse(mWificondControl.startScan( - TEST_INTERFACE_NAME, 100, - SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); - verify(mWifiScannerImpl, never()).scan(any(SingleScanSettings.class)); - } - - /** - * Verifies that startPnoScan() can convert input parameters to PnoSettings correctly. - */ - @Test - public void testStartPnoScan() throws Exception { - when(mWifiScannerImpl.startPnoScan(any(PnoSettings.class))).thenReturn(true); - assertTrue( - mWificondControl.startPnoScan(TEST_INTERFACE_NAME, TEST_PNO_SETTINGS, Runnable::run, - mPnoScanRequestCallback)); - verify(mWifiScannerImpl).startPnoScan(eq(TEST_PNO_SETTINGS)); - verify(mPnoScanRequestCallback).onPnoRequestSucceeded(); - } - - /** - * Verifies that stopPnoScan() calls underlying wificond. - */ - @Test - public void testStopPnoScan() throws Exception { - when(mWifiScannerImpl.stopPnoScan()).thenReturn(true); - assertTrue(mWificondControl.stopPnoScan(TEST_INTERFACE_NAME)); - verify(mWifiScannerImpl).stopPnoScan(); - } - - /** - * Verifies that stopPnoScan() can handle wificond failure. - */ - @Test - public void testStopPnoScanFailure() throws Exception { - - when(mWifiScannerImpl.stopPnoScan()).thenReturn(false); - assertFalse(mWificondControl.stopPnoScan(TEST_INTERFACE_NAME)); - verify(mWifiScannerImpl).stopPnoScan(); - } - - /** - * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon scan - * result event. - */ - @Test - public void testScanResultEvent() throws Exception { - ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(IScanEvent.class); - verify(mWifiScannerImpl).subscribeScanEvents(messageCaptor.capture()); - IScanEvent scanEvent = messageCaptor.getValue(); - assertNotNull(scanEvent); - scanEvent.OnScanResultReady(); - - verify(mNormalScanCallback).onScanResultReady(); - } - - /** - * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon scan - * failed event. - */ - @Test - public void testScanFailedEvent() throws Exception { - ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(IScanEvent.class); - verify(mWifiScannerImpl).subscribeScanEvents(messageCaptor.capture()); - IScanEvent scanEvent = messageCaptor.getValue(); - assertNotNull(scanEvent); - scanEvent.OnScanFailed(); - - verify(mNormalScanCallback).onScanFailed(); - } - - /** - * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon pno scan - * result event. - */ - @Test - public void testPnoScanResultEvent() throws Exception { - ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(IPnoScanEvent.class); - verify(mWifiScannerImpl).subscribePnoScanEvents(messageCaptor.capture()); - IPnoScanEvent pnoScanEvent = messageCaptor.getValue(); - assertNotNull(pnoScanEvent); - pnoScanEvent.OnPnoNetworkFound(); - verify(mPnoScanCallback).onScanResultReady(); - } - - /** - * Verifies that WificondControl can invoke WifiMetrics pno scan count methods upon pno event. - */ - @Test - public void testPnoScanEventsForMetrics() throws Exception { - ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(IPnoScanEvent.class); - verify(mWifiScannerImpl).subscribePnoScanEvents(messageCaptor.capture()); - IPnoScanEvent pnoScanEvent = messageCaptor.getValue(); - assertNotNull(pnoScanEvent); - - pnoScanEvent.OnPnoNetworkFound(); - verify(mPnoScanCallback).onScanResultReady(); - - pnoScanEvent.OnPnoScanFailed(); - verify(mPnoScanCallback).onScanFailed(); - } - - /** - * Verifies that startPnoScan() can invoke WifiMetrics pno scan count methods correctly. - */ - @Test - public void testStartPnoScanForMetrics() throws Exception { - when(mWifiScannerImpl.startPnoScan(any(PnoSettings.class))).thenReturn(false); - - assertFalse( - mWificondControl.startPnoScan(TEST_INTERFACE_NAME, TEST_PNO_SETTINGS, Runnable::run, - mPnoScanRequestCallback)); - verify(mPnoScanRequestCallback).onPnoRequestFailed(); - } - - /** - * Verifies that abortScan() calls underlying wificond. - */ - @Test - public void testAbortScan() throws Exception { - mWificondControl.abortScan(TEST_INTERFACE_NAME); - verify(mWifiScannerImpl).abortScan(); - } - - /** - * Ensures that the Ap interface callbacks are forwarded to the - * SoftApListener used for starting soft AP. - */ - @Test - public void testSoftApListenerInvocation() throws Exception { - testSetupInterfaceForSoftApMode(); - - WifiConfiguration config = new WifiConfiguration(); - config.SSID = new String(TEST_SSID, StandardCharsets.UTF_8); - - when(mApInterface.registerCallback(any())).thenReturn(true); - - final ArgumentCaptor apInterfaceCallbackCaptor = - ArgumentCaptor.forClass(IApInterfaceEventCallback.class); - - assertTrue(mWificondControl.registerApCallback( - TEST_INTERFACE_NAME, Runnable::run, mSoftApListener)); - verify(mApInterface).registerCallback(apInterfaceCallbackCaptor.capture()); - - final NativeWifiClient testClient = new NativeWifiClient(TEST_RAW_MAC_BYTES); - apInterfaceCallbackCaptor.getValue().onConnectedClientsChanged(testClient, true); - verify(mSoftApListener).onConnectedClientsChanged(eq(testClient), eq(true)); - - int channelFrequency = 2437; - int channelBandwidth = IApInterfaceEventCallback.BANDWIDTH_20; - apInterfaceCallbackCaptor.getValue().onSoftApChannelSwitched(channelFrequency, - channelBandwidth); - verify(mSoftApListener).onSoftApChannelSwitched(eq(channelFrequency), - eq(SoftApInfo.CHANNEL_WIDTH_20MHZ)); - } - - /** - * Verifies registration and invocation of wificond death handler. - */ - @Test - public void testRegisterDeathHandler() throws Exception { - Runnable deathHandler = mock(Runnable.class); - mWificondControl.setOnServiceDeadCallback(deathHandler); - mWificondControl.binderDied(); - mLooper.dispatchAll(); - verify(deathHandler).run(); - } - - /** - * Verifies handling of wificond death and ensures that all internal state is cleared and - * handlers are invoked. - */ - @Test - public void testDeathHandling() throws Exception { - Runnable deathHandler = mock(Runnable.class); - mWificondControl.setOnServiceDeadCallback(deathHandler); - - testSetupInterfaceForClientMode(); - - mWificondControl.binderDied(); - mLooper.dispatchAll(); - verify(deathHandler).run(); - - // The handles should be cleared after death. - assertEquals(0, mWificondControl.getChannelsMhzForBand(WifiScanner.WIFI_BAND_5_GHZ).length); - verify(mWificond, never()).getAvailable5gNonDFSChannels(); - } - - /** - * sendMgmtFrame() should fail if a null callback is passed in. - */ - @Test - public void testSendMgmtFrameNullCallback() throws Exception { - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, - Runnable::run, null); - - verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt()); - } - - /** - * sendMgmtFrame() should fail if a null frame is passed in. - */ - @Test - public void testSendMgmtFrameNullFrame() throws Exception { - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, null, TEST_MCS_RATE, Runnable::run, - mSendMgmtFrameCallback); - - verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt()); - verify(mSendMgmtFrameCallback).onFailure(anyInt()); - } - - /** - * sendMgmtFrame() should fail if an interface name that does not exist is passed in. - */ - @Test - public void testSendMgmtFrameInvalidInterfaceName() throws Exception { - mWificondControl.sendMgmtFrame(TEST_INVALID_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, - Runnable::run, mSendMgmtFrameCallback); - - verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt()); - verify(mSendMgmtFrameCallback).onFailure(anyInt()); - } - - /** - * sendMgmtFrame() should fail if it is called a second time before the first call completed. - */ - @Test - public void testSendMgmtFrameCalledTwiceBeforeFinished() throws Exception { - WifiCondManager.SendMgmtFrameCallback cb1 = mock( - WifiCondManager.SendMgmtFrameCallback.class); - WifiCondManager.SendMgmtFrameCallback cb2 = mock( - WifiCondManager.SendMgmtFrameCallback.class); - - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, - Runnable::run, cb1); - verify(cb1, never()).onFailure(anyInt()); - verify(mClientInterface, times(1)) - .SendMgmtFrame(AdditionalMatchers.aryEq(TEST_PROBE_FRAME), - any(), eq(TEST_MCS_RATE)); - - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, - Runnable::run, cb2); - verify(cb2).onFailure(WifiCondManager.SEND_MGMT_FRAME_ERROR_ALREADY_STARTED); - // verify SendMgmtFrame() still was only called once i.e. not called again - verify(mClientInterface, times(1)) - .SendMgmtFrame(any(), any(), anyInt()); - } - - /** - * Tests that when a RemoteException is triggered on AIDL call, onFailure() is called only once. - */ - @Test - public void testSendMgmtFrameThrowsException() throws Exception { - WifiCondManager.SendMgmtFrameCallback cb = mock( - WifiCondManager.SendMgmtFrameCallback.class); - - final ArgumentCaptor sendMgmtFrameEventCaptor = - ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); - - doThrow(new RemoteException()).when(mClientInterface) - .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); - - final ArgumentCaptor alarmListenerCaptor = - ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); - final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); - doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), - alarmListenerCaptor.capture(), handlerCaptor.capture()); - - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, - Runnable::run, cb); - mLooper.dispatchAll(); - - verify(cb).onFailure(anyInt()); - verify(mAlarmManager).cancel(eq(alarmListenerCaptor.getValue())); - - sendMgmtFrameEventCaptor.getValue().OnFailure( - WifiCondManager.SEND_MGMT_FRAME_ERROR_UNKNOWN); - mLooper.dispatchAll(); - - handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); - mLooper.dispatchAll(); - - verifyNoMoreInteractions(cb); - } - - /** - * Tests that the onAck() callback is triggered correctly. - */ - @Test - public void testSendMgmtFrameSuccess() throws Exception { - WifiCondManager.SendMgmtFrameCallback cb = mock( - WifiCondManager.SendMgmtFrameCallback.class); - - final ArgumentCaptor sendMgmtFrameEventCaptor = - ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); - doNothing().when(mClientInterface) - .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); - final ArgumentCaptor alarmListenerCaptor = - ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); - final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); - doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), - alarmListenerCaptor.capture(), handlerCaptor.capture()); - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, - Runnable::run, cb); - - sendMgmtFrameEventCaptor.getValue().OnAck(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS); - mLooper.dispatchAll(); - verify(cb).onAck(eq(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS)); - verify(cb, never()).onFailure(anyInt()); - verify(mAlarmManager).cancel(eq(alarmListenerCaptor.getValue())); - - // verify that even if timeout is triggered afterwards, SendMgmtFrameCallback is not - // triggered again - handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); - mLooper.dispatchAll(); - verify(cb, times(1)).onAck(anyInt()); - verify(cb, never()).onFailure(anyInt()); - } - - /** - * Tests that the onFailure() callback is triggered correctly. - */ - @Test - public void testSendMgmtFrameFailure() throws Exception { - WifiCondManager.SendMgmtFrameCallback cb = mock( - WifiCondManager.SendMgmtFrameCallback.class); - - final ArgumentCaptor sendMgmtFrameEventCaptor = - ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); - doNothing().when(mClientInterface) - .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); - final ArgumentCaptor alarmListenerCaptor = - ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); - final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); - doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), - alarmListenerCaptor.capture(), handlerCaptor.capture()); - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, - Runnable::run, cb); - - sendMgmtFrameEventCaptor.getValue().OnFailure( - WifiCondManager.SEND_MGMT_FRAME_ERROR_UNKNOWN); - mLooper.dispatchAll(); - verify(cb, never()).onAck(anyInt()); - verify(cb).onFailure(WifiCondManager.SEND_MGMT_FRAME_ERROR_UNKNOWN); - verify(mAlarmManager).cancel(eq(alarmListenerCaptor.getValue())); - - // verify that even if timeout is triggered afterwards, SendMgmtFrameCallback is not - // triggered again - handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); - mLooper.dispatchAll(); - verify(cb, never()).onAck(anyInt()); - verify(cb, times(1)).onFailure(anyInt()); - } - - /** - * Tests that the onTimeout() callback is triggered correctly. - */ - @Test - public void testSendMgmtFrameTimeout() throws Exception { - WifiCondManager.SendMgmtFrameCallback cb = mock( - WifiCondManager.SendMgmtFrameCallback.class); - - final ArgumentCaptor sendMgmtFrameEventCaptor = - ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); - doNothing().when(mClientInterface) - .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); - final ArgumentCaptor alarmListenerCaptor = - ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); - final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); - doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), - alarmListenerCaptor.capture(), handlerCaptor.capture()); - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, - Runnable::run, cb); - - handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); - mLooper.dispatchAll(); - verify(cb, never()).onAck(anyInt()); - verify(cb).onFailure(WifiCondManager.SEND_MGMT_FRAME_ERROR_TIMEOUT); - - // verify that even if onAck() callback is triggered after timeout, - // SendMgmtFrameCallback is not triggered again - sendMgmtFrameEventCaptor.getValue().OnAck(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS); - mLooper.dispatchAll(); - verify(cb, never()).onAck(anyInt()); - verify(cb, times(1)).onFailure(anyInt()); - } - - /** - * Tests every possible test outcome followed by every other test outcome to ensure that the - * internal state is reset correctly between calls. - * i.e. (success, success), (success, failure), (success, timeout), - * (failure, failure), (failure, success), (failure, timeout), - * (timeout, timeout), (timeout, success), (timeout, failure) - * - * Also tests that internal state is reset correctly after a transient AIDL RemoteException. - */ - @Test - public void testSendMgmtFrameMixed() throws Exception { - testSendMgmtFrameThrowsException(); - testSendMgmtFrameSuccess(); - testSendMgmtFrameSuccess(); - testSendMgmtFrameFailure(); - testSendMgmtFrameFailure(); - testSendMgmtFrameTimeout(); - testSendMgmtFrameTimeout(); - testSendMgmtFrameSuccess(); - testSendMgmtFrameTimeout(); - testSendMgmtFrameFailure(); - testSendMgmtFrameSuccess(); - } - - /** - * Tests that OnAck() does not perform any non-thread-safe operations on the binder thread. - * - * The sequence of instructions are: - * 1. post onAlarm() onto main thread - * 2. OnAck() - * 3. mLooper.dispatchAll() - * - * The actual order of execution is: - * 1. binder thread portion of OnAck() - * 2. onAlarm() (which purely executes on the main thread) - * 3. main thread portion of OnAck() - * - * If the binder thread portion of OnAck() is not thread-safe, it can possibly mess up - * onAlarm(). Tests that this does not occur. - */ - @Test - public void testSendMgmtFrameTimeoutAckThreadSafe() throws Exception { - final ArgumentCaptor sendMgmtFrameEventCaptor = - ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); - doNothing().when(mClientInterface) - .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); - final ArgumentCaptor alarmListenerCaptor = - ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); - final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); - doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), - alarmListenerCaptor.capture(), handlerCaptor.capture()); - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, - Runnable::run, mSendMgmtFrameCallback); - - // AlarmManager should post the onAlarm() callback onto the handler, but since we are - // triggering onAlarm() ourselves during the test, manually post onto handler - handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); - // OnAck posts to the handler - sendMgmtFrameEventCaptor.getValue().OnAck(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS); - mLooper.dispatchAll(); - verify(mSendMgmtFrameCallback, never()).onAck(anyInt()); - verify(mSendMgmtFrameCallback).onFailure(WifiCondManager.SEND_MGMT_FRAME_ERROR_TIMEOUT); - } - - /** - * See {@link #testSendMgmtFrameTimeoutAckThreadSafe()}. This test replaces OnAck() with - * OnFailure(). - */ - @Test - public void testSendMgmtFrameTimeoutFailureThreadSafe() throws Exception { - final ArgumentCaptor sendMgmtFrameEventCaptor = - ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); - doNothing().when(mClientInterface) - .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); - final ArgumentCaptor alarmListenerCaptor = - ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); - final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); - doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), - alarmListenerCaptor.capture(), handlerCaptor.capture()); - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, - Runnable::run, mSendMgmtFrameCallback); - - // AlarmManager should post the onAlarm() callback onto the handler, but since we are - // triggering onAlarm() ourselves during the test, manually post onto handler - handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); - // OnFailure posts to the handler - sendMgmtFrameEventCaptor.getValue().OnFailure( - WifiCondManager.SEND_MGMT_FRAME_ERROR_UNKNOWN); - mLooper.dispatchAll(); - verify(mSendMgmtFrameCallback).onFailure(WifiCondManager.SEND_MGMT_FRAME_ERROR_TIMEOUT); - } - - /** - * Tests getDeviceWiphyCapabililties - */ - @Test - public void testGetDeviceWiphyCapabilities() throws Exception { - DeviceWiphyCapabilities capaExpected = new DeviceWiphyCapabilities(); - - capaExpected.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, true); - capaExpected.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, true); - capaExpected.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AX, false); - capaExpected.setChannelWidthSupported(ScanResult.CHANNEL_WIDTH_160MHZ, true); - capaExpected.setChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ, false); - capaExpected.setMaxNumberTxSpatialStreams(2); - capaExpected.setMaxNumberRxSpatialStreams(1); - - when(mWificond.getDeviceWiphyCapabilities(TEST_INTERFACE_NAME)) - .thenReturn(capaExpected); - - DeviceWiphyCapabilities capaActual = - mWificondControl.getDeviceWiphyCapabilities(TEST_INTERFACE_NAME); - assertEquals(capaExpected, capaActual); - } - - // Create a ArgumentMatcher which captures a SingleScanSettings parameter and checks if it - // matches the provided frequency set and ssid set. - private class ScanMatcher implements ArgumentMatcher { - int mExpectedScanType; - private final Set mExpectedFreqs; - private final List mExpectedSsids; - - ScanMatcher(int expectedScanType, Set expectedFreqs, List expectedSsids) { - this.mExpectedScanType = expectedScanType; - this.mExpectedFreqs = expectedFreqs; - this.mExpectedSsids = expectedSsids; - } - - @Override - public boolean matches(SingleScanSettings settings) { - if (settings.scanType != mExpectedScanType) { - return false; - } - ArrayList channelSettings = settings.channelSettings; - ArrayList hiddenNetworks = settings.hiddenNetworks; - if (mExpectedFreqs != null) { - Set freqSet = new HashSet(); - for (ChannelSettings channel : channelSettings) { - freqSet.add(channel.frequency); - } - if (!mExpectedFreqs.equals(freqSet)) { - return false; - } - } else { - if (channelSettings != null && channelSettings.size() > 0) { - return false; - } - } - - if (mExpectedSsids != null) { - List ssidSet = new ArrayList<>(); - for (HiddenNetwork network : hiddenNetworks) { - ssidSet.add(network.ssid); - } - if (!mExpectedSsids.equals(ssidSet)) { - return false; - } - - } else { - if (hiddenNetworks != null && hiddenNetworks.size() > 0) { - return false; - } - } - return true; - } - - @Override - public String toString() { - return "ScanMatcher{mExpectedFreqs=" + mExpectedFreqs - + ", mExpectedSsids=" + mExpectedSsids + '}'; - } - } - - private static class LocalNativeUtil { - private static final int SSID_BYTES_MAX_LEN = 32; - - /** - * Converts an ArrayList of UTF_8 byte values to string. - * The string will either be: - * a) UTF-8 String encapsulated in quotes (if all the bytes are UTF-8 encodeable and non - * null), - * or - * b) Hex string with no delimiters. - * - * @param bytes List of bytes for ssid. - * @throws IllegalArgumentException for null bytes. - */ - public static String bytesToHexOrQuotedString(ArrayList bytes) { - if (bytes == null) { - throw new IllegalArgumentException("null ssid bytes"); - } - byte[] byteArray = byteArrayFromArrayList(bytes); - // Check for 0's in the byte stream in which case we cannot convert this into a string. - if (!bytes.contains(Byte.valueOf((byte) 0))) { - CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder(); - try { - CharBuffer decoded = decoder.decode(ByteBuffer.wrap(byteArray)); - return "\"" + decoded.toString() + "\""; - } catch (CharacterCodingException cce) { - } - } - return hexStringFromByteArray(byteArray); - } - - /** - * Converts an ssid string to an arraylist of UTF_8 byte values. - * These forms are acceptable: - * a) UTF-8 String encapsulated in quotes, or - * b) Hex string with no delimiters. - * - * @param ssidStr String to be converted. - * @throws IllegalArgumentException for null string. - */ - public static ArrayList decodeSsid(String ssidStr) { - ArrayList ssidBytes = hexOrQuotedStringToBytes(ssidStr); - if (ssidBytes.size() > SSID_BYTES_MAX_LEN) { - throw new IllegalArgumentException( - "ssid bytes size out of range: " + ssidBytes.size()); - } - return ssidBytes; - } - - /** - * Convert from an array list of Byte to an array of primitive bytes. - */ - public static byte[] byteArrayFromArrayList(ArrayList bytes) { - byte[] byteArray = new byte[bytes.size()]; - int i = 0; - for (Byte b : bytes) { - byteArray[i++] = b; - } - return byteArray; - } - - /** - * Converts a byte array to hex string. - * - * @param bytes List of bytes for ssid. - * @throws IllegalArgumentException for null bytes. - */ - public static String hexStringFromByteArray(byte[] bytes) { - if (bytes == null) { - throw new IllegalArgumentException("null hex bytes"); - } - return new String(HexEncoding.encode(bytes)).toLowerCase(); - } - - /** - * Converts an string to an arraylist of UTF_8 byte values. - * These forms are acceptable: - * a) UTF-8 String encapsulated in quotes, or - * b) Hex string with no delimiters. - * - * @param str String to be converted. - * @throws IllegalArgumentException for null string. - */ - public static ArrayList hexOrQuotedStringToBytes(String str) { - if (str == null) { - throw new IllegalArgumentException("null string"); - } - int length = str.length(); - if ((length > 1) && (str.charAt(0) == '"') && (str.charAt(length - 1) == '"')) { - str = str.substring(1, str.length() - 1); - return stringToByteArrayList(str); - } else { - return byteArrayToArrayList(hexStringToByteArray(str)); - } - } - - /** - * Convert the string to byte array list. - * - * @return the UTF_8 char byte values of str, as an ArrayList. - * @throws IllegalArgumentException if a null or unencodable string is sent. - */ - public static ArrayList stringToByteArrayList(String str) { - if (str == null) { - throw new IllegalArgumentException("null string"); - } - // Ensure that the provided string is UTF_8 encoded. - CharsetEncoder encoder = StandardCharsets.UTF_8.newEncoder(); - try { - ByteBuffer encoded = encoder.encode(CharBuffer.wrap(str)); - byte[] byteArray = new byte[encoded.remaining()]; - encoded.get(byteArray); - return byteArrayToArrayList(byteArray); - } catch (CharacterCodingException cce) { - throw new IllegalArgumentException("cannot be utf-8 encoded", cce); - } - } - - /** - * Convert from an array of primitive bytes to an array list of Byte. - */ - public static ArrayList byteArrayToArrayList(byte[] bytes) { - ArrayList byteList = new ArrayList<>(); - for (Byte b : bytes) { - byteList.add(b); - } - return byteList; - } - - /** - * Converts a hex string to byte array. - * - * @param hexStr String to be converted. - * @throws IllegalArgumentException for null string. - */ - public static byte[] hexStringToByteArray(String hexStr) { - if (hexStr == null) { - throw new IllegalArgumentException("null hex string"); - } - return HexEncoding.decode(hexStr.toCharArray(), false); - } - } -} diff --git a/wifi/tests/src/android/net/wifi/wificond/WifiNl80211ManagerTest.java b/wifi/tests/src/android/net/wifi/wificond/WifiNl80211ManagerTest.java new file mode 100644 index 000000000000..a8184068ff5a --- /dev/null +++ b/wifi/tests/src/android/net/wifi/wificond/WifiNl80211ManagerTest.java @@ -0,0 +1,1265 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.wificond; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Matchers.argThat; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyLong; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +import android.app.AlarmManager; +import android.app.test.TestAlarmManager; +import android.content.Context; +import android.net.MacAddress; +import android.net.wifi.ScanResult; +import android.net.wifi.SoftApInfo; +import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiScanner; +import android.net.wifi.util.HexEncoding; +import android.os.Handler; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.test.TestLooper; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.AdditionalMatchers; +import org.mockito.ArgumentCaptor; +import org.mockito.ArgumentMatcher; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.CharacterCodingException; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Unit tests for {@link android.net.wifi.wificond.WifiNl80211Manager}. + */ +@SmallTest +public class WifiNl80211ManagerTest { + @Mock + private IWificond mWificond; + @Mock + private IBinder mWifiCondBinder; + @Mock + private IClientInterface mClientInterface; + @Mock + private IWifiScannerImpl mWifiScannerImpl; + @Mock + private IApInterface mApInterface; + @Mock + private WifiNl80211Manager.SoftApCallback mSoftApListener; + @Mock + private WifiNl80211Manager.SendMgmtFrameCallback mSendMgmtFrameCallback; + @Mock + private WifiNl80211Manager.ScanEventCallback mNormalScanCallback; + @Mock + private WifiNl80211Manager.ScanEventCallback mPnoScanCallback; + @Mock + private WifiNl80211Manager.PnoScanRequestCallback mPnoScanRequestCallback; + @Mock + private Context mContext; + private TestLooper mLooper; + private TestAlarmManager mTestAlarmManager; + private AlarmManager mAlarmManager; + private WifiNl80211Manager mWificondControl; + private static final String TEST_INTERFACE_NAME = "test_wlan_if"; + private static final String TEST_INTERFACE_NAME1 = "test_wlan_if1"; + private static final String TEST_INVALID_INTERFACE_NAME = "asdf"; + private static final byte[] TEST_SSID = + new byte[]{'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'}; + private static final byte[] TEST_PSK = + new byte[]{'T', 'e', 's', 't'}; + + private static final Set SCAN_FREQ_SET = + new HashSet() {{ + add(2410); + add(2450); + add(5050); + add(5200); + }}; + private static final String TEST_QUOTED_SSID_1 = "\"testSsid1\""; + private static final String TEST_QUOTED_SSID_2 = "\"testSsid2\""; + private static final int[] TEST_FREQUENCIES_1 = {}; + private static final int[] TEST_FREQUENCIES_2 = {2500, 5124}; + private static final MacAddress TEST_RAW_MAC_BYTES = MacAddress.fromBytes( + new byte[]{0x00, 0x01, 0x02, 0x03, 0x04, 0x05}); + + private static final List SCAN_HIDDEN_NETWORK_SSID_LIST = + new ArrayList() {{ + add(LocalNativeUtil.byteArrayFromArrayList( + LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_1))); + add(LocalNativeUtil.byteArrayFromArrayList( + LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_2))); + }}; + + private static final PnoSettings TEST_PNO_SETTINGS = new PnoSettings(); + static { + TEST_PNO_SETTINGS.setIntervalMillis(6000); + List initPnoNetworks = new ArrayList<>(); + PnoNetwork network = new PnoNetwork(); + network.setSsid(LocalNativeUtil.byteArrayFromArrayList( + LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_1))); + network.setHidden(true); + network.setFrequenciesMhz(TEST_FREQUENCIES_1); + initPnoNetworks.add(network); + network.setSsid(LocalNativeUtil.byteArrayFromArrayList( + LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_2))); + network.setHidden(false); + network.setFrequenciesMhz(TEST_FREQUENCIES_2); + initPnoNetworks.add(network); + TEST_PNO_SETTINGS.setPnoNetworks(initPnoNetworks); + } + + private static final int TEST_MCS_RATE = 5; + private static final int TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS = 100; + private static final byte[] TEST_PROBE_FRAME = { + 0x40, 0x00, 0x3c, 0x00, (byte) 0xa8, (byte) 0xbd, 0x27, 0x5b, + 0x33, 0x72, (byte) 0xf4, (byte) 0xf5, (byte) 0xe8, 0x51, (byte) 0x9e, 0x09, + (byte) 0xa8, (byte) 0xbd, 0x27, 0x5b, 0x33, 0x72, (byte) 0xb0, 0x66, + 0x00, 0x00 + }; + + @Before + public void setUp() throws Exception { + // Setup mocks for successful WificondControl operation. Failure case mocks should be + // created in specific tests + MockitoAnnotations.initMocks(this); + + mTestAlarmManager = new TestAlarmManager(); + mAlarmManager = mTestAlarmManager.getAlarmManager(); + when(mContext.getSystemServiceName(AlarmManager.class)).thenReturn(Context.ALARM_SERVICE); + when(mContext.getSystemService(AlarmManager.class)).thenReturn(mAlarmManager); + + mLooper = new TestLooper(); + when(mContext.getMainLooper()).thenReturn(mLooper.getLooper()); + + when(mWificond.asBinder()).thenReturn(mWifiCondBinder); + when(mClientInterface.getWifiScannerImpl()).thenReturn(mWifiScannerImpl); + when(mWificond.createClientInterface(any())).thenReturn(mClientInterface); + when(mWificond.createApInterface(any())).thenReturn(mApInterface); + when(mWificond.tearDownClientInterface(any())).thenReturn(true); + when(mWificond.tearDownApInterface(any())).thenReturn(true); + when(mClientInterface.getWifiScannerImpl()).thenReturn(mWifiScannerImpl); + when(mClientInterface.getInterfaceName()).thenReturn(TEST_INTERFACE_NAME); + mWificondControl = new WifiNl80211Manager(mContext, mWificond); + assertEquals(true, + mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, Runnable::run, + mNormalScanCallback, mPnoScanCallback)); + } + + /** + * Verifies that setupInterfaceForClientMode(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testSetupInterfaceForClientMode() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + verify(mWificond).createClientInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that setupInterfaceForClientMode(TEST_INTERFACE_NAME) calls subscribeScanEvents(). + */ + @Test + public void testSetupInterfaceForClientModeCallsScanEventSubscripiton() throws Exception { + verify(mWifiScannerImpl).subscribeScanEvents(any(IScanEvent.class)); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownClientInterface() throws Exception { + when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(true); + + assertTrue(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); + verify(mWifiScannerImpl).unsubscribeScanEvents(); + verify(mWifiScannerImpl).unsubscribePnoScanEvents(); + verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownClientInterfaceOnInvalidIface() throws Exception { + when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME1)).thenReturn(true); + + assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME1)); + verify(mWifiScannerImpl, never()).unsubscribeScanEvents(); + verify(mWifiScannerImpl, never()).unsubscribePnoScanEvents(); + verify(mWificond, never()).tearDownClientInterface(any()); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownClientInterfaceFailDueToExceptionScannerUnsubscribe() throws Exception { + when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(true); + doThrow(new RemoteException()).when(mWifiScannerImpl).unsubscribeScanEvents(); + + assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); + verify(mWifiScannerImpl).unsubscribeScanEvents(); + verify(mWifiScannerImpl, never()).unsubscribePnoScanEvents(); + verify(mWificond, never()).tearDownClientInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownClientInterfaceErrorWhenWificondFailed() throws Exception { + when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(false); + + assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); + verify(mWifiScannerImpl).unsubscribeScanEvents(); + verify(mWifiScannerImpl).unsubscribePnoScanEvents(); + verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that the client handles are cleared after teardown. + */ + @Test + public void testTeardownClientInterfaceClearsHandles() throws Exception { + testTeardownClientInterface(); + + assertNull(mWificondControl.signalPoll(TEST_INTERFACE_NAME)); + verify(mClientInterface, never()).signalPoll(); + + assertFalse(mWificondControl.startScan( + TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_LATENCY, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); + verify(mWifiScannerImpl, never()).scan(any()); + } + + /** + * Verifies that setupInterfaceForSoftApMode(TEST_INTERFACE_NAME) calls wificond. + */ + @Test + public void testSetupInterfaceForSoftApMode() throws Exception { + when(mWificond.createApInterface(TEST_INTERFACE_NAME)).thenReturn(mApInterface); + + assertEquals(true, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME)); + verify(mWificond).createApInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that setupInterfaceForSoftAp() returns null when wificond is not started. + */ + @Test + public void testSetupInterfaceForSoftApModeErrorWhenWificondIsNotStarted() throws Exception { + // Invoke wificond death handler to clear the handle. + mWificondControl.binderDied(); + mLooper.dispatchAll(); + + assertEquals(false, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME)); + } + + /** + * Verifies that setupInterfaceForSoftApMode(TEST_INTERFACE_NAME) returns null when wificond + * failed to setup AP interface. + */ + @Test + public void testSetupInterfaceForSoftApModeErrorWhenWificondFailedToSetupInterface() + throws Exception { + when(mWificond.createApInterface(TEST_INTERFACE_NAME)).thenReturn(null); + + assertEquals(false, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME)); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownSoftApInterface() throws Exception { + testSetupInterfaceForSoftApMode(); + when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME)).thenReturn(true); + + assertTrue(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME)); + verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that tearDownSoftapInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownSoftApInterfaceOnInvalidIface() throws Exception { + testSetupInterfaceForSoftApMode(); + when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME1)).thenReturn(true); + + assertFalse(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME1)); + verify(mWificond, never()).tearDownApInterface(any()); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownSoftApInterfaceErrorWhenWificondFailed() throws Exception { + testSetupInterfaceForSoftApMode(); + when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME)).thenReturn(false); + + assertFalse(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME)); + verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that the SoftAp handles are cleared after teardown. + */ + @Test + public void testTeardownSoftApInterfaceClearsHandles() throws Exception { + testTeardownSoftApInterface(); + + assertFalse(mWificondControl.registerApCallback( + TEST_INTERFACE_NAME, Runnable::run, mSoftApListener)); + verify(mApInterface, never()).registerCallback(any()); + } + + /** + * Verifies that we can setup concurrent interfaces. + */ + @Test + public void testSetupMultipleInterfaces() throws Exception { + when(mWificond.createApInterface(TEST_INTERFACE_NAME1)).thenReturn(mApInterface); + + assertEquals(true, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME1)); + + verify(mWificond).createClientInterface(TEST_INTERFACE_NAME); + verify(mWificond).createApInterface(TEST_INTERFACE_NAME1); + } + + /** + * Verifies that we can setup concurrent interfaces. + */ + @Test + public void testTeardownMultipleInterfaces() throws Exception { + testSetupMultipleInterfaces(); + assertTrue(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); + assertTrue(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME1)); + + verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME); + verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME1); + } + + /** + * Verifies that tearDownInterfaces() calls wificond. + */ + @Test + public void testTearDownInterfaces() throws Exception { + assertTrue(mWificondControl.tearDownInterfaces()); + verify(mWificond).tearDownInterfaces(); + } + + /** + * Verifies that tearDownInterfaces() calls unsubscribeScanEvents() when there was + * a configured client interface. + */ + @Test + public void testTearDownInterfacesRemovesScanEventSubscription() throws Exception { + assertTrue(mWificondControl.tearDownInterfaces()); + verify(mWifiScannerImpl).unsubscribeScanEvents(); + } + + /** + * Verifies that tearDownInterfaces() returns false when wificond is not started. + */ + @Test + public void testTearDownInterfacesErrorWhenWificondIsNotStarterd() throws Exception { + // Invoke wificond death handler to clear the handle. + mWificondControl.binderDied(); + mLooper.dispatchAll(); + assertFalse(mWificondControl.tearDownInterfaces()); + } + + /** + * Verifies that signalPoll() calls wificond. + */ + @Test + public void testSignalPoll() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + + mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, Runnable::run, + mNormalScanCallback, mPnoScanCallback); + mWificondControl.signalPoll(TEST_INTERFACE_NAME); + verify(mClientInterface).signalPoll(); + } + + /** + * Verifies that signalPoll() returns null when there is no configured client interface. + */ + @Test + public void testSignalPollErrorWhenNoClientInterfaceConfigured() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + + // Configure client interface. + assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, + Runnable::run, mNormalScanCallback, mPnoScanCallback)); + + // Tear down interfaces. + assertTrue(mWificondControl.tearDownInterfaces()); + + // Signal poll should fail. + assertEquals(null, mWificondControl.signalPoll(TEST_INTERFACE_NAME)); + } + + /** + * Verifies that getTxPacketCounters() calls wificond. + */ + @Test + public void testGetTxPacketCounters() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + + mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, Runnable::run, + mNormalScanCallback, mPnoScanCallback); + mWificondControl.getTxPacketCounters(TEST_INTERFACE_NAME); + verify(mClientInterface).getPacketCounters(); + } + + /** + * Verifies that getTxPacketCounters() returns null when there is no configured client + * interface. + */ + @Test + public void testGetTxPacketCountersErrorWhenNoClientInterfaceConfigured() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + + // Configure client interface. + assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, + Runnable::run, mNormalScanCallback, mPnoScanCallback)); + + // Tear down interfaces. + assertTrue(mWificondControl.tearDownInterfaces()); + + // Signal poll should fail. + assertEquals(null, mWificondControl.getTxPacketCounters(TEST_INTERFACE_NAME)); + } + + /** + * Verifies that getScanResults() returns null when there is no configured client + * interface. + */ + @Test + public void testGetScanResultsErrorWhenNoClientInterfaceConfigured() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + + // Configure client interface. + assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, + Runnable::run, mNormalScanCallback, mPnoScanCallback)); + + // Tear down interfaces. + assertTrue(mWificondControl.tearDownInterfaces()); + + // getScanResults should fail. + assertEquals(0, + mWificondControl.getScanResults(TEST_INTERFACE_NAME, + WifiNl80211Manager.SCAN_TYPE_SINGLE_SCAN).size()); + } + + /** + * Verifies that Scan() can convert input parameters to SingleScanSettings correctly. + */ + @Test + public void testScan() throws Exception { + when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true); + assertTrue(mWificondControl.startScan( + TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_POWER, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); + verify(mWifiScannerImpl).scan(argThat(new ScanMatcher( + IWifiScannerImpl.SCAN_TYPE_LOW_POWER, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST))); + } + + /** + * Verifies that Scan() removes duplicates hiddenSsids passed in from input. + */ + @Test + public void testScanWithDuplicateHiddenSsids() throws Exception { + when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true); + // Create a list of hiddenSsid that has a duplicate element + List hiddenSsidWithDup = new ArrayList<>(SCAN_HIDDEN_NETWORK_SSID_LIST); + hiddenSsidWithDup.add(SCAN_HIDDEN_NETWORK_SSID_LIST.get(0)); + assertEquals(hiddenSsidWithDup.get(0), + hiddenSsidWithDup.get(hiddenSsidWithDup.size() - 1)); + // Pass the List with duplicate elements into scan() + assertTrue(mWificondControl.startScan( + TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_POWER, + SCAN_FREQ_SET, hiddenSsidWithDup)); + // But the argument passed down should have the duplicate removed. + verify(mWifiScannerImpl).scan(argThat(new ScanMatcher( + IWifiScannerImpl.SCAN_TYPE_LOW_POWER, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST))); + } + + /** + * Verifies that Scan() can handle null input parameters correctly. + */ + @Test + public void testScanNullParameters() throws Exception { + when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true); + assertTrue(mWificondControl.startScan( + TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_HIGH_ACCURACY, null, null)); + verify(mWifiScannerImpl).scan(argThat(new ScanMatcher( + IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY, null, null))); + } + + /** + * Verifies that Scan() can handle wificond scan failure. + */ + @Test + public void testScanFailure() throws Exception { + when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(false); + assertFalse(mWificondControl.startScan( + TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_LATENCY, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); + verify(mWifiScannerImpl).scan(any(SingleScanSettings.class)); + } + + /** + * Verifies that Scan() can handle invalid type. + */ + @Test + public void testScanFailureDueToInvalidType() throws Exception { + assertFalse(mWificondControl.startScan( + TEST_INTERFACE_NAME, 100, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); + verify(mWifiScannerImpl, never()).scan(any(SingleScanSettings.class)); + } + + /** + * Verifies that startPnoScan() can convert input parameters to PnoSettings correctly. + */ + @Test + public void testStartPnoScan() throws Exception { + when(mWifiScannerImpl.startPnoScan(any(PnoSettings.class))).thenReturn(true); + assertTrue( + mWificondControl.startPnoScan(TEST_INTERFACE_NAME, TEST_PNO_SETTINGS, Runnable::run, + mPnoScanRequestCallback)); + verify(mWifiScannerImpl).startPnoScan(eq(TEST_PNO_SETTINGS)); + verify(mPnoScanRequestCallback).onPnoRequestSucceeded(); + } + + /** + * Verifies that stopPnoScan() calls underlying wificond. + */ + @Test + public void testStopPnoScan() throws Exception { + when(mWifiScannerImpl.stopPnoScan()).thenReturn(true); + assertTrue(mWificondControl.stopPnoScan(TEST_INTERFACE_NAME)); + verify(mWifiScannerImpl).stopPnoScan(); + } + + /** + * Verifies that stopPnoScan() can handle wificond failure. + */ + @Test + public void testStopPnoScanFailure() throws Exception { + + when(mWifiScannerImpl.stopPnoScan()).thenReturn(false); + assertFalse(mWificondControl.stopPnoScan(TEST_INTERFACE_NAME)); + verify(mWifiScannerImpl).stopPnoScan(); + } + + /** + * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon scan + * result event. + */ + @Test + public void testScanResultEvent() throws Exception { + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(IScanEvent.class); + verify(mWifiScannerImpl).subscribeScanEvents(messageCaptor.capture()); + IScanEvent scanEvent = messageCaptor.getValue(); + assertNotNull(scanEvent); + scanEvent.OnScanResultReady(); + + verify(mNormalScanCallback).onScanResultReady(); + } + + /** + * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon scan + * failed event. + */ + @Test + public void testScanFailedEvent() throws Exception { + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(IScanEvent.class); + verify(mWifiScannerImpl).subscribeScanEvents(messageCaptor.capture()); + IScanEvent scanEvent = messageCaptor.getValue(); + assertNotNull(scanEvent); + scanEvent.OnScanFailed(); + + verify(mNormalScanCallback).onScanFailed(); + } + + /** + * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon pno scan + * result event. + */ + @Test + public void testPnoScanResultEvent() throws Exception { + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(IPnoScanEvent.class); + verify(mWifiScannerImpl).subscribePnoScanEvents(messageCaptor.capture()); + IPnoScanEvent pnoScanEvent = messageCaptor.getValue(); + assertNotNull(pnoScanEvent); + pnoScanEvent.OnPnoNetworkFound(); + verify(mPnoScanCallback).onScanResultReady(); + } + + /** + * Verifies that WificondControl can invoke WifiMetrics pno scan count methods upon pno event. + */ + @Test + public void testPnoScanEventsForMetrics() throws Exception { + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(IPnoScanEvent.class); + verify(mWifiScannerImpl).subscribePnoScanEvents(messageCaptor.capture()); + IPnoScanEvent pnoScanEvent = messageCaptor.getValue(); + assertNotNull(pnoScanEvent); + + pnoScanEvent.OnPnoNetworkFound(); + verify(mPnoScanCallback).onScanResultReady(); + + pnoScanEvent.OnPnoScanFailed(); + verify(mPnoScanCallback).onScanFailed(); + } + + /** + * Verifies that startPnoScan() can invoke WifiMetrics pno scan count methods correctly. + */ + @Test + public void testStartPnoScanForMetrics() throws Exception { + when(mWifiScannerImpl.startPnoScan(any(PnoSettings.class))).thenReturn(false); + + assertFalse( + mWificondControl.startPnoScan(TEST_INTERFACE_NAME, TEST_PNO_SETTINGS, Runnable::run, + mPnoScanRequestCallback)); + verify(mPnoScanRequestCallback).onPnoRequestFailed(); + } + + /** + * Verifies that abortScan() calls underlying wificond. + */ + @Test + public void testAbortScan() throws Exception { + mWificondControl.abortScan(TEST_INTERFACE_NAME); + verify(mWifiScannerImpl).abortScan(); + } + + /** + * Ensures that the Ap interface callbacks are forwarded to the + * SoftApListener used for starting soft AP. + */ + @Test + public void testSoftApListenerInvocation() throws Exception { + testSetupInterfaceForSoftApMode(); + + WifiConfiguration config = new WifiConfiguration(); + config.SSID = new String(TEST_SSID, StandardCharsets.UTF_8); + + when(mApInterface.registerCallback(any())).thenReturn(true); + + final ArgumentCaptor apInterfaceCallbackCaptor = + ArgumentCaptor.forClass(IApInterfaceEventCallback.class); + + assertTrue(mWificondControl.registerApCallback( + TEST_INTERFACE_NAME, Runnable::run, mSoftApListener)); + verify(mApInterface).registerCallback(apInterfaceCallbackCaptor.capture()); + + final NativeWifiClient testClient = new NativeWifiClient(TEST_RAW_MAC_BYTES); + apInterfaceCallbackCaptor.getValue().onConnectedClientsChanged(testClient, true); + verify(mSoftApListener).onConnectedClientsChanged(eq(testClient), eq(true)); + + int channelFrequency = 2437; + int channelBandwidth = IApInterfaceEventCallback.BANDWIDTH_20; + apInterfaceCallbackCaptor.getValue().onSoftApChannelSwitched(channelFrequency, + channelBandwidth); + verify(mSoftApListener).onSoftApChannelSwitched(eq(channelFrequency), + eq(SoftApInfo.CHANNEL_WIDTH_20MHZ)); + } + + /** + * Verifies registration and invocation of wificond death handler. + */ + @Test + public void testRegisterDeathHandler() throws Exception { + Runnable deathHandler = mock(Runnable.class); + mWificondControl.setOnServiceDeadCallback(deathHandler); + mWificondControl.binderDied(); + mLooper.dispatchAll(); + verify(deathHandler).run(); + } + + /** + * Verifies handling of wificond death and ensures that all internal state is cleared and + * handlers are invoked. + */ + @Test + public void testDeathHandling() throws Exception { + Runnable deathHandler = mock(Runnable.class); + mWificondControl.setOnServiceDeadCallback(deathHandler); + + testSetupInterfaceForClientMode(); + + mWificondControl.binderDied(); + mLooper.dispatchAll(); + verify(deathHandler).run(); + + // The handles should be cleared after death. + assertEquals(0, mWificondControl.getChannelsMhzForBand(WifiScanner.WIFI_BAND_5_GHZ).length); + verify(mWificond, never()).getAvailable5gNonDFSChannels(); + } + + /** + * sendMgmtFrame() should fail if a null callback is passed in. + */ + @Test + public void testSendMgmtFrameNullCallback() throws Exception { + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, null); + + verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt()); + } + + /** + * sendMgmtFrame() should fail if a null frame is passed in. + */ + @Test + public void testSendMgmtFrameNullFrame() throws Exception { + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, null, TEST_MCS_RATE, Runnable::run, + mSendMgmtFrameCallback); + + verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt()); + verify(mSendMgmtFrameCallback).onFailure(anyInt()); + } + + /** + * sendMgmtFrame() should fail if an interface name that does not exist is passed in. + */ + @Test + public void testSendMgmtFrameInvalidInterfaceName() throws Exception { + mWificondControl.sendMgmtFrame(TEST_INVALID_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, mSendMgmtFrameCallback); + + verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt()); + verify(mSendMgmtFrameCallback).onFailure(anyInt()); + } + + /** + * sendMgmtFrame() should fail if it is called a second time before the first call completed. + */ + @Test + public void testSendMgmtFrameCalledTwiceBeforeFinished() throws Exception { + WifiNl80211Manager.SendMgmtFrameCallback cb1 = mock( + WifiNl80211Manager.SendMgmtFrameCallback.class); + WifiNl80211Manager.SendMgmtFrameCallback cb2 = mock( + WifiNl80211Manager.SendMgmtFrameCallback.class); + + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, cb1); + verify(cb1, never()).onFailure(anyInt()); + verify(mClientInterface, times(1)) + .SendMgmtFrame(AdditionalMatchers.aryEq(TEST_PROBE_FRAME), + any(), eq(TEST_MCS_RATE)); + + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, cb2); + verify(cb2).onFailure(WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_ALREADY_STARTED); + // verify SendMgmtFrame() still was only called once i.e. not called again + verify(mClientInterface, times(1)) + .SendMgmtFrame(any(), any(), anyInt()); + } + + /** + * Tests that when a RemoteException is triggered on AIDL call, onFailure() is called only once. + */ + @Test + public void testSendMgmtFrameThrowsException() throws Exception { + WifiNl80211Manager.SendMgmtFrameCallback cb = mock( + WifiNl80211Manager.SendMgmtFrameCallback.class); + + final ArgumentCaptor sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + + doThrow(new RemoteException()).when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + + final ArgumentCaptor alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, cb); + mLooper.dispatchAll(); + + verify(cb).onFailure(anyInt()); + verify(mAlarmManager).cancel(eq(alarmListenerCaptor.getValue())); + + sendMgmtFrameEventCaptor.getValue().OnFailure( + WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_UNKNOWN); + mLooper.dispatchAll(); + + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + mLooper.dispatchAll(); + + verifyNoMoreInteractions(cb); + } + + /** + * Tests that the onAck() callback is triggered correctly. + */ + @Test + public void testSendMgmtFrameSuccess() throws Exception { + WifiNl80211Manager.SendMgmtFrameCallback cb = mock( + WifiNl80211Manager.SendMgmtFrameCallback.class); + + final ArgumentCaptor sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + doNothing().when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + final ArgumentCaptor alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, cb); + + sendMgmtFrameEventCaptor.getValue().OnAck(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS); + mLooper.dispatchAll(); + verify(cb).onAck(eq(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS)); + verify(cb, never()).onFailure(anyInt()); + verify(mAlarmManager).cancel(eq(alarmListenerCaptor.getValue())); + + // verify that even if timeout is triggered afterwards, SendMgmtFrameCallback is not + // triggered again + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + mLooper.dispatchAll(); + verify(cb, times(1)).onAck(anyInt()); + verify(cb, never()).onFailure(anyInt()); + } + + /** + * Tests that the onFailure() callback is triggered correctly. + */ + @Test + public void testSendMgmtFrameFailure() throws Exception { + WifiNl80211Manager.SendMgmtFrameCallback cb = mock( + WifiNl80211Manager.SendMgmtFrameCallback.class); + + final ArgumentCaptor sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + doNothing().when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + final ArgumentCaptor alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, cb); + + sendMgmtFrameEventCaptor.getValue().OnFailure( + WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_UNKNOWN); + mLooper.dispatchAll(); + verify(cb, never()).onAck(anyInt()); + verify(cb).onFailure(WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_UNKNOWN); + verify(mAlarmManager).cancel(eq(alarmListenerCaptor.getValue())); + + // verify that even if timeout is triggered afterwards, SendMgmtFrameCallback is not + // triggered again + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + mLooper.dispatchAll(); + verify(cb, never()).onAck(anyInt()); + verify(cb, times(1)).onFailure(anyInt()); + } + + /** + * Tests that the onTimeout() callback is triggered correctly. + */ + @Test + public void testSendMgmtFrameTimeout() throws Exception { + WifiNl80211Manager.SendMgmtFrameCallback cb = mock( + WifiNl80211Manager.SendMgmtFrameCallback.class); + + final ArgumentCaptor sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + doNothing().when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + final ArgumentCaptor alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, cb); + + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + mLooper.dispatchAll(); + verify(cb, never()).onAck(anyInt()); + verify(cb).onFailure(WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_TIMEOUT); + + // verify that even if onAck() callback is triggered after timeout, + // SendMgmtFrameCallback is not triggered again + sendMgmtFrameEventCaptor.getValue().OnAck(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS); + mLooper.dispatchAll(); + verify(cb, never()).onAck(anyInt()); + verify(cb, times(1)).onFailure(anyInt()); + } + + /** + * Tests every possible test outcome followed by every other test outcome to ensure that the + * internal state is reset correctly between calls. + * i.e. (success, success), (success, failure), (success, timeout), + * (failure, failure), (failure, success), (failure, timeout), + * (timeout, timeout), (timeout, success), (timeout, failure) + * + * Also tests that internal state is reset correctly after a transient AIDL RemoteException. + */ + @Test + public void testSendMgmtFrameMixed() throws Exception { + testSendMgmtFrameThrowsException(); + testSendMgmtFrameSuccess(); + testSendMgmtFrameSuccess(); + testSendMgmtFrameFailure(); + testSendMgmtFrameFailure(); + testSendMgmtFrameTimeout(); + testSendMgmtFrameTimeout(); + testSendMgmtFrameSuccess(); + testSendMgmtFrameTimeout(); + testSendMgmtFrameFailure(); + testSendMgmtFrameSuccess(); + } + + /** + * Tests that OnAck() does not perform any non-thread-safe operations on the binder thread. + * + * The sequence of instructions are: + * 1. post onAlarm() onto main thread + * 2. OnAck() + * 3. mLooper.dispatchAll() + * + * The actual order of execution is: + * 1. binder thread portion of OnAck() + * 2. onAlarm() (which purely executes on the main thread) + * 3. main thread portion of OnAck() + * + * If the binder thread portion of OnAck() is not thread-safe, it can possibly mess up + * onAlarm(). Tests that this does not occur. + */ + @Test + public void testSendMgmtFrameTimeoutAckThreadSafe() throws Exception { + final ArgumentCaptor sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + doNothing().when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + final ArgumentCaptor alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, mSendMgmtFrameCallback); + + // AlarmManager should post the onAlarm() callback onto the handler, but since we are + // triggering onAlarm() ourselves during the test, manually post onto handler + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + // OnAck posts to the handler + sendMgmtFrameEventCaptor.getValue().OnAck(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS); + mLooper.dispatchAll(); + verify(mSendMgmtFrameCallback, never()).onAck(anyInt()); + verify(mSendMgmtFrameCallback).onFailure( + WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_TIMEOUT); + } + + /** + * See {@link #testSendMgmtFrameTimeoutAckThreadSafe()}. This test replaces OnAck() with + * OnFailure(). + */ + @Test + public void testSendMgmtFrameTimeoutFailureThreadSafe() throws Exception { + final ArgumentCaptor sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + doNothing().when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + final ArgumentCaptor alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, mSendMgmtFrameCallback); + + // AlarmManager should post the onAlarm() callback onto the handler, but since we are + // triggering onAlarm() ourselves during the test, manually post onto handler + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + // OnFailure posts to the handler + sendMgmtFrameEventCaptor.getValue().OnFailure( + WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_UNKNOWN); + mLooper.dispatchAll(); + verify(mSendMgmtFrameCallback).onFailure( + WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_TIMEOUT); + } + + /** + * Tests getDeviceWiphyCapabililties + */ + @Test + public void testGetDeviceWiphyCapabilities() throws Exception { + DeviceWiphyCapabilities capaExpected = new DeviceWiphyCapabilities(); + + capaExpected.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, true); + capaExpected.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, true); + capaExpected.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AX, false); + capaExpected.setChannelWidthSupported(ScanResult.CHANNEL_WIDTH_160MHZ, true); + capaExpected.setChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ, false); + capaExpected.setMaxNumberTxSpatialStreams(2); + capaExpected.setMaxNumberRxSpatialStreams(1); + + when(mWificond.getDeviceWiphyCapabilities(TEST_INTERFACE_NAME)) + .thenReturn(capaExpected); + + DeviceWiphyCapabilities capaActual = + mWificondControl.getDeviceWiphyCapabilities(TEST_INTERFACE_NAME); + assertEquals(capaExpected, capaActual); + } + + // Create a ArgumentMatcher which captures a SingleScanSettings parameter and checks if it + // matches the provided frequency set and ssid set. + private class ScanMatcher implements ArgumentMatcher { + int mExpectedScanType; + private final Set mExpectedFreqs; + private final List mExpectedSsids; + + ScanMatcher(int expectedScanType, Set expectedFreqs, List expectedSsids) { + this.mExpectedScanType = expectedScanType; + this.mExpectedFreqs = expectedFreqs; + this.mExpectedSsids = expectedSsids; + } + + @Override + public boolean matches(SingleScanSettings settings) { + if (settings.scanType != mExpectedScanType) { + return false; + } + ArrayList channelSettings = settings.channelSettings; + ArrayList hiddenNetworks = settings.hiddenNetworks; + if (mExpectedFreqs != null) { + Set freqSet = new HashSet(); + for (ChannelSettings channel : channelSettings) { + freqSet.add(channel.frequency); + } + if (!mExpectedFreqs.equals(freqSet)) { + return false; + } + } else { + if (channelSettings != null && channelSettings.size() > 0) { + return false; + } + } + + if (mExpectedSsids != null) { + List ssidSet = new ArrayList<>(); + for (HiddenNetwork network : hiddenNetworks) { + ssidSet.add(network.ssid); + } + if (!mExpectedSsids.equals(ssidSet)) { + return false; + } + + } else { + if (hiddenNetworks != null && hiddenNetworks.size() > 0) { + return false; + } + } + return true; + } + + @Override + public String toString() { + return "ScanMatcher{mExpectedFreqs=" + mExpectedFreqs + + ", mExpectedSsids=" + mExpectedSsids + '}'; + } + } + + private static class LocalNativeUtil { + private static final int SSID_BYTES_MAX_LEN = 32; + + /** + * Converts an ArrayList of UTF_8 byte values to string. + * The string will either be: + * a) UTF-8 String encapsulated in quotes (if all the bytes are UTF-8 encodeable and non + * null), + * or + * b) Hex string with no delimiters. + * + * @param bytes List of bytes for ssid. + * @throws IllegalArgumentException for null bytes. + */ + public static String bytesToHexOrQuotedString(ArrayList bytes) { + if (bytes == null) { + throw new IllegalArgumentException("null ssid bytes"); + } + byte[] byteArray = byteArrayFromArrayList(bytes); + // Check for 0's in the byte stream in which case we cannot convert this into a string. + if (!bytes.contains(Byte.valueOf((byte) 0))) { + CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder(); + try { + CharBuffer decoded = decoder.decode(ByteBuffer.wrap(byteArray)); + return "\"" + decoded.toString() + "\""; + } catch (CharacterCodingException cce) { + } + } + return hexStringFromByteArray(byteArray); + } + + /** + * Converts an ssid string to an arraylist of UTF_8 byte values. + * These forms are acceptable: + * a) UTF-8 String encapsulated in quotes, or + * b) Hex string with no delimiters. + * + * @param ssidStr String to be converted. + * @throws IllegalArgumentException for null string. + */ + public static ArrayList decodeSsid(String ssidStr) { + ArrayList ssidBytes = hexOrQuotedStringToBytes(ssidStr); + if (ssidBytes.size() > SSID_BYTES_MAX_LEN) { + throw new IllegalArgumentException( + "ssid bytes size out of range: " + ssidBytes.size()); + } + return ssidBytes; + } + + /** + * Convert from an array list of Byte to an array of primitive bytes. + */ + public static byte[] byteArrayFromArrayList(ArrayList bytes) { + byte[] byteArray = new byte[bytes.size()]; + int i = 0; + for (Byte b : bytes) { + byteArray[i++] = b; + } + return byteArray; + } + + /** + * Converts a byte array to hex string. + * + * @param bytes List of bytes for ssid. + * @throws IllegalArgumentException for null bytes. + */ + public static String hexStringFromByteArray(byte[] bytes) { + if (bytes == null) { + throw new IllegalArgumentException("null hex bytes"); + } + return new String(HexEncoding.encode(bytes)).toLowerCase(); + } + + /** + * Converts an string to an arraylist of UTF_8 byte values. + * These forms are acceptable: + * a) UTF-8 String encapsulated in quotes, or + * b) Hex string with no delimiters. + * + * @param str String to be converted. + * @throws IllegalArgumentException for null string. + */ + public static ArrayList hexOrQuotedStringToBytes(String str) { + if (str == null) { + throw new IllegalArgumentException("null string"); + } + int length = str.length(); + if ((length > 1) && (str.charAt(0) == '"') && (str.charAt(length - 1) == '"')) { + str = str.substring(1, str.length() - 1); + return stringToByteArrayList(str); + } else { + return byteArrayToArrayList(hexStringToByteArray(str)); + } + } + + /** + * Convert the string to byte array list. + * + * @return the UTF_8 char byte values of str, as an ArrayList. + * @throws IllegalArgumentException if a null or unencodable string is sent. + */ + public static ArrayList stringToByteArrayList(String str) { + if (str == null) { + throw new IllegalArgumentException("null string"); + } + // Ensure that the provided string is UTF_8 encoded. + CharsetEncoder encoder = StandardCharsets.UTF_8.newEncoder(); + try { + ByteBuffer encoded = encoder.encode(CharBuffer.wrap(str)); + byte[] byteArray = new byte[encoded.remaining()]; + encoded.get(byteArray); + return byteArrayToArrayList(byteArray); + } catch (CharacterCodingException cce) { + throw new IllegalArgumentException("cannot be utf-8 encoded", cce); + } + } + + /** + * Convert from an array of primitive bytes to an array list of Byte. + */ + public static ArrayList byteArrayToArrayList(byte[] bytes) { + ArrayList byteList = new ArrayList<>(); + for (Byte b : bytes) { + byteList.add(b); + } + return byteList; + } + + /** + * Converts a hex string to byte array. + * + * @param hexStr String to be converted. + * @throws IllegalArgumentException for null string. + */ + public static byte[] hexStringToByteArray(String hexStr) { + if (hexStr == null) { + throw new IllegalArgumentException("null hex string"); + } + return HexEncoding.decode(hexStr.toCharArray(), false); + } + } +} -- cgit v1.2.3 From 697e02a3b80c8f3eb897ba5918e3071ef55262a5 Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Tue, 11 Feb 2020 14:29:05 -0800 Subject: [Passpoint] Fix connected network not showing in Wi-Fi picker Newly added network by OSU does not appear in Wi-Fi picker even when connected. Root cause: newly added unique identifier included the certs and key material in the hash, but after the profile is installed, the certs and keys are moved to keystore and removed from the configuration, hence the change in hash. Bug: 149322822 Test: Manual OSU connection and provisioning successfully, verifying connected network appears in Wi-Fi picker Test: atest PasspointConfigurationTest Change-Id: Idec09bc77cb3562bb6bfe9e586a3aa7b2dce85bd --- .../net/wifi/hotspot2/PasspointConfiguration.java | 4 ++-- .../android/net/wifi/hotspot2/pps/Credential.java | 22 ++++++++++++++++++++++ .../java/android/net/wifi/hotspot2/pps/HomeSp.java | 14 ++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java index 9f581849efca..7d56585b6b71 100644 --- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java +++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java @@ -909,8 +909,8 @@ public final class PasspointConfiguration implements Parcelable { } StringBuilder sb = new StringBuilder(); - sb.append(String.format("%s_%x%x", mHomeSp.getFqdn(), mHomeSp.hashCode(), - mCredential.hashCode())); + sb.append(String.format("%s_%x%x", mHomeSp.getFqdn(), mHomeSp.getUniqueId(), + mCredential.getUniqueId())); return sb.toString(); } } diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java index b037703ca056..99901808ec3e 100644 --- a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java +++ b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java @@ -1020,6 +1020,28 @@ public final class Credential implements Parcelable { Arrays.hashCode(mClientCertificateChain)); } + /** + * Get a unique identifier for Credential. This identifier depends only on items that remain + * constant throughout the lifetime of a subscription's credentials. + * + * @hide + * @return a Unique identifier for a Credential object + */ + public int getUniqueId() { + int usedCredential; + + // Initialize usedCredential based on the credential type of the profile + if (mUserCredential != null) { + usedCredential = 0; + } else if (mCertCredential != null) { + usedCredential = 1; + } else { + usedCredential = 2; + } + + return Objects.hash(usedCredential, mRealm); + } + @Override public String toString() { StringBuilder builder = new StringBuilder(); diff --git a/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java b/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java index a5de3318f454..224c4bed9d5b 100644 --- a/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java +++ b/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java @@ -305,6 +305,20 @@ public final class HomeSp implements Parcelable { Arrays.hashCode(mRoamingConsortiumOis)); } + /** + * Get a unique identifier for HomeSp. This identifier depends only on items that remain + * constant throughout the lifetime of a subscription. + * + * @hide + * @return a Unique identifier for a HomeSp object + */ + public int getUniqueId() { + return Objects.hash(mFqdn, mFriendlyName, mHomeNetworkIds, Arrays.hashCode(mMatchAllOis), + Arrays.hashCode(mMatchAnyOis), Arrays.hashCode(mOtherHomePartners), + Arrays.hashCode(mRoamingConsortiumOis)); + } + + @Override public String toString() { StringBuilder builder = new StringBuilder(); -- cgit v1.2.3 From 381ba3e270c1a546d7f4e518f8c63041d8afdf21 Mon Sep 17 00:00:00 2001 From: David Su Date: Mon, 27 Jan 2020 17:45:29 -0800 Subject: Wifi: Rename requirePMF to requirePmf Rename to conform to API guidelines. Bug: 146046526 Test: compiles Change-Id: If8089bcbf9e18d4fadfe8abe7fdab418f8c1bbca --- wifi/java/android/net/wifi/WifiConfiguration.java | 16 ++++++++-------- .../src/android/net/wifi/WifiConfigurationTest.java | 6 +++--- .../src/android/net/wifi/WifiNetworkSuggestionTest.java | 6 +++--- 3 files changed, 14 insertions(+), 14 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 0cce23d196cf..bc31e2c87878 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -486,7 +486,7 @@ public class WifiConfiguration implements Parcelable { allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SAE); allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP); allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); - requirePMF = true; + requirePmf = true; break; case SECURITY_TYPE_EAP_SUITE_B: allowedProtocols.set(WifiConfiguration.Protocol.RSN); @@ -496,14 +496,14 @@ public class WifiConfiguration implements Parcelable { allowedGroupManagementCiphers.set(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256); // Note: allowedSuiteBCiphers bitset will be set by the service once the // certificates are attached to this profile - requirePMF = true; + requirePmf = true; break; case SECURITY_TYPE_OWE: allowedProtocols.set(WifiConfiguration.Protocol.RSN); allowedKeyManagement.set(WifiConfiguration.KeyMgmt.OWE); allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP); allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); - requirePMF = true; + requirePmf = true; break; case SECURITY_TYPE_WAPI_PSK: allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WAPI_PSK); @@ -662,7 +662,7 @@ public class WifiConfiguration implements Parcelable { * @hide */ @SystemApi - public boolean requirePMF; + public boolean requirePmf; /** * Update identifier, for Passpoint network. @@ -2168,7 +2168,7 @@ public class WifiConfiguration implements Parcelable { append(" BSSID: ").append(this.BSSID).append(" FQDN: ").append(this.FQDN) .append(" PRIO: ").append(this.priority) .append(" HIDDEN: ").append(this.hiddenSSID) - .append(" PMF: ").append(this.requirePMF) + .append(" PMF: ").append(this.requirePmf) .append("CarrierId: ").append(this.carrierId) .append('\n'); @@ -2757,7 +2757,7 @@ public class WifiConfiguration implements Parcelable { mRandomizedMacAddress = source.mRandomizedMacAddress; macRandomizationSetting = source.macRandomizationSetting; randomizedMacExpirationTimeMs = source.randomizedMacExpirationTimeMs; - requirePMF = source.requirePMF; + requirePmf = source.requirePmf; updateIdentifier = source.updateIdentifier; carrierId = source.carrierId; mPasspointUniqueId = source.mPasspointUniqueId; @@ -2789,7 +2789,7 @@ public class WifiConfiguration implements Parcelable { dest.writeInt(wepTxKeyIndex); dest.writeInt(priority); dest.writeInt(hiddenSSID ? 1 : 0); - dest.writeInt(requirePMF ? 1 : 0); + dest.writeInt(requirePmf ? 1 : 0); dest.writeString(updateIdentifier); writeBitSet(dest, allowedKeyManagement); @@ -2865,7 +2865,7 @@ public class WifiConfiguration implements Parcelable { config.wepTxKeyIndex = in.readInt(); config.priority = in.readInt(); config.hiddenSSID = in.readInt() != 0; - config.requirePMF = in.readInt() != 0; + config.requirePmf = in.readInt() != 0; config.updateIdentifier = in.readString(); config.allowedKeyManagement = readBitSet(in); diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java index 05a3dce44022..00790d5a2d60 100644 --- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java @@ -363,7 +363,7 @@ public class WifiConfigurationTest { assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SAE)); assertTrue(config.allowedPairwiseCiphers.get(WifiConfiguration.PairwiseCipher.CCMP)); assertTrue(config.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.CCMP)); - assertTrue(config.requirePMF); + assertTrue(config.requirePmf); } /** @@ -380,7 +380,7 @@ public class WifiConfigurationTest { assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.OWE)); assertTrue(config.allowedPairwiseCiphers.get(WifiConfiguration.PairwiseCipher.CCMP)); assertTrue(config.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.CCMP)); - assertTrue(config.requirePMF); + assertTrue(config.requirePmf); } /** @@ -399,7 +399,7 @@ public class WifiConfigurationTest { assertTrue(config.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.GCMP_256)); assertTrue(config.allowedGroupManagementCiphers .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256)); - assertTrue(config.requirePMF); + assertTrue(config.requirePmf); } /** diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java index af6fb5c1cd22..51bf7380a1bb 100644 --- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java +++ b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java @@ -140,7 +140,7 @@ public class WifiNetworkSuggestionTest { assertTrue(suggestion.wifiConfiguration.allowedKeyManagement .get(WifiConfiguration.KeyMgmt.OWE)); assertNull(suggestion.wifiConfiguration.preSharedKey); - assertTrue(suggestion.wifiConfiguration.requirePMF); + assertTrue(suggestion.wifiConfiguration.requirePmf); assertFalse(suggestion.isUserAllowedToManuallyConnect); assertTrue(suggestion.isInitialAutoJoinEnabled); } @@ -163,7 +163,7 @@ public class WifiNetworkSuggestionTest { .get(WifiConfiguration.KeyMgmt.SAE)); assertEquals("\"" + TEST_PRESHARED_KEY + "\"", suggestion.wifiConfiguration.preSharedKey); - assertTrue(suggestion.wifiConfiguration.requirePMF); + assertTrue(suggestion.wifiConfiguration.requirePmf); assertTrue(suggestion.isUserAllowedToManuallyConnect); assertFalse(suggestion.isInitialAutoJoinEnabled); } @@ -191,7 +191,7 @@ public class WifiNetworkSuggestionTest { .get(WifiConfiguration.GroupCipher.GCMP_256)); assertTrue(suggestion.wifiConfiguration.allowedGroupManagementCiphers .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256)); - assertTrue(suggestion.wifiConfiguration.requirePMF); + assertTrue(suggestion.wifiConfiguration.requirePmf); assertNull(suggestion.wifiConfiguration.preSharedKey); // allowedSuiteBCiphers are set according to the loaded certificate and cannot be tested // here. -- cgit v1.2.3 From 91c3b5af51a8226c493689e4c3e8c5dad3e16a47 Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Wed, 12 Feb 2020 15:11:24 -0800 Subject: [Passpoint] Truncate IMSI from the SimCredential toString method Truncate IMSI from the SimCredential toString method, avoid displaying confidential IMSI information. Bug: 149422812 Test: dumpsys wifi - confirm result Change-Id: I9d542bc6ff60de1a78076abe1010c0c03a5f444b --- wifi/java/android/net/wifi/hotspot2/pps/Credential.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java index 99901808ec3e..9c01d3643c19 100644 --- a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java +++ b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java @@ -738,7 +738,16 @@ public final class Credential implements Parcelable { @Override public String toString() { StringBuilder builder = new StringBuilder(); - builder.append("IMSI: ").append(mImsi).append("\n"); + String imsi; + if (mImsi != null) { + if (mImsi.length() > 6 && mImsi.charAt(6) != '*') { + // Truncate the full IMSI from the log + imsi = mImsi.substring(0, 6) + "****"; + } else { + imsi = mImsi; + } + builder.append("IMSI: ").append(imsi).append("\n"); + } builder.append("EAPType: ").append(mEapType).append("\n"); return builder.toString(); } -- cgit v1.2.3 From bdb30cb6bb5b7a41f410fe36bc6430b52a13d3b9 Mon Sep 17 00:00:00 2001 From: Adrian Roos Date: Wed, 12 Feb 2020 16:47:12 -0800 Subject: API Lint: Ignore existing CallbackMethodName violations Bug: 149430296 Test: make checkapi Change-Id: Ic6f634355c77f4236083065f7ca933fbee5534a6 Exempt-From-Owner-Approval: API Lint suppresion --- wifi/java/android/net/wifi/WifiManager.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index a3cce7c00b3a..6eacdded9797 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -28,6 +28,7 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; +import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; import android.app.ActivityManager; @@ -1622,11 +1623,13 @@ public class WifiManager { * @param wifiConfiguration WifiConfiguration object corresponding to the network * user selected. */ + @SuppressLint("CallbackMethodName") default void select(@NonNull WifiConfiguration wifiConfiguration) {} /** * User rejected the app's request. */ + @SuppressLint("CallbackMethodName") default void reject() {} } -- cgit v1.2.3 From 804d94a10062702f81475348d8f88cb3160ffb99 Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Sat, 15 Feb 2020 17:33:27 -0800 Subject: [WifiNl80211] Rename WifiNl80211Manager namespace Finish the renaming process from wificond -> nl80211. Bug: 149105833 Test: atest android.net.wifi Test: atest com.android.server.wifi Change-Id: Icf94799b560da66a5366743fd2a33b0f152da335 --- wifi/Android.bp | 2 +- .../android/net/wifi/nl80211/ChannelSettings.java | 95 ++ .../net/wifi/nl80211/DeviceWiphyCapabilities.java | 272 +++++ .../android/net/wifi/nl80211/HiddenNetwork.java | 87 ++ .../android/net/wifi/nl80211/NativeScanResult.java | 310 +++++ .../android/net/wifi/nl80211/NativeWifiClient.java | 103 ++ wifi/java/android/net/wifi/nl80211/PnoNetwork.java | 171 +++ .../java/android/net/wifi/nl80211/PnoSettings.java | 209 ++++ .../android/net/wifi/nl80211/RadioChainInfo.java | 125 ++ .../net/wifi/nl80211/SingleScanSettings.java | 118 ++ .../net/wifi/nl80211/WifiNl80211Manager.java | 1287 ++++++++++++++++++++ .../android/net/wifi/wificond/ChannelSettings.java | 95 -- .../net/wifi/wificond/DeviceWiphyCapabilities.java | 272 ----- .../android/net/wifi/wificond/HiddenNetwork.java | 87 -- .../net/wifi/wificond/NativeScanResult.java | 310 ----- .../net/wifi/wificond/NativeWifiClient.java | 103 -- .../java/android/net/wifi/wificond/PnoNetwork.java | 171 --- .../android/net/wifi/wificond/PnoSettings.java | 209 ---- .../android/net/wifi/wificond/RadioChainInfo.java | 125 -- .../net/wifi/wificond/SingleScanSettings.java | 118 -- .../net/wifi/wificond/WifiNl80211Manager.java | 1287 -------------------- .../wifi/nl80211/DeviceWiphyCapabilitiesTest.java | 88 ++ .../net/wifi/nl80211/NativeScanResultTest.java | 87 ++ .../android/net/wifi/nl80211/PnoSettingsTest.java | 112 ++ .../net/wifi/nl80211/SingleScanSettingsTest.java | 116 ++ .../net/wifi/nl80211/WifiNl80211ManagerTest.java | 1265 +++++++++++++++++++ .../wifi/wificond/DeviceWiphyCapabilitiesTest.java | 88 -- .../net/wifi/wificond/NativeScanResultTest.java | 87 -- .../android/net/wifi/wificond/PnoSettingsTest.java | 112 -- .../net/wifi/wificond/SingleScanSettingsTest.java | 116 -- .../net/wifi/wificond/WifiNl80211ManagerTest.java | 1265 ------------------- 31 files changed, 4446 insertions(+), 4446 deletions(-) create mode 100644 wifi/java/android/net/wifi/nl80211/ChannelSettings.java create mode 100644 wifi/java/android/net/wifi/nl80211/DeviceWiphyCapabilities.java create mode 100644 wifi/java/android/net/wifi/nl80211/HiddenNetwork.java create mode 100644 wifi/java/android/net/wifi/nl80211/NativeScanResult.java create mode 100644 wifi/java/android/net/wifi/nl80211/NativeWifiClient.java create mode 100644 wifi/java/android/net/wifi/nl80211/PnoNetwork.java create mode 100644 wifi/java/android/net/wifi/nl80211/PnoSettings.java create mode 100644 wifi/java/android/net/wifi/nl80211/RadioChainInfo.java create mode 100644 wifi/java/android/net/wifi/nl80211/SingleScanSettings.java create mode 100644 wifi/java/android/net/wifi/nl80211/WifiNl80211Manager.java delete mode 100644 wifi/java/android/net/wifi/wificond/ChannelSettings.java delete mode 100644 wifi/java/android/net/wifi/wificond/DeviceWiphyCapabilities.java delete mode 100644 wifi/java/android/net/wifi/wificond/HiddenNetwork.java delete mode 100644 wifi/java/android/net/wifi/wificond/NativeScanResult.java delete mode 100644 wifi/java/android/net/wifi/wificond/NativeWifiClient.java delete mode 100644 wifi/java/android/net/wifi/wificond/PnoNetwork.java delete mode 100644 wifi/java/android/net/wifi/wificond/PnoSettings.java delete mode 100644 wifi/java/android/net/wifi/wificond/RadioChainInfo.java delete mode 100644 wifi/java/android/net/wifi/wificond/SingleScanSettings.java delete mode 100644 wifi/java/android/net/wifi/wificond/WifiNl80211Manager.java create mode 100644 wifi/tests/src/android/net/wifi/nl80211/DeviceWiphyCapabilitiesTest.java create mode 100644 wifi/tests/src/android/net/wifi/nl80211/NativeScanResultTest.java create mode 100644 wifi/tests/src/android/net/wifi/nl80211/PnoSettingsTest.java create mode 100644 wifi/tests/src/android/net/wifi/nl80211/SingleScanSettingsTest.java create mode 100644 wifi/tests/src/android/net/wifi/nl80211/WifiNl80211ManagerTest.java delete mode 100644 wifi/tests/src/android/net/wifi/wificond/DeviceWiphyCapabilitiesTest.java delete mode 100644 wifi/tests/src/android/net/wifi/wificond/NativeScanResultTest.java delete mode 100644 wifi/tests/src/android/net/wifi/wificond/PnoSettingsTest.java delete mode 100644 wifi/tests/src/android/net/wifi/wificond/SingleScanSettingsTest.java delete mode 100644 wifi/tests/src/android/net/wifi/wificond/WifiNl80211ManagerTest.java (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 1763975e7770..5c9fb4e86bc7 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -48,7 +48,7 @@ filegroup { // to a separate package. "java/android/net/wifi/WifiNetworkScoreCache.java", "java/android/net/wifi/WifiOemMigrationHook.java", - "java/android/net/wifi/wificond/*.java", + "java/android/net/wifi/nl80211/*.java", ":libwificond_ipc_aidl", ], } diff --git a/wifi/java/android/net/wifi/nl80211/ChannelSettings.java b/wifi/java/android/net/wifi/nl80211/ChannelSettings.java new file mode 100644 index 000000000000..4c14fd499c28 --- /dev/null +++ b/wifi/java/android/net/wifi/nl80211/ChannelSettings.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2016 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.nl80211; + +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Log; + +import java.util.Objects; + +/** + * ChannelSettings for wificond + * + * @hide + */ +public class ChannelSettings implements Parcelable { + private static final String TAG = "ChannelSettings"; + + public int frequency; + + /** public constructor */ + public ChannelSettings() { } + + /** override comparator */ + @Override + public boolean equals(Object rhs) { + if (this == rhs) return true; + if (!(rhs instanceof ChannelSettings)) { + return false; + } + ChannelSettings channel = (ChannelSettings) rhs; + if (channel == null) { + return false; + } + return frequency == channel.frequency; + } + + /** override hash code */ + @Override + public int hashCode() { + return Objects.hash(frequency); + } + + /** implement Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** + * implement Parcelable interface + * |flags| is ignored. + **/ + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(frequency); + } + + /** implement Parcelable interface */ + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + /** + * Caller is responsible for providing a valid parcel. + */ + @Override + public ChannelSettings createFromParcel(Parcel in) { + ChannelSettings result = new ChannelSettings(); + result.frequency = in.readInt(); + if (in.dataAvail() != 0) { + Log.e(TAG, "Found trailing data after parcel parsing."); + } + + return result; + } + + @Override + public ChannelSettings[] newArray(int size) { + return new ChannelSettings[size]; + } + }; +} diff --git a/wifi/java/android/net/wifi/nl80211/DeviceWiphyCapabilities.java b/wifi/java/android/net/wifi/nl80211/DeviceWiphyCapabilities.java new file mode 100644 index 000000000000..a045aad9f64c --- /dev/null +++ b/wifi/java/android/net/wifi/nl80211/DeviceWiphyCapabilities.java @@ -0,0 +1,272 @@ +/* + * Copyright (C) 2020 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.nl80211; + +import android.annotation.NonNull; +import android.annotation.SystemApi; +import android.net.wifi.ScanResult; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Log; + +import java.util.Objects; + +/** + * DeviceWiphyCapabilities for wificond + * + * @hide + */ +@SystemApi +public final class DeviceWiphyCapabilities implements Parcelable { + private static final String TAG = "DeviceWiphyCapabilities"; + + private boolean m80211nSupported; + private boolean m80211acSupported; + private boolean m80211axSupported; + private boolean mChannelWidth160MhzSupported; + private boolean mChannelWidth80p80MhzSupported; + private int mMaxNumberTxSpatialStreams; + private int mMaxNumberRxSpatialStreams; + + + /** public constructor */ + public DeviceWiphyCapabilities() { + m80211nSupported = false; + m80211acSupported = false; + m80211axSupported = false; + mChannelWidth160MhzSupported = false; + mChannelWidth80p80MhzSupported = false; + mMaxNumberTxSpatialStreams = 1; + mMaxNumberRxSpatialStreams = 1; + } + + /** + * Get the IEEE 802.11 standard support + * + * @param standard the IEEE 802.11 standard to check on its support. + * valid values from {@link ScanResult}'s {@code WIFI_STANDARD_} + * @return {@code true} if supported, {@code false} otherwise. + */ + public boolean isWifiStandardSupported(int standard) { + switch (standard) { + case ScanResult.WIFI_STANDARD_LEGACY: + return true; + case ScanResult.WIFI_STANDARD_11N: + return m80211nSupported; + case ScanResult.WIFI_STANDARD_11AC: + return m80211acSupported; + case ScanResult.WIFI_STANDARD_11AX: + return m80211axSupported; + default: + Log.e(TAG, "isWifiStandardSupported called with invalid standard: " + standard); + return false; + } + } + + /** + * Set the IEEE 802.11 standard support + * + * @param standard the IEEE 802.11 standard to set its support. + * valid values from {@link ScanResult}'s {@code WIFI_STANDARD_} + * @param support {@code true} if supported, {@code false} otherwise. + */ + public void setWifiStandardSupport(int standard, boolean support) { + switch (standard) { + case ScanResult.WIFI_STANDARD_11N: + m80211nSupported = support; + break; + case ScanResult.WIFI_STANDARD_11AC: + m80211acSupported = support; + break; + case ScanResult.WIFI_STANDARD_11AX: + m80211axSupported = support; + break; + default: + Log.e(TAG, "setWifiStandardSupport called with invalid standard: " + standard); + } + } + + /** + * Get the support for channel bandwidth + * + * @param chWidth valid values from {@link ScanResult}'s {@code CHANNEL_WIDTH_} + * + * @return {@code true} if supported, {@code false} otherwise. + */ + public boolean isChannelWidthSupported(int chWidth) { + switch (chWidth) { + case ScanResult.CHANNEL_WIDTH_20MHZ: + return true; + case ScanResult.CHANNEL_WIDTH_40MHZ: + return (m80211nSupported || m80211acSupported || m80211axSupported); + case ScanResult.CHANNEL_WIDTH_80MHZ: + return (m80211acSupported || m80211axSupported); + case ScanResult.CHANNEL_WIDTH_160MHZ: + return mChannelWidth160MhzSupported; + case ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ: + return mChannelWidth80p80MhzSupported; + default: + Log.e(TAG, "isChannelWidthSupported called with invalid channel width: " + chWidth); + } + return false; + } + + /** + * Set support for channel bandwidth + * + * @param chWidth valid values are {@link ScanResult#CHANNEL_WIDTH_160MHZ} and + * {@link ScanResult#CHANNEL_WIDTH_80MHZ_PLUS_MHZ} + * @param support {@code true} if supported, {@code false} otherwise. + */ + public void setChannelWidthSupported(int chWidth, boolean support) { + switch (chWidth) { + case ScanResult.CHANNEL_WIDTH_160MHZ: + mChannelWidth160MhzSupported = support; + break; + case ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ: + mChannelWidth80p80MhzSupported = support; + break; + default: + Log.e(TAG, "setChannelWidthSupported called with Invalid channel width: " + + chWidth); + } + } + + /** + * Get maximum number of transmit spatial streams + * + * @return number of spatial streams + */ + public int getMaxNumberTxSpatialStreams() { + return mMaxNumberTxSpatialStreams; + } + + /** + * Set maximum number of transmit spatial streams + * + * @param streams number of spatial streams + */ + public void setMaxNumberTxSpatialStreams(int streams) { + mMaxNumberTxSpatialStreams = streams; + } + + /** + * Get maximum number of receive spatial streams + * + * @return number of streams + */ + public int getMaxNumberRxSpatialStreams() { + return mMaxNumberRxSpatialStreams; + } + + /** + * Set maximum number of receive spatial streams + * + * @param streams number of streams + */ + public void setMaxNumberRxSpatialStreams(int streams) { + mMaxNumberRxSpatialStreams = streams; + } + + /** override comparator */ + @Override + public boolean equals(Object rhs) { + if (this == rhs) return true; + if (!(rhs instanceof DeviceWiphyCapabilities)) { + return false; + } + DeviceWiphyCapabilities capa = (DeviceWiphyCapabilities) rhs; + + return m80211nSupported == capa.m80211nSupported + && m80211acSupported == capa.m80211acSupported + && m80211axSupported == capa.m80211axSupported + && mChannelWidth160MhzSupported == capa.mChannelWidth160MhzSupported + && mChannelWidth80p80MhzSupported == capa.mChannelWidth80p80MhzSupported + && mMaxNumberTxSpatialStreams == capa.mMaxNumberTxSpatialStreams + && mMaxNumberRxSpatialStreams == capa.mMaxNumberRxSpatialStreams; + } + + /** override hash code */ + @Override + public int hashCode() { + return Objects.hash(m80211nSupported, m80211acSupported, m80211axSupported, + mChannelWidth160MhzSupported, mChannelWidth80p80MhzSupported, + mMaxNumberTxSpatialStreams, mMaxNumberRxSpatialStreams); + } + + /** implement Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** + * implement Parcelable interface + * |flags| is ignored. + */ + @Override + public void writeToParcel(@NonNull Parcel out, int flags) { + out.writeBoolean(m80211nSupported); + out.writeBoolean(m80211acSupported); + out.writeBoolean(m80211axSupported); + out.writeBoolean(mChannelWidth160MhzSupported); + out.writeBoolean(mChannelWidth80p80MhzSupported); + out.writeInt(mMaxNumberTxSpatialStreams); + out.writeInt(mMaxNumberRxSpatialStreams); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("m80211nSupported:").append(m80211nSupported ? "Yes" : "No"); + sb.append("m80211acSupported:").append(m80211acSupported ? "Yes" : "No"); + sb.append("m80211axSupported:").append(m80211axSupported ? "Yes" : "No"); + sb.append("mChannelWidth160MhzSupported: ") + .append(mChannelWidth160MhzSupported ? "Yes" : "No"); + sb.append("mChannelWidth80p80MhzSupported: ") + .append(mChannelWidth80p80MhzSupported ? "Yes" : "No"); + sb.append("mMaxNumberTxSpatialStreams: ").append(mMaxNumberTxSpatialStreams); + sb.append("mMaxNumberRxSpatialStreams: ").append(mMaxNumberRxSpatialStreams); + + return sb.toString(); + } + + /** implement Parcelable interface */ + public static final @NonNull Parcelable.Creator CREATOR = + new Parcelable.Creator() { + /** + * Caller is responsible for providing a valid parcel. + */ + @Override + public DeviceWiphyCapabilities createFromParcel(Parcel in) { + DeviceWiphyCapabilities capabilities = new DeviceWiphyCapabilities(); + capabilities.m80211nSupported = in.readBoolean(); + capabilities.m80211acSupported = in.readBoolean(); + capabilities.m80211axSupported = in.readBoolean(); + capabilities.mChannelWidth160MhzSupported = in.readBoolean(); + capabilities.mChannelWidth80p80MhzSupported = in.readBoolean(); + capabilities.mMaxNumberTxSpatialStreams = in.readInt(); + capabilities.mMaxNumberRxSpatialStreams = in.readInt(); + return capabilities; + } + + @Override + public DeviceWiphyCapabilities[] newArray(int size) { + return new DeviceWiphyCapabilities[size]; + } + }; +} diff --git a/wifi/java/android/net/wifi/nl80211/HiddenNetwork.java b/wifi/java/android/net/wifi/nl80211/HiddenNetwork.java new file mode 100644 index 000000000000..b1475b2c7b43 --- /dev/null +++ b/wifi/java/android/net/wifi/nl80211/HiddenNetwork.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2016 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.nl80211; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.Arrays; + +/** + * HiddenNetwork for wificond + * + * @hide + */ +public class HiddenNetwork implements Parcelable { + private static final String TAG = "HiddenNetwork"; + + public byte[] ssid; + + /** public constructor */ + public HiddenNetwork() { } + + /** override comparator */ + @Override + public boolean equals(Object rhs) { + if (this == rhs) return true; + if (!(rhs instanceof HiddenNetwork)) { + return false; + } + HiddenNetwork network = (HiddenNetwork) rhs; + return Arrays.equals(ssid, network.ssid); + } + + /** override hash code */ + @Override + public int hashCode() { + return Arrays.hashCode(ssid); + } + + /** implement Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** + * implement Parcelable interface + * |flags| is ignored. + */ + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeByteArray(ssid); + } + + /** implement Parcelable interface */ + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + /** + * Caller is responsible for providing a valid parcel. + */ + @Override + public HiddenNetwork createFromParcel(Parcel in) { + HiddenNetwork result = new HiddenNetwork(); + result.ssid = in.createByteArray(); + return result; + } + + @Override + public HiddenNetwork[] newArray(int size) { + return new HiddenNetwork[size]; + } + }; +} diff --git a/wifi/java/android/net/wifi/nl80211/NativeScanResult.java b/wifi/java/android/net/wifi/nl80211/NativeScanResult.java new file mode 100644 index 000000000000..a8e999973fe8 --- /dev/null +++ b/wifi/java/android/net/wifi/nl80211/NativeScanResult.java @@ -0,0 +1,310 @@ +/* + * Copyright (C) 2016 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.nl80211; + +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.net.MacAddress; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Log; + +import com.android.internal.annotations.VisibleForTesting; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Raw scan result data from the wificond daemon. + * + * @hide + */ +@SystemApi +public final class NativeScanResult implements Parcelable { + private static final String TAG = "NativeScanResult"; + + /** @hide */ + @VisibleForTesting + public byte[] ssid; + /** @hide */ + @VisibleForTesting + public byte[] bssid; + /** @hide */ + @VisibleForTesting + public byte[] infoElement; + /** @hide */ + @VisibleForTesting + public int frequency; + /** @hide */ + @VisibleForTesting + public int signalMbm; + /** @hide */ + @VisibleForTesting + public long tsf; + /** @hide */ + @VisibleForTesting + @BssCapabilityBits public int capability; + /** @hide */ + @VisibleForTesting + public boolean associated; + /** @hide */ + @VisibleForTesting + public List radioChainInfos; + + /** + * Returns the SSID raw byte array of the AP represented by this scan result. + * + * @return A byte array. + */ + @NonNull public byte[] getSsid() { + return ssid; + } + + /** + * Returns the MAC address (BSSID) of the AP represented by this scan result. + * + * @return a MacAddress or null on error. + */ + @Nullable public MacAddress getBssid() { + try { + return MacAddress.fromBytes(bssid); + } catch (IllegalArgumentException e) { + Log.e(TAG, "Illegal argument " + Arrays.toString(bssid), e); + return null; + } + } + + /** + * Returns the raw bytes of the information element advertised by the AP represented by this + * scan result. + * + * @return A byte array, possibly null or containing an invalid TLV configuration. + */ + @NonNull public byte[] getInformationElements() { + return infoElement; + } + + /** + * Returns the frequency (in MHz) on which the AP represented by this scan result was observed. + * + * @return The frequency in MHz. + */ + public int getFrequencyMhz() { + return frequency; + } + + /** + * Return the signal strength of probe response/beacon in (100 * dBm). + * + * @return Signal strenght in (100 * dBm). + */ + public int getSignalMbm() { + return signalMbm; + } + + /** + * Return the TSF (Timing Synchronization Function) of the received probe response/beacon. + * @return + */ + public long getTsf() { + return tsf; + } + + /** + * Return a boolean indicating whether or not we're associated to the AP represented by this + * scan result. + * + * @return A boolean indicating association. + */ + public boolean isAssociated() { + return associated; + } + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(flag = true, prefix = {"BSS_CAPABILITY_"}, + value = {BSS_CAPABILITY_ESS, + BSS_CAPABILITY_IBSS, + BSS_CAPABILITY_CF_POLLABLE, + BSS_CAPABILITY_CF_POLL_REQUEST, + BSS_CAPABILITY_PRIVACY, + BSS_CAPABILITY_SHORT_PREAMBLE, + BSS_CAPABILITY_PBCC, + BSS_CAPABILITY_CHANNEL_AGILITY, + BSS_CAPABILITY_SPECTRUM_MANAGEMENT, + BSS_CAPABILITY_QOS, + BSS_CAPABILITY_SHORT_SLOT_TIME, + BSS_CAPABILITY_APSD, + BSS_CAPABILITY_RADIO_MANAGEMENT, + BSS_CAPABILITY_DSSS_OFDM, + BSS_CAPABILITY_DELAYED_BLOCK_ACK, + BSS_CAPABILITY_IMMEDIATE_BLOCK_ACK + }) + public @interface BssCapabilityBits { } + + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): ESS. + */ + public static final int BSS_CAPABILITY_ESS = 0x1 << 0; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): IBSS. + */ + public static final int BSS_CAPABILITY_IBSS = 0x1 << 1; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): CF Pollable. + */ + public static final int BSS_CAPABILITY_CF_POLLABLE = 0x1 << 2; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): CF-Poll Request. + */ + public static final int BSS_CAPABILITY_CF_POLL_REQUEST = 0x1 << 3; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Privacy. + */ + public static final int BSS_CAPABILITY_PRIVACY = 0x1 << 4; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Short Preamble. + */ + public static final int BSS_CAPABILITY_SHORT_PREAMBLE = 0x1 << 5; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): PBCC. + */ + public static final int BSS_CAPABILITY_PBCC = 0x1 << 6; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Channel Agility. + */ + public static final int BSS_CAPABILITY_CHANNEL_AGILITY = 0x1 << 7; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Spectrum Management. + */ + public static final int BSS_CAPABILITY_SPECTRUM_MANAGEMENT = 0x1 << 8; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): QoS. + */ + public static final int BSS_CAPABILITY_QOS = 0x1 << 9; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Short Slot Time. + */ + public static final int BSS_CAPABILITY_SHORT_SLOT_TIME = 0x1 << 10; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): APSD. + */ + public static final int BSS_CAPABILITY_APSD = 0x1 << 11; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Radio Management. + */ + public static final int BSS_CAPABILITY_RADIO_MANAGEMENT = 0x1 << 12; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): DSSS-OFDM. + */ + public static final int BSS_CAPABILITY_DSSS_OFDM = 0x1 << 13; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Delayed Block Ack. + */ + public static final int BSS_CAPABILITY_DELAYED_BLOCK_ACK = 0x1 << 14; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Immediate Block Ack. + */ + public static final int BSS_CAPABILITY_IMMEDIATE_BLOCK_ACK = 0x1 << 15; + + /** + * Returns the capabilities of the AP repseresented by this scan result as advertised in the + * received probe response or beacon. + * + * This is a bit mask describing the capabilities of a BSS. See IEEE Std 802.11: 9.4.1.4: one + * of the {@code BSS_CAPABILITY_*} flags. + * + * @return a bit mask of capabilities. + */ + @BssCapabilityBits public int getCapabilities() { + return capability; + } + + /** + * Returns details of the signal received on each radio chain for the AP represented by this + * scan result in a list of {@link RadioChainInfo} elements. + * + * @return A list of {@link RadioChainInfo} - possibly empty in case of error. + */ + @NonNull public List getRadioChainInfos() { + return radioChainInfos; + } + + /** + * Construct an empty native scan result. + */ + public NativeScanResult() { } + + /** implement Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** implement Parcelable interface */ + @Override + public void writeToParcel(@NonNull Parcel out, int flags) { + out.writeByteArray(ssid); + out.writeByteArray(bssid); + out.writeByteArray(infoElement); + out.writeInt(frequency); + out.writeInt(signalMbm); + out.writeLong(tsf); + out.writeInt(capability); + out.writeInt(associated ? 1 : 0); + out.writeTypedList(radioChainInfos); + } + + /** implement Parcelable interface */ + @NonNull public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @Override + public NativeScanResult createFromParcel(Parcel in) { + NativeScanResult result = new NativeScanResult(); + result.ssid = in.createByteArray(); + if (result.ssid == null) { + result.ssid = new byte[0]; + } + result.bssid = in.createByteArray(); + if (result.bssid == null) { + result.bssid = new byte[0]; + } + result.infoElement = in.createByteArray(); + if (result.infoElement == null) { + result.infoElement = new byte[0]; + } + result.frequency = in.readInt(); + result.signalMbm = in.readInt(); + result.tsf = in.readLong(); + result.capability = in.readInt(); + result.associated = (in.readInt() != 0); + result.radioChainInfos = new ArrayList<>(); + in.readTypedList(result.radioChainInfos, RadioChainInfo.CREATOR); + return result; + } + + @Override + public NativeScanResult[] newArray(int size) { + return new NativeScanResult[size]; + } + }; +} diff --git a/wifi/java/android/net/wifi/nl80211/NativeWifiClient.java b/wifi/java/android/net/wifi/nl80211/NativeWifiClient.java new file mode 100644 index 000000000000..984d7d034302 --- /dev/null +++ b/wifi/java/android/net/wifi/nl80211/NativeWifiClient.java @@ -0,0 +1,103 @@ +/* + * 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.nl80211; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.net.MacAddress; +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.Objects; + +/** + * Structure providing information about clients (STAs) associated with a SoftAp. + * + * @hide + */ +@SystemApi +public final class NativeWifiClient implements Parcelable { + private final MacAddress mMacAddress; + + /** + * The MAC address of the client (STA) represented by this object. The MAC address may be null + * in case of an error. + */ + @Nullable public MacAddress getMacAddress() { + return mMacAddress; + } + + /** + * Construct a native Wi-Fi client. + */ + public NativeWifiClient(@Nullable MacAddress macAddress) { + this.mMacAddress = macAddress; + } + + /** override comparator */ + @Override + public boolean equals(Object rhs) { + if (this == rhs) return true; + if (!(rhs instanceof NativeWifiClient)) { + return false; + } + NativeWifiClient other = (NativeWifiClient) rhs; + return Objects.equals(mMacAddress, other.mMacAddress); + } + + /** override hash code */ + @Override + public int hashCode() { + return mMacAddress.hashCode(); + } + + /** implement Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** + * implement Parcelable interface + * |flag| is ignored. + */ + @Override + public void writeToParcel(@NonNull Parcel out, int flags) { + out.writeByteArray(mMacAddress.toByteArray()); + } + + /** implement Parcelable interface */ + @NonNull public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @Override + public NativeWifiClient createFromParcel(Parcel in) { + MacAddress macAddress; + try { + macAddress = MacAddress.fromBytes(in.createByteArray()); + } catch (IllegalArgumentException e) { + macAddress = null; + } + return new NativeWifiClient(macAddress); + } + + @Override + public NativeWifiClient[] newArray(int size) { + return new NativeWifiClient[size]; + } + }; +} diff --git a/wifi/java/android/net/wifi/nl80211/PnoNetwork.java b/wifi/java/android/net/wifi/nl80211/PnoNetwork.java new file mode 100644 index 000000000000..e8eff09583b9 --- /dev/null +++ b/wifi/java/android/net/wifi/nl80211/PnoNetwork.java @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2016 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.nl80211; + +import android.annotation.NonNull; +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.Arrays; +import java.util.Objects; + +/** + * Configuration for a PNO (preferred network offload) network used in {@link PnoSettings}. A PNO + * network allows configuration of a specific network to search for. + * + * @hide + */ +@SystemApi +public final class PnoNetwork implements Parcelable { + private boolean mIsHidden; + private byte[] mSsid; + private int[] mFrequencies; + + /** + * Indicates whether the PNO network configuration is for a hidden SSID - i.e. a network which + * does not broadcast its SSID and must be queried explicitly. + * + * @return True if the configuration is for a hidden network, false otherwise. + */ + public boolean isHidden() { + return mIsHidden; + } + + /** + * Configure whether the PNO network configuration is for a hidden SSID - i.e. a network which + * does not broadcast its SSID and must be queried explicitly. + * + * @param isHidden True if the configuration is for a hidden network, false otherwise. + */ + public void setHidden(boolean isHidden) { + mIsHidden = isHidden; + } + + /** + * Get the raw bytes for the SSID of the PNO network being scanned for. + * + * @return A byte array. + */ + @NonNull public byte[] getSsid() { + return mSsid; + } + + /** + * Set the raw bytes for the SSID of the PNO network being scanned for. + * + * @param ssid A byte array. + */ + public void setSsid(@NonNull byte[] ssid) { + if (ssid == null) { + throw new IllegalArgumentException("null argument"); + } + this.mSsid = ssid; + } + + /** + * Get the frequencies (in MHz) on which to PNO scan for the current network is being searched + * for. A null return (i.e. no frequencies configured) indicates that the network is search for + * on all supported frequencies. + * + * @return A array of frequencies (in MHz), a null indicates no configured frequencies. + */ + @NonNull public int[] getFrequenciesMhz() { + return mFrequencies; + } + + /** + * Set the frequencies (in MHz) on which to PNO scan for the current network is being searched + * for. A null configuration (i.e. no frequencies configured) indicates that the network is + * search for on all supported frequencies. + * + * @param frequenciesMhz an array of frequencies (in MHz), null indicating no configured + * frequencies. + */ + public void setFrequenciesMhz(@NonNull int[] frequenciesMhz) { + if (frequenciesMhz == null) { + throw new IllegalArgumentException("null argument"); + } + this.mFrequencies = frequenciesMhz; + } + + /** Construct an uninitialized PnoNetwork object */ + public PnoNetwork() { } + + /** override comparator */ + @Override + public boolean equals(Object rhs) { + if (this == rhs) return true; + if (!(rhs instanceof PnoNetwork)) { + return false; + } + PnoNetwork network = (PnoNetwork) rhs; + return Arrays.equals(mSsid, network.mSsid) + && Arrays.equals(mFrequencies, network.mFrequencies) + && mIsHidden == network.mIsHidden; + } + + /** override hash code */ + @Override + public int hashCode() { + return Objects.hash( + mIsHidden, + Arrays.hashCode(mSsid), + Arrays.hashCode(mFrequencies)); + } + + /** implement Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** + * implement Parcelable interface + * |flag| is ignored. + */ + @Override + public void writeToParcel(@NonNull Parcel out, int flags) { + out.writeInt(mIsHidden ? 1 : 0); + out.writeByteArray(mSsid); + out.writeIntArray(mFrequencies); + } + + /** implement Parcelable interface */ + @NonNull public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @Override + public PnoNetwork createFromParcel(Parcel in) { + PnoNetwork result = new PnoNetwork(); + result.mIsHidden = in.readInt() != 0 ? true : false; + result.mSsid = in.createByteArray(); + if (result.mSsid == null) { + result.mSsid = new byte[0]; + } + result.mFrequencies = in.createIntArray(); + if (result.mFrequencies == null) { + result.mFrequencies = new int[0]; + } + return result; + } + + @Override + public PnoNetwork[] newArray(int size) { + return new PnoNetwork[size]; + } + }; +} diff --git a/wifi/java/android/net/wifi/nl80211/PnoSettings.java b/wifi/java/android/net/wifi/nl80211/PnoSettings.java new file mode 100644 index 000000000000..00ebe624ba0d --- /dev/null +++ b/wifi/java/android/net/wifi/nl80211/PnoSettings.java @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2016 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.nl80211; + +import android.annotation.DurationMillisLong; +import android.annotation.NonNull; +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * Configuration for a PNO (preferred network offload). A mechanism by which scans are offloaded + * from the host device to the Wi-Fi chip. + * + * @hide + */ +@SystemApi +public final class PnoSettings implements Parcelable { + private long mIntervalMs; + private int mMin2gRssi; + private int mMin5gRssi; + private int mMin6gRssi; + private List mPnoNetworks; + + /** Construct an uninitialized PnoSettings object */ + public PnoSettings() { } + + /** + * Get the requested PNO scan interval in milliseconds. + * + * @return An interval in milliseconds. + */ + public @DurationMillisLong long getIntervalMillis() { + return mIntervalMs; + } + + /** + * Set the requested PNO scan interval in milliseconds. + * + * @param intervalMillis An interval in milliseconds. + */ + public void setIntervalMillis(@DurationMillisLong long intervalMillis) { + this.mIntervalMs = intervalMillis; + } + + /** + * Get the requested minimum RSSI threshold (in dBm) for APs to report in scan results in the + * 2.4GHz band. + * + * @return An RSSI value in dBm. + */ + public int getMin2gRssiDbm() { + return mMin2gRssi; + } + + /** + * Set the requested minimum RSSI threshold (in dBm) for APs to report in scan scan results in + * the 2.4GHz band. + * + * @param min2gRssiDbm An RSSI value in dBm. + */ + public void setMin2gRssiDbm(int min2gRssiDbm) { + this.mMin2gRssi = min2gRssiDbm; + } + + /** + * Get the requested minimum RSSI threshold (in dBm) for APs to report in scan results in the + * 5GHz band. + * + * @return An RSSI value in dBm. + */ + public int getMin5gRssiDbm() { + return mMin5gRssi; + } + + /** + * Set the requested minimum RSSI threshold (in dBm) for APs to report in scan scan results in + * the 5GHz band. + * + * @param min5gRssiDbm An RSSI value in dBm. + */ + public void setMin5gRssiDbm(int min5gRssiDbm) { + this.mMin5gRssi = min5gRssiDbm; + } + + /** + * Get the requested minimum RSSI threshold (in dBm) for APs to report in scan results in the + * 6GHz band. + * + * @return An RSSI value in dBm. + */ + public int getMin6gRssiDbm() { + return mMin6gRssi; + } + + /** + * Set the requested minimum RSSI threshold (in dBm) for APs to report in scan scan results in + * the 6GHz band. + * + * @param min6gRssiDbm An RSSI value in dBm. + */ + public void setMin6gRssiDbm(int min6gRssiDbm) { + this.mMin6gRssi = min6gRssiDbm; + } + + /** + * Return the configured list of specific networks to search for in a PNO scan. + * + * @return A list of {@link PnoNetwork} objects, possibly empty if non configured. + */ + @NonNull public List getPnoNetworks() { + return mPnoNetworks; + } + + /** + * Set the list of specified networks to scan for in a PNO scan. The networks (APs) are + * specified using {@link PnoNetwork}s. An empty list indicates that all networks are scanned + * for. + * + * @param pnoNetworks A (possibly empty) list of {@link PnoNetwork} objects. + */ + public void setPnoNetworks(@NonNull List pnoNetworks) { + this.mPnoNetworks = pnoNetworks; + } + + /** override comparator */ + @Override + public boolean equals(Object rhs) { + if (this == rhs) return true; + if (!(rhs instanceof PnoSettings)) { + return false; + } + PnoSettings settings = (PnoSettings) rhs; + if (settings == null) { + return false; + } + return mIntervalMs == settings.mIntervalMs + && mMin2gRssi == settings.mMin2gRssi + && mMin5gRssi == settings.mMin5gRssi + && mMin6gRssi == settings.mMin6gRssi + && mPnoNetworks.equals(settings.mPnoNetworks); + } + + /** override hash code */ + @Override + public int hashCode() { + return Objects.hash(mIntervalMs, mMin2gRssi, mMin5gRssi, mMin6gRssi, mPnoNetworks); + } + + /** implement Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** + * implement Parcelable interface + * |flag| is ignored. + **/ + @Override + public void writeToParcel(@NonNull Parcel out, int flags) { + out.writeLong(mIntervalMs); + out.writeInt(mMin2gRssi); + out.writeInt(mMin5gRssi); + out.writeInt(mMin6gRssi); + out.writeTypedList(mPnoNetworks); + } + + /** implement Parcelable interface */ + @NonNull public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @Override + public PnoSettings createFromParcel(Parcel in) { + PnoSettings result = new PnoSettings(); + result.mIntervalMs = in.readLong(); + result.mMin2gRssi = in.readInt(); + result.mMin5gRssi = in.readInt(); + result.mMin6gRssi = in.readInt(); + + result.mPnoNetworks = new ArrayList<>(); + in.readTypedList(result.mPnoNetworks, PnoNetwork.CREATOR); + + return result; + } + + @Override + public PnoSettings[] newArray(int size) { + return new PnoSettings[size]; + } + }; +} diff --git a/wifi/java/android/net/wifi/nl80211/RadioChainInfo.java b/wifi/java/android/net/wifi/nl80211/RadioChainInfo.java new file mode 100644 index 000000000000..2c12163dc9a1 --- /dev/null +++ b/wifi/java/android/net/wifi/nl80211/RadioChainInfo.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2016 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.nl80211; + +import android.annotation.NonNull; +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; + +import com.android.internal.annotations.VisibleForTesting; + +import java.util.Objects; + +/** + * A class representing the radio chains of the Wi-Fi modems. Use to provide raw information about + * signals received on different radio chains. + * + * @hide + */ +@SystemApi +public final class RadioChainInfo implements Parcelable { + private static final String TAG = "RadioChainInfo"; + + /** @hide */ + @VisibleForTesting + public int chainId; + /** @hide */ + @VisibleForTesting + public int level; + + /** + * Return an identifier for this radio chain. This is an arbitrary ID which is consistent for + * the same device. + * + * @return The radio chain ID. + */ + public int getChainId() { + return chainId; + } + + /** + * Returns the detected signal level on this radio chain in dBm (aka RSSI). + * + * @return A signal level in dBm. + */ + public int getLevelDbm() { + return level; + } + + /** + * Construct a RadioChainInfo. + */ + public RadioChainInfo(int chainId, int level) { + this.chainId = chainId; + this.level = level; + } + + /** override comparator */ + @Override + public boolean equals(Object rhs) { + if (this == rhs) return true; + if (!(rhs instanceof RadioChainInfo)) { + return false; + } + RadioChainInfo chainInfo = (RadioChainInfo) rhs; + if (chainInfo == null) { + return false; + } + return chainId == chainInfo.chainId && level == chainInfo.level; + } + + /** override hash code */ + @Override + public int hashCode() { + return Objects.hash(chainId, level); + } + + + /** implement Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** + * implement Parcelable interface + * |flags| is ignored. + */ + @Override + public void writeToParcel(@NonNull Parcel out, int flags) { + out.writeInt(chainId); + out.writeInt(level); + } + + /** implement Parcelable interface */ + @NonNull public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + /** + * Caller is responsible for providing a valid parcel. + */ + @Override + public RadioChainInfo createFromParcel(Parcel in) { + return new RadioChainInfo(in.readInt(), in.readInt()); + } + + @Override + public RadioChainInfo[] newArray(int size) { + return new RadioChainInfo[size]; + } + }; +} diff --git a/wifi/java/android/net/wifi/nl80211/SingleScanSettings.java b/wifi/java/android/net/wifi/nl80211/SingleScanSettings.java new file mode 100644 index 000000000000..24b1854fbf6c --- /dev/null +++ b/wifi/java/android/net/wifi/nl80211/SingleScanSettings.java @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2016 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.nl80211; + +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Log; + +import java.util.ArrayList; +import java.util.Objects; + +/** + * SingleScanSettings for wificond + * + * @hide + */ +public class SingleScanSettings implements Parcelable { + private static final String TAG = "SingleScanSettings"; + + public int scanType; + public ArrayList channelSettings; + public ArrayList hiddenNetworks; + + /** public constructor */ + public SingleScanSettings() { } + + /** override comparator */ + @Override + public boolean equals(Object rhs) { + if (this == rhs) return true; + if (!(rhs instanceof SingleScanSettings)) { + return false; + } + SingleScanSettings settings = (SingleScanSettings) rhs; + if (settings == null) { + return false; + } + return scanType == settings.scanType + && channelSettings.equals(settings.channelSettings) + && hiddenNetworks.equals(settings.hiddenNetworks); + } + + /** override hash code */ + @Override + public int hashCode() { + return Objects.hash(scanType, channelSettings, hiddenNetworks); + } + + + /** implement Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + private static boolean isValidScanType(int scanType) { + return scanType == IWifiScannerImpl.SCAN_TYPE_LOW_SPAN + || scanType == IWifiScannerImpl.SCAN_TYPE_LOW_POWER + || scanType == IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY; + } + + /** + * implement Parcelable interface + * |flags| is ignored. + */ + @Override + public void writeToParcel(Parcel out, int flags) { + if (!isValidScanType(scanType)) { + Log.wtf(TAG, "Invalid scan type " + scanType); + } + out.writeInt(scanType); + out.writeTypedList(channelSettings); + out.writeTypedList(hiddenNetworks); + } + + /** implement Parcelable interface */ + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + /** + * Caller is responsible for providing a valid parcel. + */ + @Override + public SingleScanSettings createFromParcel(Parcel in) { + SingleScanSettings result = new SingleScanSettings(); + result.scanType = in.readInt(); + if (!isValidScanType(result.scanType)) { + Log.wtf(TAG, "Invalid scan type " + result.scanType); + } + result.channelSettings = new ArrayList(); + in.readTypedList(result.channelSettings, ChannelSettings.CREATOR); + result.hiddenNetworks = new ArrayList(); + in.readTypedList(result.hiddenNetworks, HiddenNetwork.CREATOR); + if (in.dataAvail() != 0) { + Log.e(TAG, "Found trailing data after parcel parsing."); + } + return result; + } + + @Override + public SingleScanSettings[] newArray(int size) { + return new SingleScanSettings[size]; + } + }; +} diff --git a/wifi/java/android/net/wifi/nl80211/WifiNl80211Manager.java b/wifi/java/android/net/wifi/nl80211/WifiNl80211Manager.java new file mode 100644 index 000000000000..3215246a9c1f --- /dev/null +++ b/wifi/java/android/net/wifi/nl80211/WifiNl80211Manager.java @@ -0,0 +1,1287 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.nl80211; + +import android.annotation.CallbackExecutor; +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.annotation.SystemService; +import android.app.AlarmManager; +import android.content.Context; +import android.net.wifi.SoftApInfo; +import android.net.wifi.WifiAnnotations; +import android.net.wifi.WifiScanner; +import android.os.Binder; +import android.os.Handler; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.os.SystemClock; +import android.util.Log; + +import com.android.internal.annotations.VisibleForTesting; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * This class encapsulates the interface the wificond daemon presents to the Wi-Fi framework - used + * to encapsulate the Wi-Fi 80211nl management interface. The + * interface is only for use by the Wi-Fi framework and access is protected by SELinux permissions. + * + * @hide + */ +@SystemApi +@SystemService(Context.WIFI_NL80211_SERVICE) +public class WifiNl80211Manager { + private static final String TAG = "WifiNl80211Manager"; + private boolean mVerboseLoggingEnabled = false; + + /** + * The {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} + * timeout, in milliseconds, after which + * {@link SendMgmtFrameCallback#onFailure(int)} will be called with reason + * {@link #SEND_MGMT_FRAME_ERROR_TIMEOUT}. + */ + private static final int SEND_MGMT_FRAME_TIMEOUT_MS = 1000; + + private static final String TIMEOUT_ALARM_TAG = TAG + " Send Management Frame Timeout"; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"SCAN_TYPE_"}, + value = {SCAN_TYPE_SINGLE_SCAN, + SCAN_TYPE_PNO_SCAN}) + public @interface ScanResultType {} + + /** + * Specifies a scan type: single scan initiated by the framework. Can be used in + * {@link #getScanResults(String, int)} to specify the type of scan result to fetch. + */ + public static final int SCAN_TYPE_SINGLE_SCAN = 0; + + /** + * Specifies a scan type: PNO scan. Can be used in {@link #getScanResults(String, int)} to + * specify the type of scan result to fetch. + */ + public static final int SCAN_TYPE_PNO_SCAN = 1; + + private AlarmManager mAlarmManager; + private Handler mEventHandler; + + // Cached wificond binder handlers. + private IWificond mWificond; + private HashMap mClientInterfaces = new HashMap<>(); + private HashMap mApInterfaces = new HashMap<>(); + private HashMap mWificondScanners = new HashMap<>(); + private HashMap mScanEventHandlers = new HashMap<>(); + private HashMap mPnoScanEventHandlers = new HashMap<>(); + private HashMap mApInterfaceListeners = new HashMap<>(); + private Runnable mDeathEventHandler; + /** + * Ensures that no more than one sendMgmtFrame operation runs concurrently. + */ + private AtomicBoolean mSendMgmtFrameInProgress = new AtomicBoolean(false); + + /** + * Interface used when waiting for scans to be completed (with results). + */ + public interface ScanEventCallback { + /** + * Called when scan results are available. Scans results should then be obtained from + * {@link #getScanResults(String, int)}. + */ + void onScanResultReady(); + + /** + * Called when a scan has failed. + */ + void onScanFailed(); + } + + /** + * Interface for a callback to provide information about PNO scan request requested with + * {@link #startPnoScan(String, PnoSettings, Executor, PnoScanRequestCallback)}. Note that the + * callback are for the status of the request - not the scan itself. The results of the scan + * are returned with {@link ScanEventCallback}. + */ + public interface PnoScanRequestCallback { + /** + * Called when a PNO scan request has been successfully submitted. + */ + void onPnoRequestSucceeded(); + + /** + * Called when a PNO scan request fails. + */ + void onPnoRequestFailed(); + } + + private class ScanEventHandler extends IScanEvent.Stub { + private Executor mExecutor; + private ScanEventCallback mCallback; + + ScanEventHandler(@NonNull Executor executor, @NonNull ScanEventCallback callback) { + mExecutor = executor; + mCallback = callback; + } + + @Override + public void OnScanResultReady() { + Log.d(TAG, "Scan result ready event"); + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mCallback.onScanResultReady()); + } + + @Override + public void OnScanFailed() { + Log.d(TAG, "Scan failed event"); + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mCallback.onScanFailed()); + } + } + + /** + * Result of a signal poll requested using {@link #signalPoll(String)}. + */ + public static class SignalPollResult { + /** @hide */ + public SignalPollResult(int currentRssiDbm, int txBitrateMbps, int rxBitrateMbps, + int associationFrequencyMHz) { + this.currentRssiDbm = currentRssiDbm; + this.txBitrateMbps = txBitrateMbps; + this.rxBitrateMbps = rxBitrateMbps; + this.associationFrequencyMHz = associationFrequencyMHz; + } + + /** + * RSSI value in dBM. + */ + public final int currentRssiDbm; + + /** + * Transmission bit rate in Mbps. + */ + public final int txBitrateMbps; + + /** + * Last received packet bit rate in Mbps. + */ + public final int rxBitrateMbps; + + /** + * Association frequency in MHz. + */ + public final int associationFrequencyMHz; + } + + /** + * Transmission counters obtained using {@link #getTxPacketCounters(String)}. + */ + public static class TxPacketCounters { + /** @hide */ + public TxPacketCounters(int txPacketSucceeded, int txPacketFailed) { + this.txPacketSucceeded = txPacketSucceeded; + this.txPacketFailed = txPacketFailed; + } + + /** + * Number of successfully transmitted packets. + */ + public final int txPacketSucceeded; + + /** + * Number of packet transmission failures. + */ + public final int txPacketFailed; + } + + /** + * Callbacks for SoftAp interface registered using + * {@link #registerApCallback(String, Executor, SoftApCallback)}. + */ + public interface SoftApCallback { + /** + * Invoked when there is a fatal failure and the SoftAp is shutdown. + */ + void onFailure(); + + /** + * Invoked when there is a change in the associated station (STA). + * @param client Information about the client whose status has changed. + * @param isConnected Indication as to whether the client is connected (true), or + * disconnected (false). + */ + void onConnectedClientsChanged(@NonNull NativeWifiClient client, boolean isConnected); + + /** + * Invoked when a channel switch event happens - i.e. the SoftAp is moved to a different + * channel. Also called on initial registration. + * @param frequencyMhz The new frequency of the SoftAp. A value of 0 is invalid and is an + * indication that the SoftAp is not enabled. + * @param bandwidth The new bandwidth of the SoftAp. + */ + void onSoftApChannelSwitched(int frequencyMhz, @WifiAnnotations.Bandwidth int bandwidth); + } + + /** + * Callback to notify the results of a + * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} call. + * Note: no callbacks will be triggered if the interface dies while sending a frame. + */ + public interface SendMgmtFrameCallback { + /** + * Called when the management frame was successfully sent and ACKed by the recipient. + * @param elapsedTimeMs The elapsed time between when the management frame was sent and when + * the ACK was processed, in milliseconds, as measured by wificond. + * This includes the time that the send frame spent queuing before it + * was sent, any firmware retries, and the time the received ACK spent + * queuing before it was processed. + */ + void onAck(int elapsedTimeMs); + + /** + * Called when the send failed. + * @param reason The error code for the failure. + */ + void onFailure(@SendMgmtFrameError int reason); + } + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"SEND_MGMT_FRAME_ERROR_"}, + value = {SEND_MGMT_FRAME_ERROR_UNKNOWN, + SEND_MGMT_FRAME_ERROR_MCS_UNSUPPORTED, + SEND_MGMT_FRAME_ERROR_NO_ACK, + SEND_MGMT_FRAME_ERROR_TIMEOUT, + SEND_MGMT_FRAME_ERROR_ALREADY_STARTED}) + public @interface SendMgmtFrameError {} + + // Send management frame error codes + + /** + * Unknown error occurred during call to + * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)}. + */ + public static final int SEND_MGMT_FRAME_ERROR_UNKNOWN = 1; + + /** + * Specifying the MCS rate in + * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} is not + * supported by this device. + */ + public static final int SEND_MGMT_FRAME_ERROR_MCS_UNSUPPORTED = 2; + + /** + * Driver reported that no ACK was received for the frame transmitted using + * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)}. + */ + public static final int SEND_MGMT_FRAME_ERROR_NO_ACK = 3; + + /** + * Error code for when the driver fails to report on the status of the frame sent by + * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} + * after {@link #SEND_MGMT_FRAME_TIMEOUT_MS} milliseconds. + */ + public static final int SEND_MGMT_FRAME_ERROR_TIMEOUT = 4; + + /** + * An existing call to + * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} + * is in progress. Another frame cannot be sent until the first call completes. + */ + public static final int SEND_MGMT_FRAME_ERROR_ALREADY_STARTED = 5; + + /** @hide */ + public WifiNl80211Manager(Context context) { + mAlarmManager = context.getSystemService(AlarmManager.class); + mEventHandler = new Handler(context.getMainLooper()); + } + + /** @hide */ + @VisibleForTesting + public WifiNl80211Manager(Context context, IWificond wificond) { + this(context); + mWificond = wificond; + } + + private class PnoScanEventHandler extends IPnoScanEvent.Stub { + private Executor mExecutor; + private ScanEventCallback mCallback; + + PnoScanEventHandler(@NonNull Executor executor, @NonNull ScanEventCallback callback) { + mExecutor = executor; + mCallback = callback; + } + + @Override + public void OnPnoNetworkFound() { + Log.d(TAG, "Pno scan result event"); + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mCallback.onScanResultReady()); + } + + @Override + public void OnPnoScanFailed() { + Log.d(TAG, "Pno Scan failed event"); + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mCallback.onScanFailed()); + } + } + + /** + * Listener for AP Interface events. + */ + private class ApInterfaceEventCallback extends IApInterfaceEventCallback.Stub { + private Executor mExecutor; + private SoftApCallback mSoftApListener; + + ApInterfaceEventCallback(Executor executor, SoftApCallback listener) { + mExecutor = executor; + mSoftApListener = listener; + } + + @Override + public void onConnectedClientsChanged(NativeWifiClient client, boolean isConnected) { + if (mVerboseLoggingEnabled) { + Log.d(TAG, "onConnectedClientsChanged called with " + + client.getMacAddress() + " isConnected: " + isConnected); + } + + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mSoftApListener.onConnectedClientsChanged(client, isConnected)); + } + + @Override + public void onSoftApChannelSwitched(int frequency, int bandwidth) { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mSoftApListener.onSoftApChannelSwitched(frequency, + toFrameworkBandwidth(bandwidth))); + } + + private @WifiAnnotations.Bandwidth int toFrameworkBandwidth(int bandwidth) { + switch(bandwidth) { + case IApInterfaceEventCallback.BANDWIDTH_INVALID: + return SoftApInfo.CHANNEL_WIDTH_INVALID; + case IApInterfaceEventCallback.BANDWIDTH_20_NOHT: + return SoftApInfo.CHANNEL_WIDTH_20MHZ_NOHT; + case IApInterfaceEventCallback.BANDWIDTH_20: + return SoftApInfo.CHANNEL_WIDTH_20MHZ; + case IApInterfaceEventCallback.BANDWIDTH_40: + return SoftApInfo.CHANNEL_WIDTH_40MHZ; + case IApInterfaceEventCallback.BANDWIDTH_80: + return SoftApInfo.CHANNEL_WIDTH_80MHZ; + case IApInterfaceEventCallback.BANDWIDTH_80P80: + return SoftApInfo.CHANNEL_WIDTH_80MHZ_PLUS_MHZ; + case IApInterfaceEventCallback.BANDWIDTH_160: + return SoftApInfo.CHANNEL_WIDTH_160MHZ; + default: + return SoftApInfo.CHANNEL_WIDTH_INVALID; + } + } + } + + /** + * Callback triggered by wificond. + */ + private class SendMgmtFrameEvent extends ISendMgmtFrameEvent.Stub { + private Executor mExecutor; + private SendMgmtFrameCallback mCallback; + private AlarmManager.OnAlarmListener mTimeoutCallback; + /** + * ensures that mCallback is only called once + */ + private boolean mWasCalled; + + private void runIfFirstCall(Runnable r) { + if (mWasCalled) return; + mWasCalled = true; + + mSendMgmtFrameInProgress.set(false); + r.run(); + } + + SendMgmtFrameEvent(@NonNull Executor executor, @NonNull SendMgmtFrameCallback callback) { + mExecutor = executor; + mCallback = callback; + // called in main thread + mTimeoutCallback = () -> runIfFirstCall(() -> { + if (mVerboseLoggingEnabled) { + Log.e(TAG, "Timed out waiting for ACK"); + } + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mCallback.onFailure(SEND_MGMT_FRAME_ERROR_TIMEOUT)); + }); + mWasCalled = false; + + mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, + SystemClock.elapsedRealtime() + SEND_MGMT_FRAME_TIMEOUT_MS, + TIMEOUT_ALARM_TAG, mTimeoutCallback, mEventHandler); + } + + // called in binder thread + @Override + public void OnAck(int elapsedTimeMs) { + // post to main thread + mEventHandler.post(() -> runIfFirstCall(() -> { + mAlarmManager.cancel(mTimeoutCallback); + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mCallback.onAck(elapsedTimeMs)); + })); + } + + // called in binder thread + @Override + public void OnFailure(int reason) { + // post to main thread + mEventHandler.post(() -> runIfFirstCall(() -> { + mAlarmManager.cancel(mTimeoutCallback); + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mCallback.onFailure(reason)); + })); + } + } + + /** + * Called by the binder subsystem upon remote object death. + * Invoke all the register death handlers and clear state. + * @hide + */ + @VisibleForTesting + public void binderDied() { + mEventHandler.post(() -> { + Log.e(TAG, "Wificond died!"); + clearState(); + // Invalidate the global wificond handle on death. Will be refreshed + // on the next setup call. + mWificond = null; + if (mDeathEventHandler != null) { + mDeathEventHandler.run(); + } + }); + } + + /** + * Enable or disable verbose logging of the WifiNl80211Manager module. + * @param enable True to enable verbose logging. False to disable verbose logging. + */ + public void enableVerboseLogging(boolean enable) { + mVerboseLoggingEnabled = enable; + } + + /** + * Register a death notification for the WifiNl80211Manager which acts as a proxy for the + * wificond daemon (i.e. the death listener will be called when and if the wificond daemon + * dies). + * + * @param deathEventHandler A {@link Runnable} to be called whenever the wificond daemon dies. + */ + public void setOnServiceDeadCallback(@NonNull Runnable deathEventHandler) { + if (mDeathEventHandler != null) { + Log.e(TAG, "Death handler already present"); + } + mDeathEventHandler = deathEventHandler; + } + + /** + * Helper method to retrieve the global wificond handle and register for + * death notifications. + */ + private boolean retrieveWificondAndRegisterForDeath() { + if (mWificond != null) { + if (mVerboseLoggingEnabled) { + Log.d(TAG, "Wificond handle already retrieved"); + } + // We already have a wificond handle. + return true; + } + IBinder binder = ServiceManager.getService(Context.WIFI_NL80211_SERVICE); + mWificond = IWificond.Stub.asInterface(binder); + if (mWificond == null) { + Log.e(TAG, "Failed to get reference to wificond"); + return false; + } + try { + mWificond.asBinder().linkToDeath(() -> binderDied(), 0); + } catch (RemoteException e) { + Log.e(TAG, "Failed to register death notification for wificond"); + // The remote has already died. + return false; + } + return true; + } + + /** + * Set up an interface for client (STA) mode. + * + * @param ifaceName Name of the interface to configure. + * @param executor The Executor on which to execute the callbacks. + * @param scanCallback A callback for framework initiated scans. + * @param pnoScanCallback A callback for PNO (offloaded) scans. + * @return true on success. + */ + public boolean setupInterfaceForClientMode(@NonNull String ifaceName, + @NonNull @CallbackExecutor Executor executor, + @NonNull ScanEventCallback scanCallback, @NonNull ScanEventCallback pnoScanCallback) { + Log.d(TAG, "Setting up interface for client mode"); + if (!retrieveWificondAndRegisterForDeath()) { + return false; + } + + if (scanCallback == null || pnoScanCallback == null || executor == null) { + Log.e(TAG, "setupInterfaceForClientMode invoked with null callbacks"); + return false; + } + + IClientInterface clientInterface = null; + try { + clientInterface = mWificond.createClientInterface(ifaceName); + } catch (RemoteException e1) { + Log.e(TAG, "Failed to get IClientInterface due to remote exception"); + return false; + } + + if (clientInterface == null) { + Log.e(TAG, "Could not get IClientInterface instance from wificond"); + return false; + } + Binder.allowBlocking(clientInterface.asBinder()); + + // Refresh Handlers + mClientInterfaces.put(ifaceName, clientInterface); + try { + IWifiScannerImpl wificondScanner = clientInterface.getWifiScannerImpl(); + if (wificondScanner == null) { + Log.e(TAG, "Failed to get WificondScannerImpl"); + return false; + } + mWificondScanners.put(ifaceName, wificondScanner); + Binder.allowBlocking(wificondScanner.asBinder()); + ScanEventHandler scanEventHandler = new ScanEventHandler(executor, scanCallback); + mScanEventHandlers.put(ifaceName, scanEventHandler); + wificondScanner.subscribeScanEvents(scanEventHandler); + PnoScanEventHandler pnoScanEventHandler = new PnoScanEventHandler(executor, + pnoScanCallback); + mPnoScanEventHandlers.put(ifaceName, pnoScanEventHandler); + wificondScanner.subscribePnoScanEvents(pnoScanEventHandler); + } catch (RemoteException e) { + Log.e(TAG, "Failed to refresh wificond scanner due to remote exception"); + } + + return true; + } + + /** + * Tear down a specific client (STA) interface configured using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}. + * + * @param ifaceName Name of the interface to tear down. + * @return Returns true on success, false on failure (e.g. when called before an interface was + * set up). + */ + public boolean tearDownClientInterface(@NonNull String ifaceName) { + if (getClientInterface(ifaceName) == null) { + Log.e(TAG, "No valid wificond client interface handler"); + return false; + } + try { + IWifiScannerImpl scannerImpl = mWificondScanners.get(ifaceName); + if (scannerImpl != null) { + scannerImpl.unsubscribeScanEvents(); + scannerImpl.unsubscribePnoScanEvents(); + } + } catch (RemoteException e) { + Log.e(TAG, "Failed to unsubscribe wificond scanner due to remote exception"); + return false; + } + + if (mWificond == null) { + Log.e(TAG, "Reference to wifiCond is null"); + return false; + } + + boolean success; + try { + success = mWificond.tearDownClientInterface(ifaceName); + } catch (RemoteException e1) { + Log.e(TAG, "Failed to teardown client interface due to remote exception"); + return false; + } + if (!success) { + Log.e(TAG, "Failed to teardown client interface"); + return false; + } + + mClientInterfaces.remove(ifaceName); + mWificondScanners.remove(ifaceName); + mScanEventHandlers.remove(ifaceName); + mPnoScanEventHandlers.remove(ifaceName); + return true; + } + + /** + * Set up interface as a Soft AP. + * + * @param ifaceName Name of the interface to configure. + * @return true on success. + */ + public boolean setupInterfaceForSoftApMode(@NonNull String ifaceName) { + Log.d(TAG, "Setting up interface for soft ap mode"); + if (!retrieveWificondAndRegisterForDeath()) { + return false; + } + + IApInterface apInterface = null; + try { + apInterface = mWificond.createApInterface(ifaceName); + } catch (RemoteException e1) { + Log.e(TAG, "Failed to get IApInterface due to remote exception"); + return false; + } + + if (apInterface == null) { + Log.e(TAG, "Could not get IApInterface instance from wificond"); + return false; + } + Binder.allowBlocking(apInterface.asBinder()); + + // Refresh Handlers + mApInterfaces.put(ifaceName, apInterface); + return true; + } + + /** + * Tear down a Soft AP interface configured using + * {@link #setupInterfaceForSoftApMode(String)}. + * + * @param ifaceName Name of the interface to tear down. + * @return Returns true on success, false on failure (e.g. when called before an interface was + * set up). + */ + public boolean tearDownSoftApInterface(@NonNull String ifaceName) { + if (getApInterface(ifaceName) == null) { + Log.e(TAG, "No valid wificond ap interface handler"); + return false; + } + + if (mWificond == null) { + Log.e(TAG, "Reference to wifiCond is null"); + return false; + } + + boolean success; + try { + success = mWificond.tearDownApInterface(ifaceName); + } catch (RemoteException e1) { + Log.e(TAG, "Failed to teardown AP interface due to remote exception"); + return false; + } + if (!success) { + Log.e(TAG, "Failed to teardown AP interface"); + return false; + } + mApInterfaces.remove(ifaceName); + mApInterfaceListeners.remove(ifaceName); + return true; + } + + /** + * Tear down all interfaces, whether clients (STA) or Soft AP. + * + * @return Returns true on success. + */ + public boolean tearDownInterfaces() { + Log.d(TAG, "tearing down interfaces in wificond"); + // Explicitly refresh the wificodn handler because |tearDownInterfaces()| + // could be used to cleanup before we setup any interfaces. + if (!retrieveWificondAndRegisterForDeath()) { + return false; + } + + try { + for (Map.Entry entry : mWificondScanners.entrySet()) { + entry.getValue().unsubscribeScanEvents(); + entry.getValue().unsubscribePnoScanEvents(); + } + mWificond.tearDownInterfaces(); + clearState(); + return true; + } catch (RemoteException e) { + Log.e(TAG, "Failed to tear down interfaces due to remote exception"); + } + + return false; + } + + /** Helper function to look up the interface handle using name */ + private IClientInterface getClientInterface(@NonNull String ifaceName) { + return mClientInterfaces.get(ifaceName); + } + + /** + * Request signal polling. + * + * @param ifaceName Name of the interface on which to poll. The interface must have been + * already set up using + *{@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} + * or {@link #setupInterfaceForSoftApMode(String)}. + * + * @return A {@link SignalPollResult} object containing interface statistics, or a null on + * error (e.g. the interface hasn't been set up yet). + */ + @Nullable public SignalPollResult signalPoll(@NonNull String ifaceName) { + IClientInterface iface = getClientInterface(ifaceName); + if (iface == null) { + Log.e(TAG, "No valid wificond client interface handler"); + return null; + } + + int[] resultArray; + try { + resultArray = iface.signalPoll(); + if (resultArray == null || resultArray.length != 4) { + Log.e(TAG, "Invalid signal poll result from wificond"); + return null; + } + } catch (RemoteException e) { + Log.e(TAG, "Failed to do signal polling due to remote exception"); + return null; + } + return new SignalPollResult(resultArray[0], resultArray[1], resultArray[3], resultArray[2]); + } + + /** + * Get current transmit (Tx) packet counters of the specified interface. The interface must + * have been already set up using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} + * or {@link #setupInterfaceForSoftApMode(String)}. + * + * @param ifaceName Name of the interface. + * @return {@link TxPacketCounters} of the current interface or null on error (e.g. when + * called before the interface has been set up). + */ + @Nullable public TxPacketCounters getTxPacketCounters(@NonNull String ifaceName) { + IClientInterface iface = getClientInterface(ifaceName); + if (iface == null) { + Log.e(TAG, "No valid wificond client interface handler"); + return null; + } + + int[] resultArray; + try { + resultArray = iface.getPacketCounters(); + if (resultArray == null || resultArray.length != 2) { + Log.e(TAG, "Invalid signal poll result from wificond"); + return null; + } + } catch (RemoteException e) { + Log.e(TAG, "Failed to do signal polling due to remote exception"); + return null; + } + return new TxPacketCounters(resultArray[0], resultArray[1]); + } + + /** Helper function to look up the scanner impl handle using name */ + private IWifiScannerImpl getScannerImpl(@NonNull String ifaceName) { + return mWificondScanners.get(ifaceName); + } + + /** + * Fetch the latest scan results of the indicated type for the specified interface. Note that + * this method fetches the latest results - it does not initiate a scan. Initiating a scan can + * be done using {@link #startScan(String, int, Set, List)} or + * {@link #startPnoScan(String, PnoSettings, Executor, PnoScanRequestCallback)}. + * + * Note: The interface must have been already set up using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} + * or {@link #setupInterfaceForSoftApMode(String)}. + * + * @param ifaceName Name of the interface. + * @param scanType The type of scan result to be returned, can be + * {@link #SCAN_TYPE_SINGLE_SCAN} or {@link #SCAN_TYPE_PNO_SCAN}. + * @return Returns an array of {@link NativeScanResult} or an empty array on failure (e.g. when + * called before the interface has been set up). + */ + @NonNull public List getScanResults(@NonNull String ifaceName, + @ScanResultType int scanType) { + IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); + if (scannerImpl == null) { + Log.e(TAG, "No valid wificond scanner interface handler"); + return new ArrayList<>(); + } + List results = null; + try { + if (scanType == SCAN_TYPE_SINGLE_SCAN) { + results = Arrays.asList(scannerImpl.getScanResults()); + } else { + results = Arrays.asList(scannerImpl.getPnoScanResults()); + } + } catch (RemoteException e1) { + Log.e(TAG, "Failed to create ScanDetail ArrayList"); + } + if (results == null) { + results = new ArrayList<>(); + } + if (mVerboseLoggingEnabled) { + Log.d(TAG, "get " + results.size() + " scan results from wificond"); + } + + return results; + } + + /** + * Return scan type for the parcelable {@link SingleScanSettings} + */ + private static int getScanType(@WifiAnnotations.ScanType int scanType) { + switch (scanType) { + case WifiScanner.SCAN_TYPE_LOW_LATENCY: + return IWifiScannerImpl.SCAN_TYPE_LOW_SPAN; + case WifiScanner.SCAN_TYPE_LOW_POWER: + return IWifiScannerImpl.SCAN_TYPE_LOW_POWER; + case WifiScanner.SCAN_TYPE_HIGH_ACCURACY: + return IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY; + default: + throw new IllegalArgumentException("Invalid scan type " + scanType); + } + } + + /** + * Start a scan using the specified parameters. A scan is an asynchronous operation. The + * result of the operation is returned in the {@link ScanEventCallback} registered when + * setting up an interface using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}. + * The latest scans can be obtained using {@link #getScanResults(String, int)} and using a + * {@link #SCAN_TYPE_SINGLE_SCAN} for the {@code scanType}. + * + * Note: The interface must have been already set up using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} + * or {@link #setupInterfaceForSoftApMode(String)}. + * + * @param ifaceName Name of the interface on which to initiate the scan. + * @param scanType Type of scan to perform, can be any of + * {@link WifiScanner#SCAN_TYPE_HIGH_ACCURACY}, {@link WifiScanner#SCAN_TYPE_LOW_POWER}, or + * {@link WifiScanner#SCAN_TYPE_LOW_LATENCY}. + * @param freqs list of frequencies to scan for, if null scan all supported channels. + * @param hiddenNetworkSSIDs List of hidden networks to be scanned for, a null indicates that + * no hidden frequencies will be scanned for. + * @return Returns true on success, false on failure (e.g. when called before the interface + * has been set up). + */ + public boolean startScan(@NonNull String ifaceName, @WifiAnnotations.ScanType int scanType, + @Nullable Set freqs, @Nullable List hiddenNetworkSSIDs) { + IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); + if (scannerImpl == null) { + Log.e(TAG, "No valid wificond scanner interface handler"); + return false; + } + SingleScanSettings settings = new SingleScanSettings(); + try { + settings.scanType = getScanType(scanType); + } catch (IllegalArgumentException e) { + Log.e(TAG, "Invalid scan type ", e); + return false; + } + settings.channelSettings = new ArrayList<>(); + settings.hiddenNetworks = new ArrayList<>(); + + if (freqs != null) { + for (Integer freq : freqs) { + ChannelSettings channel = new ChannelSettings(); + channel.frequency = freq; + settings.channelSettings.add(channel); + } + } + if (hiddenNetworkSSIDs != null) { + for (byte[] ssid : hiddenNetworkSSIDs) { + HiddenNetwork network = new HiddenNetwork(); + network.ssid = ssid; + + // settings.hiddenNetworks is expected to be very small, so this shouldn't cause + // any performance issues. + if (!settings.hiddenNetworks.contains(network)) { + settings.hiddenNetworks.add(network); + } + } + } + + try { + return scannerImpl.scan(settings); + } catch (RemoteException e1) { + Log.e(TAG, "Failed to request scan due to remote exception"); + } + return false; + } + + /** + * Request a PNO (Preferred Network Offload). The offload request and the scans are asynchronous + * operations. The result of the request are returned in the {@code callback} parameter which + * is an {@link PnoScanRequestCallback}. The scan results are are return in the + * {@link ScanEventCallback} which is registered when setting up an interface using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}. + * The latest PNO scans can be obtained using {@link #getScanResults(String, int)} with the + * {@code scanType} set to {@link #SCAN_TYPE_PNO_SCAN}. + * + * Note: The interface must have been already set up using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} + * or {@link #setupInterfaceForSoftApMode(String)}. + * + * @param ifaceName Name of the interface on which to request a PNO. + * @param pnoSettings PNO scan configuration. + * @param executor The Executor on which to execute the callback. + * @param callback Callback for the results of the offload request. + * @return true on success, false on failure (e.g. when called before the interface has been set + * up). + */ + public boolean startPnoScan(@NonNull String ifaceName, @NonNull PnoSettings pnoSettings, + @NonNull @CallbackExecutor Executor executor, + @NonNull PnoScanRequestCallback callback) { + IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); + if (scannerImpl == null) { + Log.e(TAG, "No valid wificond scanner interface handler"); + return false; + } + + if (callback == null || executor == null) { + Log.e(TAG, "startPnoScan called with a null callback"); + return false; + } + + try { + boolean success = scannerImpl.startPnoScan(pnoSettings); + if (success) { + executor.execute(callback::onPnoRequestSucceeded); + } else { + executor.execute(callback::onPnoRequestFailed); + } + return success; + } catch (RemoteException e1) { + Log.e(TAG, "Failed to start pno scan due to remote exception"); + } + return false; + } + + /** + * Stop PNO scan configured with + * {@link #startPnoScan(String, PnoSettings, Executor, PnoScanRequestCallback)}. + * + * Note: The interface must have been already set up using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} + * or {@link #setupInterfaceForSoftApMode(String)}. + * + * @param ifaceName Name of the interface on which the PNO scan was configured. + * @return true on success, false on failure (e.g. when called before the interface has been + * set up). + */ + public boolean stopPnoScan(@NonNull String ifaceName) { + IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); + if (scannerImpl == null) { + Log.e(TAG, "No valid wificond scanner interface handler"); + return false; + } + try { + return scannerImpl.stopPnoScan(); + } catch (RemoteException e1) { + Log.e(TAG, "Failed to stop pno scan due to remote exception"); + } + return false; + } + + /** + * Abort ongoing single scan started with {@link #startScan(String, int, Set, List)}. No failure + * callback, e.g. {@link ScanEventCallback#onScanFailed()}, is triggered by this operation. + * + * Note: The interface must have been already set up using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} + * or {@link #setupInterfaceForSoftApMode(String)}. If the interface has not been set up then + * this method has no impact. + * + * @param ifaceName Name of the interface on which the scan was started. + */ + public void abortScan(@NonNull String ifaceName) { + IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); + if (scannerImpl == null) { + Log.e(TAG, "No valid wificond scanner interface handler"); + return; + } + try { + scannerImpl.abortScan(); + } catch (RemoteException e1) { + Log.e(TAG, "Failed to request abortScan due to remote exception"); + } + } + + /** + * Query the list of valid frequencies (in MHz) for the provided band. + * The result depends on the on the country code that has been set. + * + * @param band as specified by one of the WifiScanner.WIFI_BAND_* constants. + * The following bands are supported {@link @WifiScanner.WifiBandBasic}: + * WifiScanner.WIFI_BAND_24_GHZ + * WifiScanner.WIFI_BAND_5_GHZ + * WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY + * WifiScanner.WIFI_BAND_6_GHZ + * @return frequencies vector of valid frequencies (MHz), or an empty array for error. + * @throws IllegalArgumentException if band is not recognized. + */ + public @NonNull int[] getChannelsMhzForBand(@WifiAnnotations.WifiBandBasic int band) { + if (mWificond == null) { + Log.e(TAG, "No valid wificond scanner interface handler"); + return new int[0]; + } + int[] result = null; + try { + switch (band) { + case WifiScanner.WIFI_BAND_24_GHZ: + result = mWificond.getAvailable2gChannels(); + break; + case WifiScanner.WIFI_BAND_5_GHZ: + result = mWificond.getAvailable5gNonDFSChannels(); + break; + case WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY: + result = mWificond.getAvailableDFSChannels(); + break; + case WifiScanner.WIFI_BAND_6_GHZ: + result = mWificond.getAvailable6gChannels(); + break; + default: + throw new IllegalArgumentException("unsupported band " + band); + } + } catch (RemoteException e1) { + Log.e(TAG, "Failed to request getChannelsForBand due to remote exception"); + } + if (result == null) { + result = new int[0]; + } + return result; + } + + /** Helper function to look up the interface handle using name */ + private IApInterface getApInterface(@NonNull String ifaceName) { + return mApInterfaces.get(ifaceName); + } + + /** + * Get the device phy capabilities for a given interface. + * + * Note: The interface must have been already set up using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} + * or {@link #setupInterfaceForSoftApMode(String)}. + * + * @return DeviceWiphyCapabilities or null on error (e.g. when called on an interface which has + * not been set up). + */ + @Nullable public DeviceWiphyCapabilities getDeviceWiphyCapabilities(@NonNull String ifaceName) { + if (mWificond == null) { + Log.e(TAG, "Can not query for device wiphy capabilities at this time"); + return null; + } + + try { + return mWificond.getDeviceWiphyCapabilities(ifaceName); + } catch (RemoteException e) { + return null; + } + } + + /** + * Register the provided callback handler for SoftAp events. The interface must first be created + * using {@link #setupInterfaceForSoftApMode(String)}. The callback registration is valid until + * the interface is deleted using {@link #tearDownSoftApInterface(String)} (no deregistration + * method is provided). + *

    + * Note that only one callback can be registered at a time - any registration overrides previous + * registrations. + * + * @param ifaceName Name of the interface on which to register the callback. + * @param executor The Executor on which to execute the callbacks. + * @param callback Callback for AP events. + * @return true on success, false on failure (e.g. when called on an interface which has not + * been set up). + */ + public boolean registerApCallback(@NonNull String ifaceName, + @NonNull @CallbackExecutor Executor executor, + @NonNull SoftApCallback callback) { + IApInterface iface = getApInterface(ifaceName); + if (iface == null) { + Log.e(TAG, "No valid ap interface handler"); + return false; + } + + if (callback == null || executor == null) { + Log.e(TAG, "registerApCallback called with a null callback"); + return false; + } + + try { + IApInterfaceEventCallback wificondCallback = new ApInterfaceEventCallback(executor, + callback); + mApInterfaceListeners.put(ifaceName, wificondCallback); + boolean success = iface.registerCallback(wificondCallback); + if (!success) { + Log.e(TAG, "Failed to register ap callback."); + return false; + } + } catch (RemoteException e) { + Log.e(TAG, "Exception in registering AP callback: " + e); + return false; + } + return true; + } + + /** + * Send a management frame on the specified interface at the specified rate. Useful for probing + * the link with arbitrary frames. + * + * Note: The interface must have been already set up using + * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} + * or {@link #setupInterfaceForSoftApMode(String)}. + * + * @param ifaceName The interface on which to send the frame. + * @param frame The raw byte array of the management frame to tramit. + * @param mcs The MCS (modulation and coding scheme), i.e. rate, at which to transmit the + * frame. Specified per IEEE 802.11. + * @param executor The Executor on which to execute the callbacks. + * @param callback A {@link SendMgmtFrameCallback} callback for results of the operation. + */ + public void sendMgmtFrame(@NonNull String ifaceName, @NonNull byte[] frame, int mcs, + @NonNull @CallbackExecutor Executor executor, + @NonNull SendMgmtFrameCallback callback) { + + if (callback == null || executor == null) { + Log.e(TAG, "callback cannot be null!"); + return; + } + + if (frame == null) { + Log.e(TAG, "frame cannot be null!"); + executor.execute(() -> callback.onFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN)); + return; + } + + // TODO (b/112029045) validate mcs + IClientInterface clientInterface = getClientInterface(ifaceName); + if (clientInterface == null) { + Log.e(TAG, "No valid wificond client interface handler"); + executor.execute(() -> callback.onFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN)); + return; + } + + if (!mSendMgmtFrameInProgress.compareAndSet(false, true)) { + Log.e(TAG, "An existing management frame transmission is in progress!"); + executor.execute(() -> callback.onFailure(SEND_MGMT_FRAME_ERROR_ALREADY_STARTED)); + return; + } + + SendMgmtFrameEvent sendMgmtFrameEvent = new SendMgmtFrameEvent(executor, callback); + try { + clientInterface.SendMgmtFrame(frame, sendMgmtFrameEvent, mcs); + } catch (RemoteException e) { + Log.e(TAG, "Exception while starting link probe: " + e); + // Call sendMgmtFrameEvent.OnFailure() instead of callback.onFailure() so that + // sendMgmtFrameEvent can clean up internal state, such as cancelling the timer. + sendMgmtFrameEvent.OnFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN); + } + } + + /** + * Clear all internal handles. + */ + private void clearState() { + // Refresh handlers + mClientInterfaces.clear(); + mWificondScanners.clear(); + mPnoScanEventHandlers.clear(); + mScanEventHandlers.clear(); + mApInterfaces.clear(); + mApInterfaceListeners.clear(); + mSendMgmtFrameInProgress.set(false); + } + + /** + * OEM parsed security type + */ + public static class OemSecurityType { + /** The protocol defined in {@link android.net.wifi.WifiAnnotations.Protocol}. */ + public final @WifiAnnotations.Protocol int protocol; + /** + * Supported key management types defined + * in {@link android.net.wifi.WifiAnnotations.KeyMgmt}. + */ + @NonNull public final List keyManagement; + /** + * Supported pairwise cipher types defined + * in {@link android.net.wifi.WifiAnnotations.Cipher}. + */ + @NonNull public final List pairwiseCipher; + /** The group cipher type defined in {@link android.net.wifi.WifiAnnotations.Cipher}. */ + public final @WifiAnnotations.Cipher int groupCipher; + /** + * Default constructor for OemSecurityType + * + * @param protocol The protocol defined in + * {@link android.net.wifi.WifiAnnotations.Protocol}. + * @param keyManagement Supported key management types defined + * in {@link android.net.wifi.WifiAnnotations.KeyMgmt}. + * @param pairwiseCipher Supported pairwise cipher types defined + * in {@link android.net.wifi.WifiAnnotations.Cipher}. + * @param groupCipher The group cipher type defined + * in {@link android.net.wifi.WifiAnnotations.Cipher}. + */ + public OemSecurityType( + @WifiAnnotations.Protocol int protocol, + @NonNull List keyManagement, + @NonNull List pairwiseCipher, + @WifiAnnotations.Cipher int groupCipher) { + this.protocol = protocol; + this.keyManagement = (keyManagement != null) + ? keyManagement : new ArrayList(); + this.pairwiseCipher = (pairwiseCipher != null) + ? pairwiseCipher : new ArrayList(); + this.groupCipher = groupCipher; + } + } + + /** + * OEM information element parser for security types not parsed by the framework. + * + * The OEM method should use the method inputs {@code id}, {@code idExt}, and {@code bytes} + * to perform the parsing. The method should place the results in an OemSecurityType objct. + * + * @param id The information element id. + * @param idExt The information element extension id. This is valid only when id is + * the extension id, {@code 255}. + * @param bytes The raw bytes of information element data, 'Element ID' and 'Length' are + * stripped off already. + * @return an OemSecurityType object if this IE is parsed successfully, null otherwise. + */ + @Nullable public static OemSecurityType parseOemSecurityTypeElement( + int id, + int idExt, + @NonNull byte[] bytes) { + return null; + } +} diff --git a/wifi/java/android/net/wifi/wificond/ChannelSettings.java b/wifi/java/android/net/wifi/wificond/ChannelSettings.java deleted file mode 100644 index c2d65b581491..000000000000 --- a/wifi/java/android/net/wifi/wificond/ChannelSettings.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2016 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.wificond; - -import android.os.Parcel; -import android.os.Parcelable; -import android.util.Log; - -import java.util.Objects; - -/** - * ChannelSettings for wificond - * - * @hide - */ -public class ChannelSettings implements Parcelable { - private static final String TAG = "ChannelSettings"; - - public int frequency; - - /** public constructor */ - public ChannelSettings() { } - - /** override comparator */ - @Override - public boolean equals(Object rhs) { - if (this == rhs) return true; - if (!(rhs instanceof ChannelSettings)) { - return false; - } - ChannelSettings channel = (ChannelSettings) rhs; - if (channel == null) { - return false; - } - return frequency == channel.frequency; - } - - /** override hash code */ - @Override - public int hashCode() { - return Objects.hash(frequency); - } - - /** implement Parcelable interface */ - @Override - public int describeContents() { - return 0; - } - - /** - * implement Parcelable interface - * |flags| is ignored. - **/ - @Override - public void writeToParcel(Parcel out, int flags) { - out.writeInt(frequency); - } - - /** implement Parcelable interface */ - public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - /** - * Caller is responsible for providing a valid parcel. - */ - @Override - public ChannelSettings createFromParcel(Parcel in) { - ChannelSettings result = new ChannelSettings(); - result.frequency = in.readInt(); - if (in.dataAvail() != 0) { - Log.e(TAG, "Found trailing data after parcel parsing."); - } - - return result; - } - - @Override - public ChannelSettings[] newArray(int size) { - return new ChannelSettings[size]; - } - }; -} diff --git a/wifi/java/android/net/wifi/wificond/DeviceWiphyCapabilities.java b/wifi/java/android/net/wifi/wificond/DeviceWiphyCapabilities.java deleted file mode 100644 index 13ae3b322841..000000000000 --- a/wifi/java/android/net/wifi/wificond/DeviceWiphyCapabilities.java +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright (C) 2020 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.wificond; - -import android.annotation.NonNull; -import android.annotation.SystemApi; -import android.net.wifi.ScanResult; -import android.os.Parcel; -import android.os.Parcelable; -import android.util.Log; - -import java.util.Objects; - -/** - * DeviceWiphyCapabilities for wificond - * - * @hide - */ -@SystemApi -public final class DeviceWiphyCapabilities implements Parcelable { - private static final String TAG = "DeviceWiphyCapabilities"; - - private boolean m80211nSupported; - private boolean m80211acSupported; - private boolean m80211axSupported; - private boolean mChannelWidth160MhzSupported; - private boolean mChannelWidth80p80MhzSupported; - private int mMaxNumberTxSpatialStreams; - private int mMaxNumberRxSpatialStreams; - - - /** public constructor */ - public DeviceWiphyCapabilities() { - m80211nSupported = false; - m80211acSupported = false; - m80211axSupported = false; - mChannelWidth160MhzSupported = false; - mChannelWidth80p80MhzSupported = false; - mMaxNumberTxSpatialStreams = 1; - mMaxNumberRxSpatialStreams = 1; - } - - /** - * Get the IEEE 802.11 standard support - * - * @param standard the IEEE 802.11 standard to check on its support. - * valid values from {@link ScanResult}'s {@code WIFI_STANDARD_} - * @return {@code true} if supported, {@code false} otherwise. - */ - public boolean isWifiStandardSupported(int standard) { - switch (standard) { - case ScanResult.WIFI_STANDARD_LEGACY: - return true; - case ScanResult.WIFI_STANDARD_11N: - return m80211nSupported; - case ScanResult.WIFI_STANDARD_11AC: - return m80211acSupported; - case ScanResult.WIFI_STANDARD_11AX: - return m80211axSupported; - default: - Log.e(TAG, "isWifiStandardSupported called with invalid standard: " + standard); - return false; - } - } - - /** - * Set the IEEE 802.11 standard support - * - * @param standard the IEEE 802.11 standard to set its support. - * valid values from {@link ScanResult}'s {@code WIFI_STANDARD_} - * @param support {@code true} if supported, {@code false} otherwise. - */ - public void setWifiStandardSupport(int standard, boolean support) { - switch (standard) { - case ScanResult.WIFI_STANDARD_11N: - m80211nSupported = support; - break; - case ScanResult.WIFI_STANDARD_11AC: - m80211acSupported = support; - break; - case ScanResult.WIFI_STANDARD_11AX: - m80211axSupported = support; - break; - default: - Log.e(TAG, "setWifiStandardSupport called with invalid standard: " + standard); - } - } - - /** - * Get the support for channel bandwidth - * - * @param chWidth valid values from {@link ScanResult}'s {@code CHANNEL_WIDTH_} - * - * @return {@code true} if supported, {@code false} otherwise. - */ - public boolean isChannelWidthSupported(int chWidth) { - switch (chWidth) { - case ScanResult.CHANNEL_WIDTH_20MHZ: - return true; - case ScanResult.CHANNEL_WIDTH_40MHZ: - return (m80211nSupported || m80211acSupported || m80211axSupported); - case ScanResult.CHANNEL_WIDTH_80MHZ: - return (m80211acSupported || m80211axSupported); - case ScanResult.CHANNEL_WIDTH_160MHZ: - return mChannelWidth160MhzSupported; - case ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ: - return mChannelWidth80p80MhzSupported; - default: - Log.e(TAG, "isChannelWidthSupported called with invalid channel width: " + chWidth); - } - return false; - } - - /** - * Set support for channel bandwidth - * - * @param chWidth valid values are {@link ScanResult#CHANNEL_WIDTH_160MHZ} and - * {@link ScanResult#CHANNEL_WIDTH_80MHZ_PLUS_MHZ} - * @param support {@code true} if supported, {@code false} otherwise. - */ - public void setChannelWidthSupported(int chWidth, boolean support) { - switch (chWidth) { - case ScanResult.CHANNEL_WIDTH_160MHZ: - mChannelWidth160MhzSupported = support; - break; - case ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ: - mChannelWidth80p80MhzSupported = support; - break; - default: - Log.e(TAG, "setChannelWidthSupported called with Invalid channel width: " - + chWidth); - } - } - - /** - * Get maximum number of transmit spatial streams - * - * @return number of spatial streams - */ - public int getMaxNumberTxSpatialStreams() { - return mMaxNumberTxSpatialStreams; - } - - /** - * Set maximum number of transmit spatial streams - * - * @param streams number of spatial streams - */ - public void setMaxNumberTxSpatialStreams(int streams) { - mMaxNumberTxSpatialStreams = streams; - } - - /** - * Get maximum number of receive spatial streams - * - * @return number of streams - */ - public int getMaxNumberRxSpatialStreams() { - return mMaxNumberRxSpatialStreams; - } - - /** - * Set maximum number of receive spatial streams - * - * @param streams number of streams - */ - public void setMaxNumberRxSpatialStreams(int streams) { - mMaxNumberRxSpatialStreams = streams; - } - - /** override comparator */ - @Override - public boolean equals(Object rhs) { - if (this == rhs) return true; - if (!(rhs instanceof DeviceWiphyCapabilities)) { - return false; - } - DeviceWiphyCapabilities capa = (DeviceWiphyCapabilities) rhs; - - return m80211nSupported == capa.m80211nSupported - && m80211acSupported == capa.m80211acSupported - && m80211axSupported == capa.m80211axSupported - && mChannelWidth160MhzSupported == capa.mChannelWidth160MhzSupported - && mChannelWidth80p80MhzSupported == capa.mChannelWidth80p80MhzSupported - && mMaxNumberTxSpatialStreams == capa.mMaxNumberTxSpatialStreams - && mMaxNumberRxSpatialStreams == capa.mMaxNumberRxSpatialStreams; - } - - /** override hash code */ - @Override - public int hashCode() { - return Objects.hash(m80211nSupported, m80211acSupported, m80211axSupported, - mChannelWidth160MhzSupported, mChannelWidth80p80MhzSupported, - mMaxNumberTxSpatialStreams, mMaxNumberRxSpatialStreams); - } - - /** implement Parcelable interface */ - @Override - public int describeContents() { - return 0; - } - - /** - * implement Parcelable interface - * |flags| is ignored. - */ - @Override - public void writeToParcel(@NonNull Parcel out, int flags) { - out.writeBoolean(m80211nSupported); - out.writeBoolean(m80211acSupported); - out.writeBoolean(m80211axSupported); - out.writeBoolean(mChannelWidth160MhzSupported); - out.writeBoolean(mChannelWidth80p80MhzSupported); - out.writeInt(mMaxNumberTxSpatialStreams); - out.writeInt(mMaxNumberRxSpatialStreams); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("m80211nSupported:").append(m80211nSupported ? "Yes" : "No"); - sb.append("m80211acSupported:").append(m80211acSupported ? "Yes" : "No"); - sb.append("m80211axSupported:").append(m80211axSupported ? "Yes" : "No"); - sb.append("mChannelWidth160MhzSupported: ") - .append(mChannelWidth160MhzSupported ? "Yes" : "No"); - sb.append("mChannelWidth80p80MhzSupported: ") - .append(mChannelWidth80p80MhzSupported ? "Yes" : "No"); - sb.append("mMaxNumberTxSpatialStreams: ").append(mMaxNumberTxSpatialStreams); - sb.append("mMaxNumberRxSpatialStreams: ").append(mMaxNumberRxSpatialStreams); - - return sb.toString(); - } - - /** implement Parcelable interface */ - public static final @NonNull Parcelable.Creator CREATOR = - new Parcelable.Creator() { - /** - * Caller is responsible for providing a valid parcel. - */ - @Override - public DeviceWiphyCapabilities createFromParcel(Parcel in) { - DeviceWiphyCapabilities capabilities = new DeviceWiphyCapabilities(); - capabilities.m80211nSupported = in.readBoolean(); - capabilities.m80211acSupported = in.readBoolean(); - capabilities.m80211axSupported = in.readBoolean(); - capabilities.mChannelWidth160MhzSupported = in.readBoolean(); - capabilities.mChannelWidth80p80MhzSupported = in.readBoolean(); - capabilities.mMaxNumberTxSpatialStreams = in.readInt(); - capabilities.mMaxNumberRxSpatialStreams = in.readInt(); - return capabilities; - } - - @Override - public DeviceWiphyCapabilities[] newArray(int size) { - return new DeviceWiphyCapabilities[size]; - } - }; -} diff --git a/wifi/java/android/net/wifi/wificond/HiddenNetwork.java b/wifi/java/android/net/wifi/wificond/HiddenNetwork.java deleted file mode 100644 index 38dacea77488..000000000000 --- a/wifi/java/android/net/wifi/wificond/HiddenNetwork.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2016 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.wificond; - -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.Arrays; - -/** - * HiddenNetwork for wificond - * - * @hide - */ -public class HiddenNetwork implements Parcelable { - private static final String TAG = "HiddenNetwork"; - - public byte[] ssid; - - /** public constructor */ - public HiddenNetwork() { } - - /** override comparator */ - @Override - public boolean equals(Object rhs) { - if (this == rhs) return true; - if (!(rhs instanceof HiddenNetwork)) { - return false; - } - HiddenNetwork network = (HiddenNetwork) rhs; - return Arrays.equals(ssid, network.ssid); - } - - /** override hash code */ - @Override - public int hashCode() { - return Arrays.hashCode(ssid); - } - - /** implement Parcelable interface */ - @Override - public int describeContents() { - return 0; - } - - /** - * implement Parcelable interface - * |flags| is ignored. - */ - @Override - public void writeToParcel(Parcel out, int flags) { - out.writeByteArray(ssid); - } - - /** implement Parcelable interface */ - public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - /** - * Caller is responsible for providing a valid parcel. - */ - @Override - public HiddenNetwork createFromParcel(Parcel in) { - HiddenNetwork result = new HiddenNetwork(); - result.ssid = in.createByteArray(); - return result; - } - - @Override - public HiddenNetwork[] newArray(int size) { - return new HiddenNetwork[size]; - } - }; -} diff --git a/wifi/java/android/net/wifi/wificond/NativeScanResult.java b/wifi/java/android/net/wifi/wificond/NativeScanResult.java deleted file mode 100644 index bd99476afe43..000000000000 --- a/wifi/java/android/net/wifi/wificond/NativeScanResult.java +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright (C) 2016 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.wificond; - -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.net.MacAddress; -import android.os.Parcel; -import android.os.Parcelable; -import android.util.Log; - -import com.android.internal.annotations.VisibleForTesting; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * Raw scan result data from the wificond daemon. - * - * @hide - */ -@SystemApi -public final class NativeScanResult implements Parcelable { - private static final String TAG = "NativeScanResult"; - - /** @hide */ - @VisibleForTesting - public byte[] ssid; - /** @hide */ - @VisibleForTesting - public byte[] bssid; - /** @hide */ - @VisibleForTesting - public byte[] infoElement; - /** @hide */ - @VisibleForTesting - public int frequency; - /** @hide */ - @VisibleForTesting - public int signalMbm; - /** @hide */ - @VisibleForTesting - public long tsf; - /** @hide */ - @VisibleForTesting - @BssCapabilityBits public int capability; - /** @hide */ - @VisibleForTesting - public boolean associated; - /** @hide */ - @VisibleForTesting - public List radioChainInfos; - - /** - * Returns the SSID raw byte array of the AP represented by this scan result. - * - * @return A byte array. - */ - @NonNull public byte[] getSsid() { - return ssid; - } - - /** - * Returns the MAC address (BSSID) of the AP represented by this scan result. - * - * @return a MacAddress or null on error. - */ - @Nullable public MacAddress getBssid() { - try { - return MacAddress.fromBytes(bssid); - } catch (IllegalArgumentException e) { - Log.e(TAG, "Illegal argument " + Arrays.toString(bssid), e); - return null; - } - } - - /** - * Returns the raw bytes of the information element advertised by the AP represented by this - * scan result. - * - * @return A byte array, possibly null or containing an invalid TLV configuration. - */ - @NonNull public byte[] getInformationElements() { - return infoElement; - } - - /** - * Returns the frequency (in MHz) on which the AP represented by this scan result was observed. - * - * @return The frequency in MHz. - */ - public int getFrequencyMhz() { - return frequency; - } - - /** - * Return the signal strength of probe response/beacon in (100 * dBm). - * - * @return Signal strenght in (100 * dBm). - */ - public int getSignalMbm() { - return signalMbm; - } - - /** - * Return the TSF (Timing Synchronization Function) of the received probe response/beacon. - * @return - */ - public long getTsf() { - return tsf; - } - - /** - * Return a boolean indicating whether or not we're associated to the AP represented by this - * scan result. - * - * @return A boolean indicating association. - */ - public boolean isAssociated() { - return associated; - } - - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(flag = true, prefix = {"BSS_CAPABILITY_"}, - value = {BSS_CAPABILITY_ESS, - BSS_CAPABILITY_IBSS, - BSS_CAPABILITY_CF_POLLABLE, - BSS_CAPABILITY_CF_POLL_REQUEST, - BSS_CAPABILITY_PRIVACY, - BSS_CAPABILITY_SHORT_PREAMBLE, - BSS_CAPABILITY_PBCC, - BSS_CAPABILITY_CHANNEL_AGILITY, - BSS_CAPABILITY_SPECTRUM_MANAGEMENT, - BSS_CAPABILITY_QOS, - BSS_CAPABILITY_SHORT_SLOT_TIME, - BSS_CAPABILITY_APSD, - BSS_CAPABILITY_RADIO_MANAGEMENT, - BSS_CAPABILITY_DSSS_OFDM, - BSS_CAPABILITY_DELAYED_BLOCK_ACK, - BSS_CAPABILITY_IMMEDIATE_BLOCK_ACK - }) - public @interface BssCapabilityBits { } - - /** - * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): ESS. - */ - public static final int BSS_CAPABILITY_ESS = 0x1 << 0; - /** - * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): IBSS. - */ - public static final int BSS_CAPABILITY_IBSS = 0x1 << 1; - /** - * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): CF Pollable. - */ - public static final int BSS_CAPABILITY_CF_POLLABLE = 0x1 << 2; - /** - * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): CF-Poll Request. - */ - public static final int BSS_CAPABILITY_CF_POLL_REQUEST = 0x1 << 3; - /** - * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Privacy. - */ - public static final int BSS_CAPABILITY_PRIVACY = 0x1 << 4; - /** - * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Short Preamble. - */ - public static final int BSS_CAPABILITY_SHORT_PREAMBLE = 0x1 << 5; - /** - * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): PBCC. - */ - public static final int BSS_CAPABILITY_PBCC = 0x1 << 6; - /** - * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Channel Agility. - */ - public static final int BSS_CAPABILITY_CHANNEL_AGILITY = 0x1 << 7; - /** - * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Spectrum Management. - */ - public static final int BSS_CAPABILITY_SPECTRUM_MANAGEMENT = 0x1 << 8; - /** - * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): QoS. - */ - public static final int BSS_CAPABILITY_QOS = 0x1 << 9; - /** - * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Short Slot Time. - */ - public static final int BSS_CAPABILITY_SHORT_SLOT_TIME = 0x1 << 10; - /** - * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): APSD. - */ - public static final int BSS_CAPABILITY_APSD = 0x1 << 11; - /** - * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Radio Management. - */ - public static final int BSS_CAPABILITY_RADIO_MANAGEMENT = 0x1 << 12; - /** - * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): DSSS-OFDM. - */ - public static final int BSS_CAPABILITY_DSSS_OFDM = 0x1 << 13; - /** - * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Delayed Block Ack. - */ - public static final int BSS_CAPABILITY_DELAYED_BLOCK_ACK = 0x1 << 14; - /** - * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Immediate Block Ack. - */ - public static final int BSS_CAPABILITY_IMMEDIATE_BLOCK_ACK = 0x1 << 15; - - /** - * Returns the capabilities of the AP repseresented by this scan result as advertised in the - * received probe response or beacon. - * - * This is a bit mask describing the capabilities of a BSS. See IEEE Std 802.11: 9.4.1.4: one - * of the {@code BSS_CAPABILITY_*} flags. - * - * @return a bit mask of capabilities. - */ - @BssCapabilityBits public int getCapabilities() { - return capability; - } - - /** - * Returns details of the signal received on each radio chain for the AP represented by this - * scan result in a list of {@link RadioChainInfo} elements. - * - * @return A list of {@link RadioChainInfo} - possibly empty in case of error. - */ - @NonNull public List getRadioChainInfos() { - return radioChainInfos; - } - - /** - * Construct an empty native scan result. - */ - public NativeScanResult() { } - - /** implement Parcelable interface */ - @Override - public int describeContents() { - return 0; - } - - /** implement Parcelable interface */ - @Override - public void writeToParcel(@NonNull Parcel out, int flags) { - out.writeByteArray(ssid); - out.writeByteArray(bssid); - out.writeByteArray(infoElement); - out.writeInt(frequency); - out.writeInt(signalMbm); - out.writeLong(tsf); - out.writeInt(capability); - out.writeInt(associated ? 1 : 0); - out.writeTypedList(radioChainInfos); - } - - /** implement Parcelable interface */ - @NonNull public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - @Override - public NativeScanResult createFromParcel(Parcel in) { - NativeScanResult result = new NativeScanResult(); - result.ssid = in.createByteArray(); - if (result.ssid == null) { - result.ssid = new byte[0]; - } - result.bssid = in.createByteArray(); - if (result.bssid == null) { - result.bssid = new byte[0]; - } - result.infoElement = in.createByteArray(); - if (result.infoElement == null) { - result.infoElement = new byte[0]; - } - result.frequency = in.readInt(); - result.signalMbm = in.readInt(); - result.tsf = in.readLong(); - result.capability = in.readInt(); - result.associated = (in.readInt() != 0); - result.radioChainInfos = new ArrayList<>(); - in.readTypedList(result.radioChainInfos, RadioChainInfo.CREATOR); - return result; - } - - @Override - public NativeScanResult[] newArray(int size) { - return new NativeScanResult[size]; - } - }; -} diff --git a/wifi/java/android/net/wifi/wificond/NativeWifiClient.java b/wifi/java/android/net/wifi/wificond/NativeWifiClient.java deleted file mode 100644 index 9ad2a2769add..000000000000 --- a/wifi/java/android/net/wifi/wificond/NativeWifiClient.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * 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.wificond; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.net.MacAddress; -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.Objects; - -/** - * Structure providing information about clients (STAs) associated with a SoftAp. - * - * @hide - */ -@SystemApi -public final class NativeWifiClient implements Parcelable { - private final MacAddress mMacAddress; - - /** - * The MAC address of the client (STA) represented by this object. The MAC address may be null - * in case of an error. - */ - @Nullable public MacAddress getMacAddress() { - return mMacAddress; - } - - /** - * Construct a native Wi-Fi client. - */ - public NativeWifiClient(@Nullable MacAddress macAddress) { - this.mMacAddress = macAddress; - } - - /** override comparator */ - @Override - public boolean equals(Object rhs) { - if (this == rhs) return true; - if (!(rhs instanceof NativeWifiClient)) { - return false; - } - NativeWifiClient other = (NativeWifiClient) rhs; - return Objects.equals(mMacAddress, other.mMacAddress); - } - - /** override hash code */ - @Override - public int hashCode() { - return mMacAddress.hashCode(); - } - - /** implement Parcelable interface */ - @Override - public int describeContents() { - return 0; - } - - /** - * implement Parcelable interface - * |flag| is ignored. - */ - @Override - public void writeToParcel(@NonNull Parcel out, int flags) { - out.writeByteArray(mMacAddress.toByteArray()); - } - - /** implement Parcelable interface */ - @NonNull public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - @Override - public NativeWifiClient createFromParcel(Parcel in) { - MacAddress macAddress; - try { - macAddress = MacAddress.fromBytes(in.createByteArray()); - } catch (IllegalArgumentException e) { - macAddress = null; - } - return new NativeWifiClient(macAddress); - } - - @Override - public NativeWifiClient[] newArray(int size) { - return new NativeWifiClient[size]; - } - }; -} diff --git a/wifi/java/android/net/wifi/wificond/PnoNetwork.java b/wifi/java/android/net/wifi/wificond/PnoNetwork.java deleted file mode 100644 index ca0b1cfb6223..000000000000 --- a/wifi/java/android/net/wifi/wificond/PnoNetwork.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) 2016 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.wificond; - -import android.annotation.NonNull; -import android.annotation.SystemApi; -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.Arrays; -import java.util.Objects; - -/** - * Configuration for a PNO (preferred network offload) network used in {@link PnoSettings}. A PNO - * network allows configuration of a specific network to search for. - * - * @hide - */ -@SystemApi -public final class PnoNetwork implements Parcelable { - private boolean mIsHidden; - private byte[] mSsid; - private int[] mFrequencies; - - /** - * Indicates whether the PNO network configuration is for a hidden SSID - i.e. a network which - * does not broadcast its SSID and must be queried explicitly. - * - * @return True if the configuration is for a hidden network, false otherwise. - */ - public boolean isHidden() { - return mIsHidden; - } - - /** - * Configure whether the PNO network configuration is for a hidden SSID - i.e. a network which - * does not broadcast its SSID and must be queried explicitly. - * - * @param isHidden True if the configuration is for a hidden network, false otherwise. - */ - public void setHidden(boolean isHidden) { - mIsHidden = isHidden; - } - - /** - * Get the raw bytes for the SSID of the PNO network being scanned for. - * - * @return A byte array. - */ - @NonNull public byte[] getSsid() { - return mSsid; - } - - /** - * Set the raw bytes for the SSID of the PNO network being scanned for. - * - * @param ssid A byte array. - */ - public void setSsid(@NonNull byte[] ssid) { - if (ssid == null) { - throw new IllegalArgumentException("null argument"); - } - this.mSsid = ssid; - } - - /** - * Get the frequencies (in MHz) on which to PNO scan for the current network is being searched - * for. A null return (i.e. no frequencies configured) indicates that the network is search for - * on all supported frequencies. - * - * @return A array of frequencies (in MHz), a null indicates no configured frequencies. - */ - @NonNull public int[] getFrequenciesMhz() { - return mFrequencies; - } - - /** - * Set the frequencies (in MHz) on which to PNO scan for the current network is being searched - * for. A null configuration (i.e. no frequencies configured) indicates that the network is - * search for on all supported frequencies. - * - * @param frequenciesMhz an array of frequencies (in MHz), null indicating no configured - * frequencies. - */ - public void setFrequenciesMhz(@NonNull int[] frequenciesMhz) { - if (frequenciesMhz == null) { - throw new IllegalArgumentException("null argument"); - } - this.mFrequencies = frequenciesMhz; - } - - /** Construct an uninitialized PnoNetwork object */ - public PnoNetwork() { } - - /** override comparator */ - @Override - public boolean equals(Object rhs) { - if (this == rhs) return true; - if (!(rhs instanceof PnoNetwork)) { - return false; - } - PnoNetwork network = (PnoNetwork) rhs; - return Arrays.equals(mSsid, network.mSsid) - && Arrays.equals(mFrequencies, network.mFrequencies) - && mIsHidden == network.mIsHidden; - } - - /** override hash code */ - @Override - public int hashCode() { - return Objects.hash( - mIsHidden, - Arrays.hashCode(mSsid), - Arrays.hashCode(mFrequencies)); - } - - /** implement Parcelable interface */ - @Override - public int describeContents() { - return 0; - } - - /** - * implement Parcelable interface - * |flag| is ignored. - */ - @Override - public void writeToParcel(@NonNull Parcel out, int flags) { - out.writeInt(mIsHidden ? 1 : 0); - out.writeByteArray(mSsid); - out.writeIntArray(mFrequencies); - } - - /** implement Parcelable interface */ - @NonNull public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - @Override - public PnoNetwork createFromParcel(Parcel in) { - PnoNetwork result = new PnoNetwork(); - result.mIsHidden = in.readInt() != 0 ? true : false; - result.mSsid = in.createByteArray(); - if (result.mSsid == null) { - result.mSsid = new byte[0]; - } - result.mFrequencies = in.createIntArray(); - if (result.mFrequencies == null) { - result.mFrequencies = new int[0]; - } - return result; - } - - @Override - public PnoNetwork[] newArray(int size) { - return new PnoNetwork[size]; - } - }; -} diff --git a/wifi/java/android/net/wifi/wificond/PnoSettings.java b/wifi/java/android/net/wifi/wificond/PnoSettings.java deleted file mode 100644 index 533d37d3a23a..000000000000 --- a/wifi/java/android/net/wifi/wificond/PnoSettings.java +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright (C) 2016 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.wificond; - -import android.annotation.DurationMillisLong; -import android.annotation.NonNull; -import android.annotation.SystemApi; -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -/** - * Configuration for a PNO (preferred network offload). A mechanism by which scans are offloaded - * from the host device to the Wi-Fi chip. - * - * @hide - */ -@SystemApi -public final class PnoSettings implements Parcelable { - private long mIntervalMs; - private int mMin2gRssi; - private int mMin5gRssi; - private int mMin6gRssi; - private List mPnoNetworks; - - /** Construct an uninitialized PnoSettings object */ - public PnoSettings() { } - - /** - * Get the requested PNO scan interval in milliseconds. - * - * @return An interval in milliseconds. - */ - public @DurationMillisLong long getIntervalMillis() { - return mIntervalMs; - } - - /** - * Set the requested PNO scan interval in milliseconds. - * - * @param intervalMillis An interval in milliseconds. - */ - public void setIntervalMillis(@DurationMillisLong long intervalMillis) { - this.mIntervalMs = intervalMillis; - } - - /** - * Get the requested minimum RSSI threshold (in dBm) for APs to report in scan results in the - * 2.4GHz band. - * - * @return An RSSI value in dBm. - */ - public int getMin2gRssiDbm() { - return mMin2gRssi; - } - - /** - * Set the requested minimum RSSI threshold (in dBm) for APs to report in scan scan results in - * the 2.4GHz band. - * - * @param min2gRssiDbm An RSSI value in dBm. - */ - public void setMin2gRssiDbm(int min2gRssiDbm) { - this.mMin2gRssi = min2gRssiDbm; - } - - /** - * Get the requested minimum RSSI threshold (in dBm) for APs to report in scan results in the - * 5GHz band. - * - * @return An RSSI value in dBm. - */ - public int getMin5gRssiDbm() { - return mMin5gRssi; - } - - /** - * Set the requested minimum RSSI threshold (in dBm) for APs to report in scan scan results in - * the 5GHz band. - * - * @param min5gRssiDbm An RSSI value in dBm. - */ - public void setMin5gRssiDbm(int min5gRssiDbm) { - this.mMin5gRssi = min5gRssiDbm; - } - - /** - * Get the requested minimum RSSI threshold (in dBm) for APs to report in scan results in the - * 6GHz band. - * - * @return An RSSI value in dBm. - */ - public int getMin6gRssiDbm() { - return mMin6gRssi; - } - - /** - * Set the requested minimum RSSI threshold (in dBm) for APs to report in scan scan results in - * the 6GHz band. - * - * @param min6gRssiDbm An RSSI value in dBm. - */ - public void setMin6gRssiDbm(int min6gRssiDbm) { - this.mMin6gRssi = min6gRssiDbm; - } - - /** - * Return the configured list of specific networks to search for in a PNO scan. - * - * @return A list of {@link PnoNetwork} objects, possibly empty if non configured. - */ - @NonNull public List getPnoNetworks() { - return mPnoNetworks; - } - - /** - * Set the list of specified networks to scan for in a PNO scan. The networks (APs) are - * specified using {@link PnoNetwork}s. An empty list indicates that all networks are scanned - * for. - * - * @param pnoNetworks A (possibly empty) list of {@link PnoNetwork} objects. - */ - public void setPnoNetworks(@NonNull List pnoNetworks) { - this.mPnoNetworks = pnoNetworks; - } - - /** override comparator */ - @Override - public boolean equals(Object rhs) { - if (this == rhs) return true; - if (!(rhs instanceof PnoSettings)) { - return false; - } - PnoSettings settings = (PnoSettings) rhs; - if (settings == null) { - return false; - } - return mIntervalMs == settings.mIntervalMs - && mMin2gRssi == settings.mMin2gRssi - && mMin5gRssi == settings.mMin5gRssi - && mMin6gRssi == settings.mMin6gRssi - && mPnoNetworks.equals(settings.mPnoNetworks); - } - - /** override hash code */ - @Override - public int hashCode() { - return Objects.hash(mIntervalMs, mMin2gRssi, mMin5gRssi, mMin6gRssi, mPnoNetworks); - } - - /** implement Parcelable interface */ - @Override - public int describeContents() { - return 0; - } - - /** - * implement Parcelable interface - * |flag| is ignored. - **/ - @Override - public void writeToParcel(@NonNull Parcel out, int flags) { - out.writeLong(mIntervalMs); - out.writeInt(mMin2gRssi); - out.writeInt(mMin5gRssi); - out.writeInt(mMin6gRssi); - out.writeTypedList(mPnoNetworks); - } - - /** implement Parcelable interface */ - @NonNull public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - @Override - public PnoSettings createFromParcel(Parcel in) { - PnoSettings result = new PnoSettings(); - result.mIntervalMs = in.readLong(); - result.mMin2gRssi = in.readInt(); - result.mMin5gRssi = in.readInt(); - result.mMin6gRssi = in.readInt(); - - result.mPnoNetworks = new ArrayList<>(); - in.readTypedList(result.mPnoNetworks, PnoNetwork.CREATOR); - - return result; - } - - @Override - public PnoSettings[] newArray(int size) { - return new PnoSettings[size]; - } - }; -} diff --git a/wifi/java/android/net/wifi/wificond/RadioChainInfo.java b/wifi/java/android/net/wifi/wificond/RadioChainInfo.java deleted file mode 100644 index 97c0ee9d1c2c..000000000000 --- a/wifi/java/android/net/wifi/wificond/RadioChainInfo.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2016 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.wificond; - -import android.annotation.NonNull; -import android.annotation.SystemApi; -import android.os.Parcel; -import android.os.Parcelable; - -import com.android.internal.annotations.VisibleForTesting; - -import java.util.Objects; - -/** - * A class representing the radio chains of the Wi-Fi modems. Use to provide raw information about - * signals received on different radio chains. - * - * @hide - */ -@SystemApi -public final class RadioChainInfo implements Parcelable { - private static final String TAG = "RadioChainInfo"; - - /** @hide */ - @VisibleForTesting - public int chainId; - /** @hide */ - @VisibleForTesting - public int level; - - /** - * Return an identifier for this radio chain. This is an arbitrary ID which is consistent for - * the same device. - * - * @return The radio chain ID. - */ - public int getChainId() { - return chainId; - } - - /** - * Returns the detected signal level on this radio chain in dBm (aka RSSI). - * - * @return A signal level in dBm. - */ - public int getLevelDbm() { - return level; - } - - /** - * Construct a RadioChainInfo. - */ - public RadioChainInfo(int chainId, int level) { - this.chainId = chainId; - this.level = level; - } - - /** override comparator */ - @Override - public boolean equals(Object rhs) { - if (this == rhs) return true; - if (!(rhs instanceof RadioChainInfo)) { - return false; - } - RadioChainInfo chainInfo = (RadioChainInfo) rhs; - if (chainInfo == null) { - return false; - } - return chainId == chainInfo.chainId && level == chainInfo.level; - } - - /** override hash code */ - @Override - public int hashCode() { - return Objects.hash(chainId, level); - } - - - /** implement Parcelable interface */ - @Override - public int describeContents() { - return 0; - } - - /** - * implement Parcelable interface - * |flags| is ignored. - */ - @Override - public void writeToParcel(@NonNull Parcel out, int flags) { - out.writeInt(chainId); - out.writeInt(level); - } - - /** implement Parcelable interface */ - @NonNull public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - /** - * Caller is responsible for providing a valid parcel. - */ - @Override - public RadioChainInfo createFromParcel(Parcel in) { - return new RadioChainInfo(in.readInt(), in.readInt()); - } - - @Override - public RadioChainInfo[] newArray(int size) { - return new RadioChainInfo[size]; - } - }; -} diff --git a/wifi/java/android/net/wifi/wificond/SingleScanSettings.java b/wifi/java/android/net/wifi/wificond/SingleScanSettings.java deleted file mode 100644 index 8c341b8bd916..000000000000 --- a/wifi/java/android/net/wifi/wificond/SingleScanSettings.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2016 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.wificond; - -import android.os.Parcel; -import android.os.Parcelable; -import android.util.Log; - -import java.util.ArrayList; -import java.util.Objects; - -/** - * SingleScanSettings for wificond - * - * @hide - */ -public class SingleScanSettings implements Parcelable { - private static final String TAG = "SingleScanSettings"; - - public int scanType; - public ArrayList channelSettings; - public ArrayList hiddenNetworks; - - /** public constructor */ - public SingleScanSettings() { } - - /** override comparator */ - @Override - public boolean equals(Object rhs) { - if (this == rhs) return true; - if (!(rhs instanceof SingleScanSettings)) { - return false; - } - SingleScanSettings settings = (SingleScanSettings) rhs; - if (settings == null) { - return false; - } - return scanType == settings.scanType - && channelSettings.equals(settings.channelSettings) - && hiddenNetworks.equals(settings.hiddenNetworks); - } - - /** override hash code */ - @Override - public int hashCode() { - return Objects.hash(scanType, channelSettings, hiddenNetworks); - } - - - /** implement Parcelable interface */ - @Override - public int describeContents() { - return 0; - } - - private static boolean isValidScanType(int scanType) { - return scanType == IWifiScannerImpl.SCAN_TYPE_LOW_SPAN - || scanType == IWifiScannerImpl.SCAN_TYPE_LOW_POWER - || scanType == IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY; - } - - /** - * implement Parcelable interface - * |flags| is ignored. - */ - @Override - public void writeToParcel(Parcel out, int flags) { - if (!isValidScanType(scanType)) { - Log.wtf(TAG, "Invalid scan type " + scanType); - } - out.writeInt(scanType); - out.writeTypedList(channelSettings); - out.writeTypedList(hiddenNetworks); - } - - /** implement Parcelable interface */ - public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - /** - * Caller is responsible for providing a valid parcel. - */ - @Override - public SingleScanSettings createFromParcel(Parcel in) { - SingleScanSettings result = new SingleScanSettings(); - result.scanType = in.readInt(); - if (!isValidScanType(result.scanType)) { - Log.wtf(TAG, "Invalid scan type " + result.scanType); - } - result.channelSettings = new ArrayList(); - in.readTypedList(result.channelSettings, ChannelSettings.CREATOR); - result.hiddenNetworks = new ArrayList(); - in.readTypedList(result.hiddenNetworks, HiddenNetwork.CREATOR); - if (in.dataAvail() != 0) { - Log.e(TAG, "Found trailing data after parcel parsing."); - } - return result; - } - - @Override - public SingleScanSettings[] newArray(int size) { - return new SingleScanSettings[size]; - } - }; -} diff --git a/wifi/java/android/net/wifi/wificond/WifiNl80211Manager.java b/wifi/java/android/net/wifi/wificond/WifiNl80211Manager.java deleted file mode 100644 index 89f642fdbb66..000000000000 --- a/wifi/java/android/net/wifi/wificond/WifiNl80211Manager.java +++ /dev/null @@ -1,1287 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.wifi.wificond; - -import android.annotation.CallbackExecutor; -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.annotation.SystemService; -import android.app.AlarmManager; -import android.content.Context; -import android.net.wifi.SoftApInfo; -import android.net.wifi.WifiAnnotations; -import android.net.wifi.WifiScanner; -import android.os.Binder; -import android.os.Handler; -import android.os.IBinder; -import android.os.RemoteException; -import android.os.ServiceManager; -import android.os.SystemClock; -import android.util.Log; - -import com.android.internal.annotations.VisibleForTesting; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.Executor; -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * This class encapsulates the interface the wificond daemon presents to the Wi-Fi framework - used - * to encapsulate the Wi-Fi 80211nl management interface. The - * interface is only for use by the Wi-Fi framework and access is protected by SELinux permissions. - * - * @hide - */ -@SystemApi -@SystemService(Context.WIFI_NL80211_SERVICE) -public class WifiNl80211Manager { - private static final String TAG = "WifiNl80211Manager"; - private boolean mVerboseLoggingEnabled = false; - - /** - * The {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} - * timeout, in milliseconds, after which - * {@link SendMgmtFrameCallback#onFailure(int)} will be called with reason - * {@link #SEND_MGMT_FRAME_ERROR_TIMEOUT}. - */ - private static final int SEND_MGMT_FRAME_TIMEOUT_MS = 1000; - - private static final String TIMEOUT_ALARM_TAG = TAG + " Send Management Frame Timeout"; - - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = {"SCAN_TYPE_"}, - value = {SCAN_TYPE_SINGLE_SCAN, - SCAN_TYPE_PNO_SCAN}) - public @interface ScanResultType {} - - /** - * Specifies a scan type: single scan initiated by the framework. Can be used in - * {@link #getScanResults(String, int)} to specify the type of scan result to fetch. - */ - public static final int SCAN_TYPE_SINGLE_SCAN = 0; - - /** - * Specifies a scan type: PNO scan. Can be used in {@link #getScanResults(String, int)} to - * specify the type of scan result to fetch. - */ - public static final int SCAN_TYPE_PNO_SCAN = 1; - - private AlarmManager mAlarmManager; - private Handler mEventHandler; - - // Cached wificond binder handlers. - private IWificond mWificond; - private HashMap mClientInterfaces = new HashMap<>(); - private HashMap mApInterfaces = new HashMap<>(); - private HashMap mWificondScanners = new HashMap<>(); - private HashMap mScanEventHandlers = new HashMap<>(); - private HashMap mPnoScanEventHandlers = new HashMap<>(); - private HashMap mApInterfaceListeners = new HashMap<>(); - private Runnable mDeathEventHandler; - /** - * Ensures that no more than one sendMgmtFrame operation runs concurrently. - */ - private AtomicBoolean mSendMgmtFrameInProgress = new AtomicBoolean(false); - - /** - * Interface used when waiting for scans to be completed (with results). - */ - public interface ScanEventCallback { - /** - * Called when scan results are available. Scans results should then be obtained from - * {@link #getScanResults(String, int)}. - */ - void onScanResultReady(); - - /** - * Called when a scan has failed. - */ - void onScanFailed(); - } - - /** - * Interface for a callback to provide information about PNO scan request requested with - * {@link #startPnoScan(String, PnoSettings, Executor, PnoScanRequestCallback)}. Note that the - * callback are for the status of the request - not the scan itself. The results of the scan - * are returned with {@link ScanEventCallback}. - */ - public interface PnoScanRequestCallback { - /** - * Called when a PNO scan request has been successfully submitted. - */ - void onPnoRequestSucceeded(); - - /** - * Called when a PNO scan request fails. - */ - void onPnoRequestFailed(); - } - - private class ScanEventHandler extends IScanEvent.Stub { - private Executor mExecutor; - private ScanEventCallback mCallback; - - ScanEventHandler(@NonNull Executor executor, @NonNull ScanEventCallback callback) { - mExecutor = executor; - mCallback = callback; - } - - @Override - public void OnScanResultReady() { - Log.d(TAG, "Scan result ready event"); - Binder.clearCallingIdentity(); - mExecutor.execute(() -> mCallback.onScanResultReady()); - } - - @Override - public void OnScanFailed() { - Log.d(TAG, "Scan failed event"); - Binder.clearCallingIdentity(); - mExecutor.execute(() -> mCallback.onScanFailed()); - } - } - - /** - * Result of a signal poll requested using {@link #signalPoll(String)}. - */ - public static class SignalPollResult { - /** @hide */ - public SignalPollResult(int currentRssiDbm, int txBitrateMbps, int rxBitrateMbps, - int associationFrequencyMHz) { - this.currentRssiDbm = currentRssiDbm; - this.txBitrateMbps = txBitrateMbps; - this.rxBitrateMbps = rxBitrateMbps; - this.associationFrequencyMHz = associationFrequencyMHz; - } - - /** - * RSSI value in dBM. - */ - public final int currentRssiDbm; - - /** - * Transmission bit rate in Mbps. - */ - public final int txBitrateMbps; - - /** - * Last received packet bit rate in Mbps. - */ - public final int rxBitrateMbps; - - /** - * Association frequency in MHz. - */ - public final int associationFrequencyMHz; - } - - /** - * Transmission counters obtained using {@link #getTxPacketCounters(String)}. - */ - public static class TxPacketCounters { - /** @hide */ - public TxPacketCounters(int txPacketSucceeded, int txPacketFailed) { - this.txPacketSucceeded = txPacketSucceeded; - this.txPacketFailed = txPacketFailed; - } - - /** - * Number of successfully transmitted packets. - */ - public final int txPacketSucceeded; - - /** - * Number of packet transmission failures. - */ - public final int txPacketFailed; - } - - /** - * Callbacks for SoftAp interface registered using - * {@link #registerApCallback(String, Executor, SoftApCallback)}. - */ - public interface SoftApCallback { - /** - * Invoked when there is a fatal failure and the SoftAp is shutdown. - */ - void onFailure(); - - /** - * Invoked when there is a change in the associated station (STA). - * @param client Information about the client whose status has changed. - * @param isConnected Indication as to whether the client is connected (true), or - * disconnected (false). - */ - void onConnectedClientsChanged(@NonNull NativeWifiClient client, boolean isConnected); - - /** - * Invoked when a channel switch event happens - i.e. the SoftAp is moved to a different - * channel. Also called on initial registration. - * @param frequencyMhz The new frequency of the SoftAp. A value of 0 is invalid and is an - * indication that the SoftAp is not enabled. - * @param bandwidth The new bandwidth of the SoftAp. - */ - void onSoftApChannelSwitched(int frequencyMhz, @WifiAnnotations.Bandwidth int bandwidth); - } - - /** - * Callback to notify the results of a - * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} call. - * Note: no callbacks will be triggered if the interface dies while sending a frame. - */ - public interface SendMgmtFrameCallback { - /** - * Called when the management frame was successfully sent and ACKed by the recipient. - * @param elapsedTimeMs The elapsed time between when the management frame was sent and when - * the ACK was processed, in milliseconds, as measured by wificond. - * This includes the time that the send frame spent queuing before it - * was sent, any firmware retries, and the time the received ACK spent - * queuing before it was processed. - */ - void onAck(int elapsedTimeMs); - - /** - * Called when the send failed. - * @param reason The error code for the failure. - */ - void onFailure(@SendMgmtFrameError int reason); - } - - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = {"SEND_MGMT_FRAME_ERROR_"}, - value = {SEND_MGMT_FRAME_ERROR_UNKNOWN, - SEND_MGMT_FRAME_ERROR_MCS_UNSUPPORTED, - SEND_MGMT_FRAME_ERROR_NO_ACK, - SEND_MGMT_FRAME_ERROR_TIMEOUT, - SEND_MGMT_FRAME_ERROR_ALREADY_STARTED}) - public @interface SendMgmtFrameError {} - - // Send management frame error codes - - /** - * Unknown error occurred during call to - * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)}. - */ - public static final int SEND_MGMT_FRAME_ERROR_UNKNOWN = 1; - - /** - * Specifying the MCS rate in - * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} is not - * supported by this device. - */ - public static final int SEND_MGMT_FRAME_ERROR_MCS_UNSUPPORTED = 2; - - /** - * Driver reported that no ACK was received for the frame transmitted using - * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)}. - */ - public static final int SEND_MGMT_FRAME_ERROR_NO_ACK = 3; - - /** - * Error code for when the driver fails to report on the status of the frame sent by - * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} - * after {@link #SEND_MGMT_FRAME_TIMEOUT_MS} milliseconds. - */ - public static final int SEND_MGMT_FRAME_ERROR_TIMEOUT = 4; - - /** - * An existing call to - * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} - * is in progress. Another frame cannot be sent until the first call completes. - */ - public static final int SEND_MGMT_FRAME_ERROR_ALREADY_STARTED = 5; - - /** @hide */ - public WifiNl80211Manager(Context context) { - mAlarmManager = context.getSystemService(AlarmManager.class); - mEventHandler = new Handler(context.getMainLooper()); - } - - /** @hide */ - @VisibleForTesting - public WifiNl80211Manager(Context context, IWificond wificond) { - this(context); - mWificond = wificond; - } - - private class PnoScanEventHandler extends IPnoScanEvent.Stub { - private Executor mExecutor; - private ScanEventCallback mCallback; - - PnoScanEventHandler(@NonNull Executor executor, @NonNull ScanEventCallback callback) { - mExecutor = executor; - mCallback = callback; - } - - @Override - public void OnPnoNetworkFound() { - Log.d(TAG, "Pno scan result event"); - Binder.clearCallingIdentity(); - mExecutor.execute(() -> mCallback.onScanResultReady()); - } - - @Override - public void OnPnoScanFailed() { - Log.d(TAG, "Pno Scan failed event"); - Binder.clearCallingIdentity(); - mExecutor.execute(() -> mCallback.onScanFailed()); - } - } - - /** - * Listener for AP Interface events. - */ - private class ApInterfaceEventCallback extends IApInterfaceEventCallback.Stub { - private Executor mExecutor; - private SoftApCallback mSoftApListener; - - ApInterfaceEventCallback(Executor executor, SoftApCallback listener) { - mExecutor = executor; - mSoftApListener = listener; - } - - @Override - public void onConnectedClientsChanged(NativeWifiClient client, boolean isConnected) { - if (mVerboseLoggingEnabled) { - Log.d(TAG, "onConnectedClientsChanged called with " - + client.getMacAddress() + " isConnected: " + isConnected); - } - - Binder.clearCallingIdentity(); - mExecutor.execute(() -> mSoftApListener.onConnectedClientsChanged(client, isConnected)); - } - - @Override - public void onSoftApChannelSwitched(int frequency, int bandwidth) { - Binder.clearCallingIdentity(); - mExecutor.execute(() -> mSoftApListener.onSoftApChannelSwitched(frequency, - toFrameworkBandwidth(bandwidth))); - } - - private @WifiAnnotations.Bandwidth int toFrameworkBandwidth(int bandwidth) { - switch(bandwidth) { - case IApInterfaceEventCallback.BANDWIDTH_INVALID: - return SoftApInfo.CHANNEL_WIDTH_INVALID; - case IApInterfaceEventCallback.BANDWIDTH_20_NOHT: - return SoftApInfo.CHANNEL_WIDTH_20MHZ_NOHT; - case IApInterfaceEventCallback.BANDWIDTH_20: - return SoftApInfo.CHANNEL_WIDTH_20MHZ; - case IApInterfaceEventCallback.BANDWIDTH_40: - return SoftApInfo.CHANNEL_WIDTH_40MHZ; - case IApInterfaceEventCallback.BANDWIDTH_80: - return SoftApInfo.CHANNEL_WIDTH_80MHZ; - case IApInterfaceEventCallback.BANDWIDTH_80P80: - return SoftApInfo.CHANNEL_WIDTH_80MHZ_PLUS_MHZ; - case IApInterfaceEventCallback.BANDWIDTH_160: - return SoftApInfo.CHANNEL_WIDTH_160MHZ; - default: - return SoftApInfo.CHANNEL_WIDTH_INVALID; - } - } - } - - /** - * Callback triggered by wificond. - */ - private class SendMgmtFrameEvent extends ISendMgmtFrameEvent.Stub { - private Executor mExecutor; - private SendMgmtFrameCallback mCallback; - private AlarmManager.OnAlarmListener mTimeoutCallback; - /** - * ensures that mCallback is only called once - */ - private boolean mWasCalled; - - private void runIfFirstCall(Runnable r) { - if (mWasCalled) return; - mWasCalled = true; - - mSendMgmtFrameInProgress.set(false); - r.run(); - } - - SendMgmtFrameEvent(@NonNull Executor executor, @NonNull SendMgmtFrameCallback callback) { - mExecutor = executor; - mCallback = callback; - // called in main thread - mTimeoutCallback = () -> runIfFirstCall(() -> { - if (mVerboseLoggingEnabled) { - Log.e(TAG, "Timed out waiting for ACK"); - } - Binder.clearCallingIdentity(); - mExecutor.execute(() -> mCallback.onFailure(SEND_MGMT_FRAME_ERROR_TIMEOUT)); - }); - mWasCalled = false; - - mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, - SystemClock.elapsedRealtime() + SEND_MGMT_FRAME_TIMEOUT_MS, - TIMEOUT_ALARM_TAG, mTimeoutCallback, mEventHandler); - } - - // called in binder thread - @Override - public void OnAck(int elapsedTimeMs) { - // post to main thread - mEventHandler.post(() -> runIfFirstCall(() -> { - mAlarmManager.cancel(mTimeoutCallback); - Binder.clearCallingIdentity(); - mExecutor.execute(() -> mCallback.onAck(elapsedTimeMs)); - })); - } - - // called in binder thread - @Override - public void OnFailure(int reason) { - // post to main thread - mEventHandler.post(() -> runIfFirstCall(() -> { - mAlarmManager.cancel(mTimeoutCallback); - Binder.clearCallingIdentity(); - mExecutor.execute(() -> mCallback.onFailure(reason)); - })); - } - } - - /** - * Called by the binder subsystem upon remote object death. - * Invoke all the register death handlers and clear state. - * @hide - */ - @VisibleForTesting - public void binderDied() { - mEventHandler.post(() -> { - Log.e(TAG, "Wificond died!"); - clearState(); - // Invalidate the global wificond handle on death. Will be refreshed - // on the next setup call. - mWificond = null; - if (mDeathEventHandler != null) { - mDeathEventHandler.run(); - } - }); - } - - /** - * Enable or disable verbose logging of the WifiNl80211Manager module. - * @param enable True to enable verbose logging. False to disable verbose logging. - */ - public void enableVerboseLogging(boolean enable) { - mVerboseLoggingEnabled = enable; - } - - /** - * Register a death notification for the WifiNl80211Manager which acts as a proxy for the - * wificond daemon (i.e. the death listener will be called when and if the wificond daemon - * dies). - * - * @param deathEventHandler A {@link Runnable} to be called whenever the wificond daemon dies. - */ - public void setOnServiceDeadCallback(@NonNull Runnable deathEventHandler) { - if (mDeathEventHandler != null) { - Log.e(TAG, "Death handler already present"); - } - mDeathEventHandler = deathEventHandler; - } - - /** - * Helper method to retrieve the global wificond handle and register for - * death notifications. - */ - private boolean retrieveWificondAndRegisterForDeath() { - if (mWificond != null) { - if (mVerboseLoggingEnabled) { - Log.d(TAG, "Wificond handle already retrieved"); - } - // We already have a wificond handle. - return true; - } - IBinder binder = ServiceManager.getService(Context.WIFI_NL80211_SERVICE); - mWificond = IWificond.Stub.asInterface(binder); - if (mWificond == null) { - Log.e(TAG, "Failed to get reference to wificond"); - return false; - } - try { - mWificond.asBinder().linkToDeath(() -> binderDied(), 0); - } catch (RemoteException e) { - Log.e(TAG, "Failed to register death notification for wificond"); - // The remote has already died. - return false; - } - return true; - } - - /** - * Set up an interface for client (STA) mode. - * - * @param ifaceName Name of the interface to configure. - * @param executor The Executor on which to execute the callbacks. - * @param scanCallback A callback for framework initiated scans. - * @param pnoScanCallback A callback for PNO (offloaded) scans. - * @return true on success. - */ - public boolean setupInterfaceForClientMode(@NonNull String ifaceName, - @NonNull @CallbackExecutor Executor executor, - @NonNull ScanEventCallback scanCallback, @NonNull ScanEventCallback pnoScanCallback) { - Log.d(TAG, "Setting up interface for client mode"); - if (!retrieveWificondAndRegisterForDeath()) { - return false; - } - - if (scanCallback == null || pnoScanCallback == null || executor == null) { - Log.e(TAG, "setupInterfaceForClientMode invoked with null callbacks"); - return false; - } - - IClientInterface clientInterface = null; - try { - clientInterface = mWificond.createClientInterface(ifaceName); - } catch (RemoteException e1) { - Log.e(TAG, "Failed to get IClientInterface due to remote exception"); - return false; - } - - if (clientInterface == null) { - Log.e(TAG, "Could not get IClientInterface instance from wificond"); - return false; - } - Binder.allowBlocking(clientInterface.asBinder()); - - // Refresh Handlers - mClientInterfaces.put(ifaceName, clientInterface); - try { - IWifiScannerImpl wificondScanner = clientInterface.getWifiScannerImpl(); - if (wificondScanner == null) { - Log.e(TAG, "Failed to get WificondScannerImpl"); - return false; - } - mWificondScanners.put(ifaceName, wificondScanner); - Binder.allowBlocking(wificondScanner.asBinder()); - ScanEventHandler scanEventHandler = new ScanEventHandler(executor, scanCallback); - mScanEventHandlers.put(ifaceName, scanEventHandler); - wificondScanner.subscribeScanEvents(scanEventHandler); - PnoScanEventHandler pnoScanEventHandler = new PnoScanEventHandler(executor, - pnoScanCallback); - mPnoScanEventHandlers.put(ifaceName, pnoScanEventHandler); - wificondScanner.subscribePnoScanEvents(pnoScanEventHandler); - } catch (RemoteException e) { - Log.e(TAG, "Failed to refresh wificond scanner due to remote exception"); - } - - return true; - } - - /** - * Tear down a specific client (STA) interface configured using - * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}. - * - * @param ifaceName Name of the interface to tear down. - * @return Returns true on success, false on failure (e.g. when called before an interface was - * set up). - */ - public boolean tearDownClientInterface(@NonNull String ifaceName) { - if (getClientInterface(ifaceName) == null) { - Log.e(TAG, "No valid wificond client interface handler"); - return false; - } - try { - IWifiScannerImpl scannerImpl = mWificondScanners.get(ifaceName); - if (scannerImpl != null) { - scannerImpl.unsubscribeScanEvents(); - scannerImpl.unsubscribePnoScanEvents(); - } - } catch (RemoteException e) { - Log.e(TAG, "Failed to unsubscribe wificond scanner due to remote exception"); - return false; - } - - if (mWificond == null) { - Log.e(TAG, "Reference to wifiCond is null"); - return false; - } - - boolean success; - try { - success = mWificond.tearDownClientInterface(ifaceName); - } catch (RemoteException e1) { - Log.e(TAG, "Failed to teardown client interface due to remote exception"); - return false; - } - if (!success) { - Log.e(TAG, "Failed to teardown client interface"); - return false; - } - - mClientInterfaces.remove(ifaceName); - mWificondScanners.remove(ifaceName); - mScanEventHandlers.remove(ifaceName); - mPnoScanEventHandlers.remove(ifaceName); - return true; - } - - /** - * Set up interface as a Soft AP. - * - * @param ifaceName Name of the interface to configure. - * @return true on success. - */ - public boolean setupInterfaceForSoftApMode(@NonNull String ifaceName) { - Log.d(TAG, "Setting up interface for soft ap mode"); - if (!retrieveWificondAndRegisterForDeath()) { - return false; - } - - IApInterface apInterface = null; - try { - apInterface = mWificond.createApInterface(ifaceName); - } catch (RemoteException e1) { - Log.e(TAG, "Failed to get IApInterface due to remote exception"); - return false; - } - - if (apInterface == null) { - Log.e(TAG, "Could not get IApInterface instance from wificond"); - return false; - } - Binder.allowBlocking(apInterface.asBinder()); - - // Refresh Handlers - mApInterfaces.put(ifaceName, apInterface); - return true; - } - - /** - * Tear down a Soft AP interface configured using - * {@link #setupInterfaceForSoftApMode(String)}. - * - * @param ifaceName Name of the interface to tear down. - * @return Returns true on success, false on failure (e.g. when called before an interface was - * set up). - */ - public boolean tearDownSoftApInterface(@NonNull String ifaceName) { - if (getApInterface(ifaceName) == null) { - Log.e(TAG, "No valid wificond ap interface handler"); - return false; - } - - if (mWificond == null) { - Log.e(TAG, "Reference to wifiCond is null"); - return false; - } - - boolean success; - try { - success = mWificond.tearDownApInterface(ifaceName); - } catch (RemoteException e1) { - Log.e(TAG, "Failed to teardown AP interface due to remote exception"); - return false; - } - if (!success) { - Log.e(TAG, "Failed to teardown AP interface"); - return false; - } - mApInterfaces.remove(ifaceName); - mApInterfaceListeners.remove(ifaceName); - return true; - } - - /** - * Tear down all interfaces, whether clients (STA) or Soft AP. - * - * @return Returns true on success. - */ - public boolean tearDownInterfaces() { - Log.d(TAG, "tearing down interfaces in wificond"); - // Explicitly refresh the wificodn handler because |tearDownInterfaces()| - // could be used to cleanup before we setup any interfaces. - if (!retrieveWificondAndRegisterForDeath()) { - return false; - } - - try { - for (Map.Entry entry : mWificondScanners.entrySet()) { - entry.getValue().unsubscribeScanEvents(); - entry.getValue().unsubscribePnoScanEvents(); - } - mWificond.tearDownInterfaces(); - clearState(); - return true; - } catch (RemoteException e) { - Log.e(TAG, "Failed to tear down interfaces due to remote exception"); - } - - return false; - } - - /** Helper function to look up the interface handle using name */ - private IClientInterface getClientInterface(@NonNull String ifaceName) { - return mClientInterfaces.get(ifaceName); - } - - /** - * Request signal polling. - * - * @param ifaceName Name of the interface on which to poll. The interface must have been - * already set up using - *{@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} - * or {@link #setupInterfaceForSoftApMode(String)}. - * - * @return A {@link SignalPollResult} object containing interface statistics, or a null on - * error (e.g. the interface hasn't been set up yet). - */ - @Nullable public SignalPollResult signalPoll(@NonNull String ifaceName) { - IClientInterface iface = getClientInterface(ifaceName); - if (iface == null) { - Log.e(TAG, "No valid wificond client interface handler"); - return null; - } - - int[] resultArray; - try { - resultArray = iface.signalPoll(); - if (resultArray == null || resultArray.length != 4) { - Log.e(TAG, "Invalid signal poll result from wificond"); - return null; - } - } catch (RemoteException e) { - Log.e(TAG, "Failed to do signal polling due to remote exception"); - return null; - } - return new SignalPollResult(resultArray[0], resultArray[1], resultArray[3], resultArray[2]); - } - - /** - * Get current transmit (Tx) packet counters of the specified interface. The interface must - * have been already set up using - * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} - * or {@link #setupInterfaceForSoftApMode(String)}. - * - * @param ifaceName Name of the interface. - * @return {@link TxPacketCounters} of the current interface or null on error (e.g. when - * called before the interface has been set up). - */ - @Nullable public TxPacketCounters getTxPacketCounters(@NonNull String ifaceName) { - IClientInterface iface = getClientInterface(ifaceName); - if (iface == null) { - Log.e(TAG, "No valid wificond client interface handler"); - return null; - } - - int[] resultArray; - try { - resultArray = iface.getPacketCounters(); - if (resultArray == null || resultArray.length != 2) { - Log.e(TAG, "Invalid signal poll result from wificond"); - return null; - } - } catch (RemoteException e) { - Log.e(TAG, "Failed to do signal polling due to remote exception"); - return null; - } - return new TxPacketCounters(resultArray[0], resultArray[1]); - } - - /** Helper function to look up the scanner impl handle using name */ - private IWifiScannerImpl getScannerImpl(@NonNull String ifaceName) { - return mWificondScanners.get(ifaceName); - } - - /** - * Fetch the latest scan results of the indicated type for the specified interface. Note that - * this method fetches the latest results - it does not initiate a scan. Initiating a scan can - * be done using {@link #startScan(String, int, Set, List)} or - * {@link #startPnoScan(String, PnoSettings, Executor, PnoScanRequestCallback)}. - * - * Note: The interface must have been already set up using - * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} - * or {@link #setupInterfaceForSoftApMode(String)}. - * - * @param ifaceName Name of the interface. - * @param scanType The type of scan result to be returned, can be - * {@link #SCAN_TYPE_SINGLE_SCAN} or {@link #SCAN_TYPE_PNO_SCAN}. - * @return Returns an array of {@link NativeScanResult} or an empty array on failure (e.g. when - * called before the interface has been set up). - */ - @NonNull public List getScanResults(@NonNull String ifaceName, - @ScanResultType int scanType) { - IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); - if (scannerImpl == null) { - Log.e(TAG, "No valid wificond scanner interface handler"); - return new ArrayList<>(); - } - List results = null; - try { - if (scanType == SCAN_TYPE_SINGLE_SCAN) { - results = Arrays.asList(scannerImpl.getScanResults()); - } else { - results = Arrays.asList(scannerImpl.getPnoScanResults()); - } - } catch (RemoteException e1) { - Log.e(TAG, "Failed to create ScanDetail ArrayList"); - } - if (results == null) { - results = new ArrayList<>(); - } - if (mVerboseLoggingEnabled) { - Log.d(TAG, "get " + results.size() + " scan results from wificond"); - } - - return results; - } - - /** - * Return scan type for the parcelable {@link SingleScanSettings} - */ - private static int getScanType(@WifiAnnotations.ScanType int scanType) { - switch (scanType) { - case WifiScanner.SCAN_TYPE_LOW_LATENCY: - return IWifiScannerImpl.SCAN_TYPE_LOW_SPAN; - case WifiScanner.SCAN_TYPE_LOW_POWER: - return IWifiScannerImpl.SCAN_TYPE_LOW_POWER; - case WifiScanner.SCAN_TYPE_HIGH_ACCURACY: - return IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY; - default: - throw new IllegalArgumentException("Invalid scan type " + scanType); - } - } - - /** - * Start a scan using the specified parameters. A scan is an asynchronous operation. The - * result of the operation is returned in the {@link ScanEventCallback} registered when - * setting up an interface using - * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}. - * The latest scans can be obtained using {@link #getScanResults(String, int)} and using a - * {@link #SCAN_TYPE_SINGLE_SCAN} for the {@code scanType}. - * - * Note: The interface must have been already set up using - * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} - * or {@link #setupInterfaceForSoftApMode(String)}. - * - * @param ifaceName Name of the interface on which to initiate the scan. - * @param scanType Type of scan to perform, can be any of - * {@link WifiScanner#SCAN_TYPE_HIGH_ACCURACY}, {@link WifiScanner#SCAN_TYPE_LOW_POWER}, or - * {@link WifiScanner#SCAN_TYPE_LOW_LATENCY}. - * @param freqs list of frequencies to scan for, if null scan all supported channels. - * @param hiddenNetworkSSIDs List of hidden networks to be scanned for, a null indicates that - * no hidden frequencies will be scanned for. - * @return Returns true on success, false on failure (e.g. when called before the interface - * has been set up). - */ - public boolean startScan(@NonNull String ifaceName, @WifiAnnotations.ScanType int scanType, - @Nullable Set freqs, @Nullable List hiddenNetworkSSIDs) { - IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); - if (scannerImpl == null) { - Log.e(TAG, "No valid wificond scanner interface handler"); - return false; - } - SingleScanSettings settings = new SingleScanSettings(); - try { - settings.scanType = getScanType(scanType); - } catch (IllegalArgumentException e) { - Log.e(TAG, "Invalid scan type ", e); - return false; - } - settings.channelSettings = new ArrayList<>(); - settings.hiddenNetworks = new ArrayList<>(); - - if (freqs != null) { - for (Integer freq : freqs) { - ChannelSettings channel = new ChannelSettings(); - channel.frequency = freq; - settings.channelSettings.add(channel); - } - } - if (hiddenNetworkSSIDs != null) { - for (byte[] ssid : hiddenNetworkSSIDs) { - HiddenNetwork network = new HiddenNetwork(); - network.ssid = ssid; - - // settings.hiddenNetworks is expected to be very small, so this shouldn't cause - // any performance issues. - if (!settings.hiddenNetworks.contains(network)) { - settings.hiddenNetworks.add(network); - } - } - } - - try { - return scannerImpl.scan(settings); - } catch (RemoteException e1) { - Log.e(TAG, "Failed to request scan due to remote exception"); - } - return false; - } - - /** - * Request a PNO (Preferred Network Offload). The offload request and the scans are asynchronous - * operations. The result of the request are returned in the {@code callback} parameter which - * is an {@link PnoScanRequestCallback}. The scan results are are return in the - * {@link ScanEventCallback} which is registered when setting up an interface using - * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}. - * The latest PNO scans can be obtained using {@link #getScanResults(String, int)} with the - * {@code scanType} set to {@link #SCAN_TYPE_PNO_SCAN}. - * - * Note: The interface must have been already set up using - * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} - * or {@link #setupInterfaceForSoftApMode(String)}. - * - * @param ifaceName Name of the interface on which to request a PNO. - * @param pnoSettings PNO scan configuration. - * @param executor The Executor on which to execute the callback. - * @param callback Callback for the results of the offload request. - * @return true on success, false on failure (e.g. when called before the interface has been set - * up). - */ - public boolean startPnoScan(@NonNull String ifaceName, @NonNull PnoSettings pnoSettings, - @NonNull @CallbackExecutor Executor executor, - @NonNull PnoScanRequestCallback callback) { - IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); - if (scannerImpl == null) { - Log.e(TAG, "No valid wificond scanner interface handler"); - return false; - } - - if (callback == null || executor == null) { - Log.e(TAG, "startPnoScan called with a null callback"); - return false; - } - - try { - boolean success = scannerImpl.startPnoScan(pnoSettings); - if (success) { - executor.execute(callback::onPnoRequestSucceeded); - } else { - executor.execute(callback::onPnoRequestFailed); - } - return success; - } catch (RemoteException e1) { - Log.e(TAG, "Failed to start pno scan due to remote exception"); - } - return false; - } - - /** - * Stop PNO scan configured with - * {@link #startPnoScan(String, PnoSettings, Executor, PnoScanRequestCallback)}. - * - * Note: The interface must have been already set up using - * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} - * or {@link #setupInterfaceForSoftApMode(String)}. - * - * @param ifaceName Name of the interface on which the PNO scan was configured. - * @return true on success, false on failure (e.g. when called before the interface has been - * set up). - */ - public boolean stopPnoScan(@NonNull String ifaceName) { - IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); - if (scannerImpl == null) { - Log.e(TAG, "No valid wificond scanner interface handler"); - return false; - } - try { - return scannerImpl.stopPnoScan(); - } catch (RemoteException e1) { - Log.e(TAG, "Failed to stop pno scan due to remote exception"); - } - return false; - } - - /** - * Abort ongoing single scan started with {@link #startScan(String, int, Set, List)}. No failure - * callback, e.g. {@link ScanEventCallback#onScanFailed()}, is triggered by this operation. - * - * Note: The interface must have been already set up using - * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} - * or {@link #setupInterfaceForSoftApMode(String)}. If the interface has not been set up then - * this method has no impact. - * - * @param ifaceName Name of the interface on which the scan was started. - */ - public void abortScan(@NonNull String ifaceName) { - IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); - if (scannerImpl == null) { - Log.e(TAG, "No valid wificond scanner interface handler"); - return; - } - try { - scannerImpl.abortScan(); - } catch (RemoteException e1) { - Log.e(TAG, "Failed to request abortScan due to remote exception"); - } - } - - /** - * Query the list of valid frequencies (in MHz) for the provided band. - * The result depends on the on the country code that has been set. - * - * @param band as specified by one of the WifiScanner.WIFI_BAND_* constants. - * The following bands are supported {@link @WifiScanner.WifiBandBasic}: - * WifiScanner.WIFI_BAND_24_GHZ - * WifiScanner.WIFI_BAND_5_GHZ - * WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY - * WifiScanner.WIFI_BAND_6_GHZ - * @return frequencies vector of valid frequencies (MHz), or an empty array for error. - * @throws IllegalArgumentException if band is not recognized. - */ - public @NonNull int[] getChannelsMhzForBand(@WifiAnnotations.WifiBandBasic int band) { - if (mWificond == null) { - Log.e(TAG, "No valid wificond scanner interface handler"); - return new int[0]; - } - int[] result = null; - try { - switch (band) { - case WifiScanner.WIFI_BAND_24_GHZ: - result = mWificond.getAvailable2gChannels(); - break; - case WifiScanner.WIFI_BAND_5_GHZ: - result = mWificond.getAvailable5gNonDFSChannels(); - break; - case WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY: - result = mWificond.getAvailableDFSChannels(); - break; - case WifiScanner.WIFI_BAND_6_GHZ: - result = mWificond.getAvailable6gChannels(); - break; - default: - throw new IllegalArgumentException("unsupported band " + band); - } - } catch (RemoteException e1) { - Log.e(TAG, "Failed to request getChannelsForBand due to remote exception"); - } - if (result == null) { - result = new int[0]; - } - return result; - } - - /** Helper function to look up the interface handle using name */ - private IApInterface getApInterface(@NonNull String ifaceName) { - return mApInterfaces.get(ifaceName); - } - - /** - * Get the device phy capabilities for a given interface. - * - * Note: The interface must have been already set up using - * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} - * or {@link #setupInterfaceForSoftApMode(String)}. - * - * @return DeviceWiphyCapabilities or null on error (e.g. when called on an interface which has - * not been set up). - */ - @Nullable public DeviceWiphyCapabilities getDeviceWiphyCapabilities(@NonNull String ifaceName) { - if (mWificond == null) { - Log.e(TAG, "Can not query for device wiphy capabilities at this time"); - return null; - } - - try { - return mWificond.getDeviceWiphyCapabilities(ifaceName); - } catch (RemoteException e) { - return null; - } - } - - /** - * Register the provided callback handler for SoftAp events. The interface must first be created - * using {@link #setupInterfaceForSoftApMode(String)}. The callback registration is valid until - * the interface is deleted using {@link #tearDownSoftApInterface(String)} (no deregistration - * method is provided). - *

    - * Note that only one callback can be registered at a time - any registration overrides previous - * registrations. - * - * @param ifaceName Name of the interface on which to register the callback. - * @param executor The Executor on which to execute the callbacks. - * @param callback Callback for AP events. - * @return true on success, false on failure (e.g. when called on an interface which has not - * been set up). - */ - public boolean registerApCallback(@NonNull String ifaceName, - @NonNull @CallbackExecutor Executor executor, - @NonNull SoftApCallback callback) { - IApInterface iface = getApInterface(ifaceName); - if (iface == null) { - Log.e(TAG, "No valid ap interface handler"); - return false; - } - - if (callback == null || executor == null) { - Log.e(TAG, "registerApCallback called with a null callback"); - return false; - } - - try { - IApInterfaceEventCallback wificondCallback = new ApInterfaceEventCallback(executor, - callback); - mApInterfaceListeners.put(ifaceName, wificondCallback); - boolean success = iface.registerCallback(wificondCallback); - if (!success) { - Log.e(TAG, "Failed to register ap callback."); - return false; - } - } catch (RemoteException e) { - Log.e(TAG, "Exception in registering AP callback: " + e); - return false; - } - return true; - } - - /** - * Send a management frame on the specified interface at the specified rate. Useful for probing - * the link with arbitrary frames. - * - * Note: The interface must have been already set up using - * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)} - * or {@link #setupInterfaceForSoftApMode(String)}. - * - * @param ifaceName The interface on which to send the frame. - * @param frame The raw byte array of the management frame to tramit. - * @param mcs The MCS (modulation and coding scheme), i.e. rate, at which to transmit the - * frame. Specified per IEEE 802.11. - * @param executor The Executor on which to execute the callbacks. - * @param callback A {@link SendMgmtFrameCallback} callback for results of the operation. - */ - public void sendMgmtFrame(@NonNull String ifaceName, @NonNull byte[] frame, int mcs, - @NonNull @CallbackExecutor Executor executor, - @NonNull SendMgmtFrameCallback callback) { - - if (callback == null || executor == null) { - Log.e(TAG, "callback cannot be null!"); - return; - } - - if (frame == null) { - Log.e(TAG, "frame cannot be null!"); - executor.execute(() -> callback.onFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN)); - return; - } - - // TODO (b/112029045) validate mcs - IClientInterface clientInterface = getClientInterface(ifaceName); - if (clientInterface == null) { - Log.e(TAG, "No valid wificond client interface handler"); - executor.execute(() -> callback.onFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN)); - return; - } - - if (!mSendMgmtFrameInProgress.compareAndSet(false, true)) { - Log.e(TAG, "An existing management frame transmission is in progress!"); - executor.execute(() -> callback.onFailure(SEND_MGMT_FRAME_ERROR_ALREADY_STARTED)); - return; - } - - SendMgmtFrameEvent sendMgmtFrameEvent = new SendMgmtFrameEvent(executor, callback); - try { - clientInterface.SendMgmtFrame(frame, sendMgmtFrameEvent, mcs); - } catch (RemoteException e) { - Log.e(TAG, "Exception while starting link probe: " + e); - // Call sendMgmtFrameEvent.OnFailure() instead of callback.onFailure() so that - // sendMgmtFrameEvent can clean up internal state, such as cancelling the timer. - sendMgmtFrameEvent.OnFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN); - } - } - - /** - * Clear all internal handles. - */ - private void clearState() { - // Refresh handlers - mClientInterfaces.clear(); - mWificondScanners.clear(); - mPnoScanEventHandlers.clear(); - mScanEventHandlers.clear(); - mApInterfaces.clear(); - mApInterfaceListeners.clear(); - mSendMgmtFrameInProgress.set(false); - } - - /** - * OEM parsed security type - */ - public static class OemSecurityType { - /** The protocol defined in {@link android.net.wifi.WifiAnnotations.Protocol}. */ - public final @WifiAnnotations.Protocol int protocol; - /** - * Supported key management types defined - * in {@link android.net.wifi.WifiAnnotations.KeyMgmt}. - */ - @NonNull public final List keyManagement; - /** - * Supported pairwise cipher types defined - * in {@link android.net.wifi.WifiAnnotations.Cipher}. - */ - @NonNull public final List pairwiseCipher; - /** The group cipher type defined in {@link android.net.wifi.WifiAnnotations.Cipher}. */ - public final @WifiAnnotations.Cipher int groupCipher; - /** - * Default constructor for OemSecurityType - * - * @param protocol The protocol defined in - * {@link android.net.wifi.WifiAnnotations.Protocol}. - * @param keyManagement Supported key management types defined - * in {@link android.net.wifi.WifiAnnotations.KeyMgmt}. - * @param pairwiseCipher Supported pairwise cipher types defined - * in {@link android.net.wifi.WifiAnnotations.Cipher}. - * @param groupCipher The group cipher type defined - * in {@link android.net.wifi.WifiAnnotations.Cipher}. - */ - public OemSecurityType( - @WifiAnnotations.Protocol int protocol, - @NonNull List keyManagement, - @NonNull List pairwiseCipher, - @WifiAnnotations.Cipher int groupCipher) { - this.protocol = protocol; - this.keyManagement = (keyManagement != null) - ? keyManagement : new ArrayList(); - this.pairwiseCipher = (pairwiseCipher != null) - ? pairwiseCipher : new ArrayList(); - this.groupCipher = groupCipher; - } - } - - /** - * OEM information element parser for security types not parsed by the framework. - * - * The OEM method should use the method inputs {@code id}, {@code idExt}, and {@code bytes} - * to perform the parsing. The method should place the results in an OemSecurityType objct. - * - * @param id The information element id. - * @param idExt The information element extension id. This is valid only when id is - * the extension id, {@code 255}. - * @param bytes The raw bytes of information element data, 'Element ID' and 'Length' are - * stripped off already. - * @return an OemSecurityType object if this IE is parsed successfully, null otherwise. - */ - @Nullable public static OemSecurityType parseOemSecurityTypeElement( - int id, - int idExt, - @NonNull byte[] bytes) { - return null; - } -} diff --git a/wifi/tests/src/android/net/wifi/nl80211/DeviceWiphyCapabilitiesTest.java b/wifi/tests/src/android/net/wifi/nl80211/DeviceWiphyCapabilitiesTest.java new file mode 100644 index 000000000000..7b900fec70a8 --- /dev/null +++ b/wifi/tests/src/android/net/wifi/nl80211/DeviceWiphyCapabilitiesTest.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2020 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.nl80211; + +import static org.junit.Assert.assertEquals; + +import android.net.wifi.ScanResult; +import android.os.Parcel; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link android.net.wifi.nl80211.DeviceWiphyCapabilities}. + */ +@SmallTest +public class DeviceWiphyCapabilitiesTest { + @Before + public void setUp() {} + + /** + * DeviceWiphyCapabilities object can be serialized and deserialized, while keeping the + * values unchanged. + */ + @Test + public void canSerializeAndDeserialize() { + DeviceWiphyCapabilities capa = new DeviceWiphyCapabilities(); + + capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, true); + capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, true); + capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AX, false); + capa.setChannelWidthSupported(ScanResult.CHANNEL_WIDTH_160MHZ, true); + capa.setChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ, false); + capa.setMaxNumberTxSpatialStreams(2); + capa.setMaxNumberRxSpatialStreams(1); + + Parcel parcel = Parcel.obtain(); + capa.writeToParcel(parcel, 0); + // Rewind the pointer to the head of the parcel. + parcel.setDataPosition(0); + DeviceWiphyCapabilities capaDeserialized = + DeviceWiphyCapabilities.CREATOR.createFromParcel(parcel); + + assertEquals(capa, capaDeserialized); + assertEquals(capa.hashCode(), capaDeserialized.hashCode()); + } + + /** + * Test mapping wifi standard support into channel width support + */ + @Test + public void testMappingWifiStandardIntoChannelWidthSupport() { + DeviceWiphyCapabilities capa = new DeviceWiphyCapabilities(); + + capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, false); + capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, false); + capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AX, false); + assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_20MHZ)); + assertEquals(false, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_40MHZ)); + assertEquals(false, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ)); + + capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, true); + assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_20MHZ)); + assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_40MHZ)); + assertEquals(false, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ)); + + capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, true); + assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_20MHZ)); + assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_40MHZ)); + assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ)); + } +} diff --git a/wifi/tests/src/android/net/wifi/nl80211/NativeScanResultTest.java b/wifi/tests/src/android/net/wifi/nl80211/NativeScanResultTest.java new file mode 100644 index 000000000000..8ddd1899179a --- /dev/null +++ b/wifi/tests/src/android/net/wifi/nl80211/NativeScanResultTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.nl80211; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import android.os.Parcel; + +import androidx.test.filters.SmallTest; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; + +/** + * Unit tests for {@link android.net.wifi.nl80211.NativeScanResult}. + */ +@SmallTest +public class NativeScanResultTest { + + private static final byte[] TEST_SSID = + new byte[] {'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'}; + private static final byte[] TEST_BSSID = + new byte[] {(byte) 0x12, (byte) 0xef, (byte) 0xa1, + (byte) 0x2c, (byte) 0x97, (byte) 0x8b}; + private static final byte[] TEST_INFO_ELEMENT = + new byte[] {(byte) 0x01, (byte) 0x03, (byte) 0x12, (byte) 0xbe, (byte) 0xff}; + private static final int TEST_FREQUENCY = 2456; + private static final int TEST_SIGNAL_MBM = -45; + private static final long TEST_TSF = 34455441; + private static final int TEST_CAPABILITY = (0x1 << 2) | (0x1 << 5); + private static final boolean TEST_ASSOCIATED = true; + private static final int[] RADIO_CHAIN_IDS = { 0, 1 }; + private static final int[] RADIO_CHAIN_LEVELS = { -56, -65 }; + + /** + * NativeScanResult object can be serialized and deserialized, while keeping the + * values unchanged. + */ + @Test + public void canSerializeAndDeserialize() { + NativeScanResult scanResult = new NativeScanResult(); + scanResult.ssid = TEST_SSID; + scanResult.bssid = TEST_BSSID; + scanResult.infoElement = TEST_INFO_ELEMENT; + scanResult.frequency = TEST_FREQUENCY; + scanResult.signalMbm = TEST_SIGNAL_MBM; + scanResult.tsf = TEST_TSF; + scanResult.capability = TEST_CAPABILITY; + scanResult.associated = TEST_ASSOCIATED; + scanResult.radioChainInfos = new ArrayList<>(Arrays.asList( + new RadioChainInfo(RADIO_CHAIN_IDS[0], RADIO_CHAIN_LEVELS[0]), + new RadioChainInfo(RADIO_CHAIN_IDS[1], RADIO_CHAIN_LEVELS[1]))); + Parcel parcel = Parcel.obtain(); + scanResult.writeToParcel(parcel, 0); + // Rewind the pointer to the head of the parcel. + parcel.setDataPosition(0); + NativeScanResult scanResultDeserialized = NativeScanResult.CREATOR.createFromParcel(parcel); + + assertArrayEquals(scanResult.ssid, scanResultDeserialized.ssid); + assertArrayEquals(scanResult.bssid, scanResultDeserialized.bssid); + assertArrayEquals(scanResult.infoElement, scanResultDeserialized.infoElement); + assertEquals(scanResult.frequency, scanResultDeserialized.frequency); + assertEquals(scanResult.signalMbm, scanResultDeserialized.signalMbm); + assertEquals(scanResult.tsf, scanResultDeserialized.tsf); + assertEquals(scanResult.capability, scanResultDeserialized.capability); + assertEquals(scanResult.associated, scanResultDeserialized.associated); + assertTrue(scanResult.radioChainInfos.containsAll(scanResultDeserialized.radioChainInfos)); + } +} diff --git a/wifi/tests/src/android/net/wifi/nl80211/PnoSettingsTest.java b/wifi/tests/src/android/net/wifi/nl80211/PnoSettingsTest.java new file mode 100644 index 000000000000..dec1db8d274e --- /dev/null +++ b/wifi/tests/src/android/net/wifi/nl80211/PnoSettingsTest.java @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.nl80211; + +import static org.junit.Assert.assertEquals; + +import android.os.Parcel; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; + +/** + * Unit tests for {@link android.net.wifi.nl80211.PnoSettings}. + */ +@SmallTest +public class PnoSettingsTest { + + private static final byte[] TEST_SSID_1 = + new byte[] {'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'}; + private static final byte[] TEST_SSID_2 = + new byte[] {'A', 'n', 'd', 'r', 'o', 'i', 'd', 'T', 'e', 's', 't'}; + private static final int[] TEST_FREQUENCIES_1 = {}; + private static final int[] TEST_FREQUENCIES_2 = {2500, 5124}; + private static final int TEST_INTERVAL_MS = 30000; + private static final int TEST_MIN_2G_RSSI = -60; + private static final int TEST_MIN_5G_RSSI = -65; + private static final int TEST_VALUE = 42; + + private PnoNetwork mPnoNetwork1; + private PnoNetwork mPnoNetwork2; + + @Before + public void setUp() { + mPnoNetwork1 = new PnoNetwork(); + mPnoNetwork1.setSsid(TEST_SSID_1); + mPnoNetwork1.setHidden(true); + mPnoNetwork1.setFrequenciesMhz(TEST_FREQUENCIES_1); + + mPnoNetwork2 = new PnoNetwork(); + mPnoNetwork2.setSsid(TEST_SSID_2); + mPnoNetwork2.setHidden(false); + mPnoNetwork2.setFrequenciesMhz(TEST_FREQUENCIES_2); + } + + /** + * PnoSettings object can be serialized and deserialized, while keeping the + * values unchanged. + */ + @Test + public void canSerializeAndDeserialize() { + PnoSettings pnoSettings = new PnoSettings(); + pnoSettings.setIntervalMillis(TEST_INTERVAL_MS); + pnoSettings.setMin2gRssiDbm(TEST_MIN_2G_RSSI); + pnoSettings.setMin5gRssiDbm(TEST_MIN_5G_RSSI); + pnoSettings.setPnoNetworks(new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2))); + + Parcel parcel = Parcel.obtain(); + pnoSettings.writeToParcel(parcel, 0); + // Rewind the pointer to the head of the parcel. + parcel.setDataPosition(0); + PnoSettings pnoSettingsDeserialized = PnoSettings.CREATOR.createFromParcel(parcel); + + assertEquals(pnoSettings, pnoSettingsDeserialized); + assertEquals(pnoSettings.hashCode(), pnoSettingsDeserialized.hashCode()); + } + + /** + * Tests usage of {@link PnoSettings} as a HashMap key type. + */ + @Test + public void testAsHashMapKey() { + PnoSettings pnoSettings1 = new PnoSettings(); + pnoSettings1.setIntervalMillis(TEST_INTERVAL_MS); + pnoSettings1.setMin2gRssiDbm(TEST_MIN_2G_RSSI); + pnoSettings1.setMin5gRssiDbm(TEST_MIN_5G_RSSI); + pnoSettings1.setPnoNetworks(new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2))); + + PnoSettings pnoSettings2 = new PnoSettings(); + pnoSettings2.setIntervalMillis(TEST_INTERVAL_MS); + pnoSettings2.setMin2gRssiDbm(TEST_MIN_2G_RSSI); + pnoSettings2.setMin5gRssiDbm(TEST_MIN_5G_RSSI); + pnoSettings2.setPnoNetworks(new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2))); + + assertEquals(pnoSettings1, pnoSettings2); + assertEquals(pnoSettings1.hashCode(), pnoSettings2.hashCode()); + + HashMap map = new HashMap<>(); + map.put(pnoSettings1, TEST_VALUE); + + assertEquals(TEST_VALUE, map.get(pnoSettings2).intValue()); + } +} diff --git a/wifi/tests/src/android/net/wifi/nl80211/SingleScanSettingsTest.java b/wifi/tests/src/android/net/wifi/nl80211/SingleScanSettingsTest.java new file mode 100644 index 000000000000..905920888012 --- /dev/null +++ b/wifi/tests/src/android/net/wifi/nl80211/SingleScanSettingsTest.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.nl80211; + +import static org.junit.Assert.assertEquals; + +import android.os.Parcel; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; + +/** + * Unit tests for {@link android.net.wifi.nl80211.SingleScanSettingsResult}. + */ +@SmallTest +public class SingleScanSettingsTest { + + private static final byte[] TEST_SSID_1 = + new byte[] {'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'}; + private static final byte[] TEST_SSID_2 = + new byte[] {'A', 'n', 'd', 'r', 'o', 'i', 'd', 'T', 'e', 's', 't'}; + private static final int TEST_FREQUENCY_1 = 2456; + private static final int TEST_FREQUENCY_2 = 5215; + private static final int TEST_VALUE = 42; + + private ChannelSettings mChannelSettings1; + private ChannelSettings mChannelSettings2; + private HiddenNetwork mHiddenNetwork1; + private HiddenNetwork mHiddenNetwork2; + + @Before + public void setUp() { + mChannelSettings1 = new ChannelSettings(); + mChannelSettings1.frequency = TEST_FREQUENCY_1; + mChannelSettings2 = new ChannelSettings(); + mChannelSettings2.frequency = TEST_FREQUENCY_2; + + mHiddenNetwork1 = new HiddenNetwork(); + mHiddenNetwork1.ssid = TEST_SSID_1; + mHiddenNetwork2 = new HiddenNetwork(); + mHiddenNetwork2.ssid = TEST_SSID_2; + } + + /** + * SingleScanSettings object can be serialized and deserialized, while keeping the + * values unchanged. + */ + @Test + public void canSerializeAndDeserialize() { + SingleScanSettings scanSettings = new SingleScanSettings(); + scanSettings.scanType = IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY; + + scanSettings.channelSettings = + new ArrayList<>(Arrays.asList(mChannelSettings1, mChannelSettings2)); + scanSettings.hiddenNetworks = + new ArrayList<>(Arrays.asList(mHiddenNetwork1, mHiddenNetwork2)); + + Parcel parcel = Parcel.obtain(); + scanSettings.writeToParcel(parcel, 0); + // Rewind the pointer to the head of the parcel. + parcel.setDataPosition(0); + SingleScanSettings scanSettingsDeserialized = + SingleScanSettings.CREATOR.createFromParcel(parcel); + + assertEquals(scanSettings, scanSettingsDeserialized); + assertEquals(scanSettings.hashCode(), scanSettingsDeserialized.hashCode()); + } + + /** + * Tests usage of {@link SingleScanSettings} as a HashMap key type. + */ + @Test + public void testAsHashMapKey() { + SingleScanSettings scanSettings1 = new SingleScanSettings(); + scanSettings1.scanType = IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY; + scanSettings1.channelSettings = + new ArrayList<>(Arrays.asList(mChannelSettings1, mChannelSettings2)); + scanSettings1.hiddenNetworks = + new ArrayList<>(Arrays.asList(mHiddenNetwork1, mHiddenNetwork2)); + + SingleScanSettings scanSettings2 = new SingleScanSettings(); + scanSettings2.scanType = IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY; + scanSettings2.channelSettings = + new ArrayList<>(Arrays.asList(mChannelSettings1, mChannelSettings2)); + scanSettings2.hiddenNetworks = + new ArrayList<>(Arrays.asList(mHiddenNetwork1, mHiddenNetwork2)); + + assertEquals(scanSettings1, scanSettings2); + assertEquals(scanSettings1.hashCode(), scanSettings2.hashCode()); + + HashMap map = new HashMap<>(); + map.put(scanSettings1, TEST_VALUE); + + assertEquals(TEST_VALUE, map.get(scanSettings2).intValue()); + } +} diff --git a/wifi/tests/src/android/net/wifi/nl80211/WifiNl80211ManagerTest.java b/wifi/tests/src/android/net/wifi/nl80211/WifiNl80211ManagerTest.java new file mode 100644 index 000000000000..9ee0acbfbaa2 --- /dev/null +++ b/wifi/tests/src/android/net/wifi/nl80211/WifiNl80211ManagerTest.java @@ -0,0 +1,1265 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.nl80211; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Matchers.argThat; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyLong; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +import android.app.AlarmManager; +import android.app.test.TestAlarmManager; +import android.content.Context; +import android.net.MacAddress; +import android.net.wifi.ScanResult; +import android.net.wifi.SoftApInfo; +import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiScanner; +import android.net.wifi.util.HexEncoding; +import android.os.Handler; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.test.TestLooper; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.AdditionalMatchers; +import org.mockito.ArgumentCaptor; +import org.mockito.ArgumentMatcher; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.CharacterCodingException; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Unit tests for {@link android.net.wifi.nl80211.WifiNl80211Manager}. + */ +@SmallTest +public class WifiNl80211ManagerTest { + @Mock + private IWificond mWificond; + @Mock + private IBinder mWifiCondBinder; + @Mock + private IClientInterface mClientInterface; + @Mock + private IWifiScannerImpl mWifiScannerImpl; + @Mock + private IApInterface mApInterface; + @Mock + private WifiNl80211Manager.SoftApCallback mSoftApListener; + @Mock + private WifiNl80211Manager.SendMgmtFrameCallback mSendMgmtFrameCallback; + @Mock + private WifiNl80211Manager.ScanEventCallback mNormalScanCallback; + @Mock + private WifiNl80211Manager.ScanEventCallback mPnoScanCallback; + @Mock + private WifiNl80211Manager.PnoScanRequestCallback mPnoScanRequestCallback; + @Mock + private Context mContext; + private TestLooper mLooper; + private TestAlarmManager mTestAlarmManager; + private AlarmManager mAlarmManager; + private WifiNl80211Manager mWificondControl; + private static final String TEST_INTERFACE_NAME = "test_wlan_if"; + private static final String TEST_INTERFACE_NAME1 = "test_wlan_if1"; + private static final String TEST_INVALID_INTERFACE_NAME = "asdf"; + private static final byte[] TEST_SSID = + new byte[]{'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'}; + private static final byte[] TEST_PSK = + new byte[]{'T', 'e', 's', 't'}; + + private static final Set SCAN_FREQ_SET = + new HashSet() {{ + add(2410); + add(2450); + add(5050); + add(5200); + }}; + private static final String TEST_QUOTED_SSID_1 = "\"testSsid1\""; + private static final String TEST_QUOTED_SSID_2 = "\"testSsid2\""; + private static final int[] TEST_FREQUENCIES_1 = {}; + private static final int[] TEST_FREQUENCIES_2 = {2500, 5124}; + private static final MacAddress TEST_RAW_MAC_BYTES = MacAddress.fromBytes( + new byte[]{0x00, 0x01, 0x02, 0x03, 0x04, 0x05}); + + private static final List SCAN_HIDDEN_NETWORK_SSID_LIST = + new ArrayList() {{ + add(LocalNativeUtil.byteArrayFromArrayList( + LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_1))); + add(LocalNativeUtil.byteArrayFromArrayList( + LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_2))); + }}; + + private static final PnoSettings TEST_PNO_SETTINGS = new PnoSettings(); + static { + TEST_PNO_SETTINGS.setIntervalMillis(6000); + List initPnoNetworks = new ArrayList<>(); + PnoNetwork network = new PnoNetwork(); + network.setSsid(LocalNativeUtil.byteArrayFromArrayList( + LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_1))); + network.setHidden(true); + network.setFrequenciesMhz(TEST_FREQUENCIES_1); + initPnoNetworks.add(network); + network.setSsid(LocalNativeUtil.byteArrayFromArrayList( + LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_2))); + network.setHidden(false); + network.setFrequenciesMhz(TEST_FREQUENCIES_2); + initPnoNetworks.add(network); + TEST_PNO_SETTINGS.setPnoNetworks(initPnoNetworks); + } + + private static final int TEST_MCS_RATE = 5; + private static final int TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS = 100; + private static final byte[] TEST_PROBE_FRAME = { + 0x40, 0x00, 0x3c, 0x00, (byte) 0xa8, (byte) 0xbd, 0x27, 0x5b, + 0x33, 0x72, (byte) 0xf4, (byte) 0xf5, (byte) 0xe8, 0x51, (byte) 0x9e, 0x09, + (byte) 0xa8, (byte) 0xbd, 0x27, 0x5b, 0x33, 0x72, (byte) 0xb0, 0x66, + 0x00, 0x00 + }; + + @Before + public void setUp() throws Exception { + // Setup mocks for successful WificondControl operation. Failure case mocks should be + // created in specific tests + MockitoAnnotations.initMocks(this); + + mTestAlarmManager = new TestAlarmManager(); + mAlarmManager = mTestAlarmManager.getAlarmManager(); + when(mContext.getSystemServiceName(AlarmManager.class)).thenReturn(Context.ALARM_SERVICE); + when(mContext.getSystemService(AlarmManager.class)).thenReturn(mAlarmManager); + + mLooper = new TestLooper(); + when(mContext.getMainLooper()).thenReturn(mLooper.getLooper()); + + when(mWificond.asBinder()).thenReturn(mWifiCondBinder); + when(mClientInterface.getWifiScannerImpl()).thenReturn(mWifiScannerImpl); + when(mWificond.createClientInterface(any())).thenReturn(mClientInterface); + when(mWificond.createApInterface(any())).thenReturn(mApInterface); + when(mWificond.tearDownClientInterface(any())).thenReturn(true); + when(mWificond.tearDownApInterface(any())).thenReturn(true); + when(mClientInterface.getWifiScannerImpl()).thenReturn(mWifiScannerImpl); + when(mClientInterface.getInterfaceName()).thenReturn(TEST_INTERFACE_NAME); + mWificondControl = new WifiNl80211Manager(mContext, mWificond); + assertEquals(true, + mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, Runnable::run, + mNormalScanCallback, mPnoScanCallback)); + } + + /** + * Verifies that setupInterfaceForClientMode(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testSetupInterfaceForClientMode() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + verify(mWificond).createClientInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that setupInterfaceForClientMode(TEST_INTERFACE_NAME) calls subscribeScanEvents(). + */ + @Test + public void testSetupInterfaceForClientModeCallsScanEventSubscripiton() throws Exception { + verify(mWifiScannerImpl).subscribeScanEvents(any(IScanEvent.class)); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownClientInterface() throws Exception { + when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(true); + + assertTrue(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); + verify(mWifiScannerImpl).unsubscribeScanEvents(); + verify(mWifiScannerImpl).unsubscribePnoScanEvents(); + verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownClientInterfaceOnInvalidIface() throws Exception { + when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME1)).thenReturn(true); + + assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME1)); + verify(mWifiScannerImpl, never()).unsubscribeScanEvents(); + verify(mWifiScannerImpl, never()).unsubscribePnoScanEvents(); + verify(mWificond, never()).tearDownClientInterface(any()); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownClientInterfaceFailDueToExceptionScannerUnsubscribe() throws Exception { + when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(true); + doThrow(new RemoteException()).when(mWifiScannerImpl).unsubscribeScanEvents(); + + assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); + verify(mWifiScannerImpl).unsubscribeScanEvents(); + verify(mWifiScannerImpl, never()).unsubscribePnoScanEvents(); + verify(mWificond, never()).tearDownClientInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownClientInterfaceErrorWhenWificondFailed() throws Exception { + when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(false); + + assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); + verify(mWifiScannerImpl).unsubscribeScanEvents(); + verify(mWifiScannerImpl).unsubscribePnoScanEvents(); + verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that the client handles are cleared after teardown. + */ + @Test + public void testTeardownClientInterfaceClearsHandles() throws Exception { + testTeardownClientInterface(); + + assertNull(mWificondControl.signalPoll(TEST_INTERFACE_NAME)); + verify(mClientInterface, never()).signalPoll(); + + assertFalse(mWificondControl.startScan( + TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_LATENCY, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); + verify(mWifiScannerImpl, never()).scan(any()); + } + + /** + * Verifies that setupInterfaceForSoftApMode(TEST_INTERFACE_NAME) calls wificond. + */ + @Test + public void testSetupInterfaceForSoftApMode() throws Exception { + when(mWificond.createApInterface(TEST_INTERFACE_NAME)).thenReturn(mApInterface); + + assertEquals(true, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME)); + verify(mWificond).createApInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that setupInterfaceForSoftAp() returns null when wificond is not started. + */ + @Test + public void testSetupInterfaceForSoftApModeErrorWhenWificondIsNotStarted() throws Exception { + // Invoke wificond death handler to clear the handle. + mWificondControl.binderDied(); + mLooper.dispatchAll(); + + assertEquals(false, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME)); + } + + /** + * Verifies that setupInterfaceForSoftApMode(TEST_INTERFACE_NAME) returns null when wificond + * failed to setup AP interface. + */ + @Test + public void testSetupInterfaceForSoftApModeErrorWhenWificondFailedToSetupInterface() + throws Exception { + when(mWificond.createApInterface(TEST_INTERFACE_NAME)).thenReturn(null); + + assertEquals(false, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME)); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownSoftApInterface() throws Exception { + testSetupInterfaceForSoftApMode(); + when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME)).thenReturn(true); + + assertTrue(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME)); + verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that tearDownSoftapInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownSoftApInterfaceOnInvalidIface() throws Exception { + testSetupInterfaceForSoftApMode(); + when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME1)).thenReturn(true); + + assertFalse(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME1)); + verify(mWificond, never()).tearDownApInterface(any()); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownSoftApInterfaceErrorWhenWificondFailed() throws Exception { + testSetupInterfaceForSoftApMode(); + when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME)).thenReturn(false); + + assertFalse(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME)); + verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that the SoftAp handles are cleared after teardown. + */ + @Test + public void testTeardownSoftApInterfaceClearsHandles() throws Exception { + testTeardownSoftApInterface(); + + assertFalse(mWificondControl.registerApCallback( + TEST_INTERFACE_NAME, Runnable::run, mSoftApListener)); + verify(mApInterface, never()).registerCallback(any()); + } + + /** + * Verifies that we can setup concurrent interfaces. + */ + @Test + public void testSetupMultipleInterfaces() throws Exception { + when(mWificond.createApInterface(TEST_INTERFACE_NAME1)).thenReturn(mApInterface); + + assertEquals(true, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME1)); + + verify(mWificond).createClientInterface(TEST_INTERFACE_NAME); + verify(mWificond).createApInterface(TEST_INTERFACE_NAME1); + } + + /** + * Verifies that we can setup concurrent interfaces. + */ + @Test + public void testTeardownMultipleInterfaces() throws Exception { + testSetupMultipleInterfaces(); + assertTrue(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); + assertTrue(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME1)); + + verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME); + verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME1); + } + + /** + * Verifies that tearDownInterfaces() calls wificond. + */ + @Test + public void testTearDownInterfaces() throws Exception { + assertTrue(mWificondControl.tearDownInterfaces()); + verify(mWificond).tearDownInterfaces(); + } + + /** + * Verifies that tearDownInterfaces() calls unsubscribeScanEvents() when there was + * a configured client interface. + */ + @Test + public void testTearDownInterfacesRemovesScanEventSubscription() throws Exception { + assertTrue(mWificondControl.tearDownInterfaces()); + verify(mWifiScannerImpl).unsubscribeScanEvents(); + } + + /** + * Verifies that tearDownInterfaces() returns false when wificond is not started. + */ + @Test + public void testTearDownInterfacesErrorWhenWificondIsNotStarterd() throws Exception { + // Invoke wificond death handler to clear the handle. + mWificondControl.binderDied(); + mLooper.dispatchAll(); + assertFalse(mWificondControl.tearDownInterfaces()); + } + + /** + * Verifies that signalPoll() calls wificond. + */ + @Test + public void testSignalPoll() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + + mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, Runnable::run, + mNormalScanCallback, mPnoScanCallback); + mWificondControl.signalPoll(TEST_INTERFACE_NAME); + verify(mClientInterface).signalPoll(); + } + + /** + * Verifies that signalPoll() returns null when there is no configured client interface. + */ + @Test + public void testSignalPollErrorWhenNoClientInterfaceConfigured() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + + // Configure client interface. + assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, + Runnable::run, mNormalScanCallback, mPnoScanCallback)); + + // Tear down interfaces. + assertTrue(mWificondControl.tearDownInterfaces()); + + // Signal poll should fail. + assertEquals(null, mWificondControl.signalPoll(TEST_INTERFACE_NAME)); + } + + /** + * Verifies that getTxPacketCounters() calls wificond. + */ + @Test + public void testGetTxPacketCounters() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + + mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, Runnable::run, + mNormalScanCallback, mPnoScanCallback); + mWificondControl.getTxPacketCounters(TEST_INTERFACE_NAME); + verify(mClientInterface).getPacketCounters(); + } + + /** + * Verifies that getTxPacketCounters() returns null when there is no configured client + * interface. + */ + @Test + public void testGetTxPacketCountersErrorWhenNoClientInterfaceConfigured() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + + // Configure client interface. + assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, + Runnable::run, mNormalScanCallback, mPnoScanCallback)); + + // Tear down interfaces. + assertTrue(mWificondControl.tearDownInterfaces()); + + // Signal poll should fail. + assertEquals(null, mWificondControl.getTxPacketCounters(TEST_INTERFACE_NAME)); + } + + /** + * Verifies that getScanResults() returns null when there is no configured client + * interface. + */ + @Test + public void testGetScanResultsErrorWhenNoClientInterfaceConfigured() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + + // Configure client interface. + assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, + Runnable::run, mNormalScanCallback, mPnoScanCallback)); + + // Tear down interfaces. + assertTrue(mWificondControl.tearDownInterfaces()); + + // getScanResults should fail. + assertEquals(0, + mWificondControl.getScanResults(TEST_INTERFACE_NAME, + WifiNl80211Manager.SCAN_TYPE_SINGLE_SCAN).size()); + } + + /** + * Verifies that Scan() can convert input parameters to SingleScanSettings correctly. + */ + @Test + public void testScan() throws Exception { + when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true); + assertTrue(mWificondControl.startScan( + TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_POWER, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); + verify(mWifiScannerImpl).scan(argThat(new ScanMatcher( + IWifiScannerImpl.SCAN_TYPE_LOW_POWER, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST))); + } + + /** + * Verifies that Scan() removes duplicates hiddenSsids passed in from input. + */ + @Test + public void testScanWithDuplicateHiddenSsids() throws Exception { + when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true); + // Create a list of hiddenSsid that has a duplicate element + List hiddenSsidWithDup = new ArrayList<>(SCAN_HIDDEN_NETWORK_SSID_LIST); + hiddenSsidWithDup.add(SCAN_HIDDEN_NETWORK_SSID_LIST.get(0)); + assertEquals(hiddenSsidWithDup.get(0), + hiddenSsidWithDup.get(hiddenSsidWithDup.size() - 1)); + // Pass the List with duplicate elements into scan() + assertTrue(mWificondControl.startScan( + TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_POWER, + SCAN_FREQ_SET, hiddenSsidWithDup)); + // But the argument passed down should have the duplicate removed. + verify(mWifiScannerImpl).scan(argThat(new ScanMatcher( + IWifiScannerImpl.SCAN_TYPE_LOW_POWER, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST))); + } + + /** + * Verifies that Scan() can handle null input parameters correctly. + */ + @Test + public void testScanNullParameters() throws Exception { + when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true); + assertTrue(mWificondControl.startScan( + TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_HIGH_ACCURACY, null, null)); + verify(mWifiScannerImpl).scan(argThat(new ScanMatcher( + IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY, null, null))); + } + + /** + * Verifies that Scan() can handle wificond scan failure. + */ + @Test + public void testScanFailure() throws Exception { + when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(false); + assertFalse(mWificondControl.startScan( + TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_LATENCY, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); + verify(mWifiScannerImpl).scan(any(SingleScanSettings.class)); + } + + /** + * Verifies that Scan() can handle invalid type. + */ + @Test + public void testScanFailureDueToInvalidType() throws Exception { + assertFalse(mWificondControl.startScan( + TEST_INTERFACE_NAME, 100, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); + verify(mWifiScannerImpl, never()).scan(any(SingleScanSettings.class)); + } + + /** + * Verifies that startPnoScan() can convert input parameters to PnoSettings correctly. + */ + @Test + public void testStartPnoScan() throws Exception { + when(mWifiScannerImpl.startPnoScan(any(PnoSettings.class))).thenReturn(true); + assertTrue( + mWificondControl.startPnoScan(TEST_INTERFACE_NAME, TEST_PNO_SETTINGS, Runnable::run, + mPnoScanRequestCallback)); + verify(mWifiScannerImpl).startPnoScan(eq(TEST_PNO_SETTINGS)); + verify(mPnoScanRequestCallback).onPnoRequestSucceeded(); + } + + /** + * Verifies that stopPnoScan() calls underlying wificond. + */ + @Test + public void testStopPnoScan() throws Exception { + when(mWifiScannerImpl.stopPnoScan()).thenReturn(true); + assertTrue(mWificondControl.stopPnoScan(TEST_INTERFACE_NAME)); + verify(mWifiScannerImpl).stopPnoScan(); + } + + /** + * Verifies that stopPnoScan() can handle wificond failure. + */ + @Test + public void testStopPnoScanFailure() throws Exception { + + when(mWifiScannerImpl.stopPnoScan()).thenReturn(false); + assertFalse(mWificondControl.stopPnoScan(TEST_INTERFACE_NAME)); + verify(mWifiScannerImpl).stopPnoScan(); + } + + /** + * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon scan + * result event. + */ + @Test + public void testScanResultEvent() throws Exception { + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(IScanEvent.class); + verify(mWifiScannerImpl).subscribeScanEvents(messageCaptor.capture()); + IScanEvent scanEvent = messageCaptor.getValue(); + assertNotNull(scanEvent); + scanEvent.OnScanResultReady(); + + verify(mNormalScanCallback).onScanResultReady(); + } + + /** + * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon scan + * failed event. + */ + @Test + public void testScanFailedEvent() throws Exception { + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(IScanEvent.class); + verify(mWifiScannerImpl).subscribeScanEvents(messageCaptor.capture()); + IScanEvent scanEvent = messageCaptor.getValue(); + assertNotNull(scanEvent); + scanEvent.OnScanFailed(); + + verify(mNormalScanCallback).onScanFailed(); + } + + /** + * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon pno scan + * result event. + */ + @Test + public void testPnoScanResultEvent() throws Exception { + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(IPnoScanEvent.class); + verify(mWifiScannerImpl).subscribePnoScanEvents(messageCaptor.capture()); + IPnoScanEvent pnoScanEvent = messageCaptor.getValue(); + assertNotNull(pnoScanEvent); + pnoScanEvent.OnPnoNetworkFound(); + verify(mPnoScanCallback).onScanResultReady(); + } + + /** + * Verifies that WificondControl can invoke WifiMetrics pno scan count methods upon pno event. + */ + @Test + public void testPnoScanEventsForMetrics() throws Exception { + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(IPnoScanEvent.class); + verify(mWifiScannerImpl).subscribePnoScanEvents(messageCaptor.capture()); + IPnoScanEvent pnoScanEvent = messageCaptor.getValue(); + assertNotNull(pnoScanEvent); + + pnoScanEvent.OnPnoNetworkFound(); + verify(mPnoScanCallback).onScanResultReady(); + + pnoScanEvent.OnPnoScanFailed(); + verify(mPnoScanCallback).onScanFailed(); + } + + /** + * Verifies that startPnoScan() can invoke WifiMetrics pno scan count methods correctly. + */ + @Test + public void testStartPnoScanForMetrics() throws Exception { + when(mWifiScannerImpl.startPnoScan(any(PnoSettings.class))).thenReturn(false); + + assertFalse( + mWificondControl.startPnoScan(TEST_INTERFACE_NAME, TEST_PNO_SETTINGS, Runnable::run, + mPnoScanRequestCallback)); + verify(mPnoScanRequestCallback).onPnoRequestFailed(); + } + + /** + * Verifies that abortScan() calls underlying wificond. + */ + @Test + public void testAbortScan() throws Exception { + mWificondControl.abortScan(TEST_INTERFACE_NAME); + verify(mWifiScannerImpl).abortScan(); + } + + /** + * Ensures that the Ap interface callbacks are forwarded to the + * SoftApListener used for starting soft AP. + */ + @Test + public void testSoftApListenerInvocation() throws Exception { + testSetupInterfaceForSoftApMode(); + + WifiConfiguration config = new WifiConfiguration(); + config.SSID = new String(TEST_SSID, StandardCharsets.UTF_8); + + when(mApInterface.registerCallback(any())).thenReturn(true); + + final ArgumentCaptor apInterfaceCallbackCaptor = + ArgumentCaptor.forClass(IApInterfaceEventCallback.class); + + assertTrue(mWificondControl.registerApCallback( + TEST_INTERFACE_NAME, Runnable::run, mSoftApListener)); + verify(mApInterface).registerCallback(apInterfaceCallbackCaptor.capture()); + + final NativeWifiClient testClient = new NativeWifiClient(TEST_RAW_MAC_BYTES); + apInterfaceCallbackCaptor.getValue().onConnectedClientsChanged(testClient, true); + verify(mSoftApListener).onConnectedClientsChanged(eq(testClient), eq(true)); + + int channelFrequency = 2437; + int channelBandwidth = IApInterfaceEventCallback.BANDWIDTH_20; + apInterfaceCallbackCaptor.getValue().onSoftApChannelSwitched(channelFrequency, + channelBandwidth); + verify(mSoftApListener).onSoftApChannelSwitched(eq(channelFrequency), + eq(SoftApInfo.CHANNEL_WIDTH_20MHZ)); + } + + /** + * Verifies registration and invocation of wificond death handler. + */ + @Test + public void testRegisterDeathHandler() throws Exception { + Runnable deathHandler = mock(Runnable.class); + mWificondControl.setOnServiceDeadCallback(deathHandler); + mWificondControl.binderDied(); + mLooper.dispatchAll(); + verify(deathHandler).run(); + } + + /** + * Verifies handling of wificond death and ensures that all internal state is cleared and + * handlers are invoked. + */ + @Test + public void testDeathHandling() throws Exception { + Runnable deathHandler = mock(Runnable.class); + mWificondControl.setOnServiceDeadCallback(deathHandler); + + testSetupInterfaceForClientMode(); + + mWificondControl.binderDied(); + mLooper.dispatchAll(); + verify(deathHandler).run(); + + // The handles should be cleared after death. + assertEquals(0, mWificondControl.getChannelsMhzForBand(WifiScanner.WIFI_BAND_5_GHZ).length); + verify(mWificond, never()).getAvailable5gNonDFSChannels(); + } + + /** + * sendMgmtFrame() should fail if a null callback is passed in. + */ + @Test + public void testSendMgmtFrameNullCallback() throws Exception { + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, null); + + verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt()); + } + + /** + * sendMgmtFrame() should fail if a null frame is passed in. + */ + @Test + public void testSendMgmtFrameNullFrame() throws Exception { + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, null, TEST_MCS_RATE, Runnable::run, + mSendMgmtFrameCallback); + + verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt()); + verify(mSendMgmtFrameCallback).onFailure(anyInt()); + } + + /** + * sendMgmtFrame() should fail if an interface name that does not exist is passed in. + */ + @Test + public void testSendMgmtFrameInvalidInterfaceName() throws Exception { + mWificondControl.sendMgmtFrame(TEST_INVALID_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, mSendMgmtFrameCallback); + + verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt()); + verify(mSendMgmtFrameCallback).onFailure(anyInt()); + } + + /** + * sendMgmtFrame() should fail if it is called a second time before the first call completed. + */ + @Test + public void testSendMgmtFrameCalledTwiceBeforeFinished() throws Exception { + WifiNl80211Manager.SendMgmtFrameCallback cb1 = mock( + WifiNl80211Manager.SendMgmtFrameCallback.class); + WifiNl80211Manager.SendMgmtFrameCallback cb2 = mock( + WifiNl80211Manager.SendMgmtFrameCallback.class); + + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, cb1); + verify(cb1, never()).onFailure(anyInt()); + verify(mClientInterface, times(1)) + .SendMgmtFrame(AdditionalMatchers.aryEq(TEST_PROBE_FRAME), + any(), eq(TEST_MCS_RATE)); + + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, cb2); + verify(cb2).onFailure(WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_ALREADY_STARTED); + // verify SendMgmtFrame() still was only called once i.e. not called again + verify(mClientInterface, times(1)) + .SendMgmtFrame(any(), any(), anyInt()); + } + + /** + * Tests that when a RemoteException is triggered on AIDL call, onFailure() is called only once. + */ + @Test + public void testSendMgmtFrameThrowsException() throws Exception { + WifiNl80211Manager.SendMgmtFrameCallback cb = mock( + WifiNl80211Manager.SendMgmtFrameCallback.class); + + final ArgumentCaptor sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + + doThrow(new RemoteException()).when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + + final ArgumentCaptor alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, cb); + mLooper.dispatchAll(); + + verify(cb).onFailure(anyInt()); + verify(mAlarmManager).cancel(eq(alarmListenerCaptor.getValue())); + + sendMgmtFrameEventCaptor.getValue().OnFailure( + WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_UNKNOWN); + mLooper.dispatchAll(); + + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + mLooper.dispatchAll(); + + verifyNoMoreInteractions(cb); + } + + /** + * Tests that the onAck() callback is triggered correctly. + */ + @Test + public void testSendMgmtFrameSuccess() throws Exception { + WifiNl80211Manager.SendMgmtFrameCallback cb = mock( + WifiNl80211Manager.SendMgmtFrameCallback.class); + + final ArgumentCaptor sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + doNothing().when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + final ArgumentCaptor alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, cb); + + sendMgmtFrameEventCaptor.getValue().OnAck(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS); + mLooper.dispatchAll(); + verify(cb).onAck(eq(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS)); + verify(cb, never()).onFailure(anyInt()); + verify(mAlarmManager).cancel(eq(alarmListenerCaptor.getValue())); + + // verify that even if timeout is triggered afterwards, SendMgmtFrameCallback is not + // triggered again + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + mLooper.dispatchAll(); + verify(cb, times(1)).onAck(anyInt()); + verify(cb, never()).onFailure(anyInt()); + } + + /** + * Tests that the onFailure() callback is triggered correctly. + */ + @Test + public void testSendMgmtFrameFailure() throws Exception { + WifiNl80211Manager.SendMgmtFrameCallback cb = mock( + WifiNl80211Manager.SendMgmtFrameCallback.class); + + final ArgumentCaptor sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + doNothing().when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + final ArgumentCaptor alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, cb); + + sendMgmtFrameEventCaptor.getValue().OnFailure( + WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_UNKNOWN); + mLooper.dispatchAll(); + verify(cb, never()).onAck(anyInt()); + verify(cb).onFailure(WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_UNKNOWN); + verify(mAlarmManager).cancel(eq(alarmListenerCaptor.getValue())); + + // verify that even if timeout is triggered afterwards, SendMgmtFrameCallback is not + // triggered again + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + mLooper.dispatchAll(); + verify(cb, never()).onAck(anyInt()); + verify(cb, times(1)).onFailure(anyInt()); + } + + /** + * Tests that the onTimeout() callback is triggered correctly. + */ + @Test + public void testSendMgmtFrameTimeout() throws Exception { + WifiNl80211Manager.SendMgmtFrameCallback cb = mock( + WifiNl80211Manager.SendMgmtFrameCallback.class); + + final ArgumentCaptor sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + doNothing().when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + final ArgumentCaptor alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, cb); + + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + mLooper.dispatchAll(); + verify(cb, never()).onAck(anyInt()); + verify(cb).onFailure(WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_TIMEOUT); + + // verify that even if onAck() callback is triggered after timeout, + // SendMgmtFrameCallback is not triggered again + sendMgmtFrameEventCaptor.getValue().OnAck(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS); + mLooper.dispatchAll(); + verify(cb, never()).onAck(anyInt()); + verify(cb, times(1)).onFailure(anyInt()); + } + + /** + * Tests every possible test outcome followed by every other test outcome to ensure that the + * internal state is reset correctly between calls. + * i.e. (success, success), (success, failure), (success, timeout), + * (failure, failure), (failure, success), (failure, timeout), + * (timeout, timeout), (timeout, success), (timeout, failure) + * + * Also tests that internal state is reset correctly after a transient AIDL RemoteException. + */ + @Test + public void testSendMgmtFrameMixed() throws Exception { + testSendMgmtFrameThrowsException(); + testSendMgmtFrameSuccess(); + testSendMgmtFrameSuccess(); + testSendMgmtFrameFailure(); + testSendMgmtFrameFailure(); + testSendMgmtFrameTimeout(); + testSendMgmtFrameTimeout(); + testSendMgmtFrameSuccess(); + testSendMgmtFrameTimeout(); + testSendMgmtFrameFailure(); + testSendMgmtFrameSuccess(); + } + + /** + * Tests that OnAck() does not perform any non-thread-safe operations on the binder thread. + * + * The sequence of instructions are: + * 1. post onAlarm() onto main thread + * 2. OnAck() + * 3. mLooper.dispatchAll() + * + * The actual order of execution is: + * 1. binder thread portion of OnAck() + * 2. onAlarm() (which purely executes on the main thread) + * 3. main thread portion of OnAck() + * + * If the binder thread portion of OnAck() is not thread-safe, it can possibly mess up + * onAlarm(). Tests that this does not occur. + */ + @Test + public void testSendMgmtFrameTimeoutAckThreadSafe() throws Exception { + final ArgumentCaptor sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + doNothing().when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + final ArgumentCaptor alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, mSendMgmtFrameCallback); + + // AlarmManager should post the onAlarm() callback onto the handler, but since we are + // triggering onAlarm() ourselves during the test, manually post onto handler + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + // OnAck posts to the handler + sendMgmtFrameEventCaptor.getValue().OnAck(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS); + mLooper.dispatchAll(); + verify(mSendMgmtFrameCallback, never()).onAck(anyInt()); + verify(mSendMgmtFrameCallback).onFailure( + WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_TIMEOUT); + } + + /** + * See {@link #testSendMgmtFrameTimeoutAckThreadSafe()}. This test replaces OnAck() with + * OnFailure(). + */ + @Test + public void testSendMgmtFrameTimeoutFailureThreadSafe() throws Exception { + final ArgumentCaptor sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + doNothing().when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + final ArgumentCaptor alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, mSendMgmtFrameCallback); + + // AlarmManager should post the onAlarm() callback onto the handler, but since we are + // triggering onAlarm() ourselves during the test, manually post onto handler + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + // OnFailure posts to the handler + sendMgmtFrameEventCaptor.getValue().OnFailure( + WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_UNKNOWN); + mLooper.dispatchAll(); + verify(mSendMgmtFrameCallback).onFailure( + WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_TIMEOUT); + } + + /** + * Tests getDeviceWiphyCapabililties + */ + @Test + public void testGetDeviceWiphyCapabilities() throws Exception { + DeviceWiphyCapabilities capaExpected = new DeviceWiphyCapabilities(); + + capaExpected.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, true); + capaExpected.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, true); + capaExpected.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AX, false); + capaExpected.setChannelWidthSupported(ScanResult.CHANNEL_WIDTH_160MHZ, true); + capaExpected.setChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ, false); + capaExpected.setMaxNumberTxSpatialStreams(2); + capaExpected.setMaxNumberRxSpatialStreams(1); + + when(mWificond.getDeviceWiphyCapabilities(TEST_INTERFACE_NAME)) + .thenReturn(capaExpected); + + DeviceWiphyCapabilities capaActual = + mWificondControl.getDeviceWiphyCapabilities(TEST_INTERFACE_NAME); + assertEquals(capaExpected, capaActual); + } + + // Create a ArgumentMatcher which captures a SingleScanSettings parameter and checks if it + // matches the provided frequency set and ssid set. + private class ScanMatcher implements ArgumentMatcher { + int mExpectedScanType; + private final Set mExpectedFreqs; + private final List mExpectedSsids; + + ScanMatcher(int expectedScanType, Set expectedFreqs, List expectedSsids) { + this.mExpectedScanType = expectedScanType; + this.mExpectedFreqs = expectedFreqs; + this.mExpectedSsids = expectedSsids; + } + + @Override + public boolean matches(SingleScanSettings settings) { + if (settings.scanType != mExpectedScanType) { + return false; + } + ArrayList channelSettings = settings.channelSettings; + ArrayList hiddenNetworks = settings.hiddenNetworks; + if (mExpectedFreqs != null) { + Set freqSet = new HashSet(); + for (ChannelSettings channel : channelSettings) { + freqSet.add(channel.frequency); + } + if (!mExpectedFreqs.equals(freqSet)) { + return false; + } + } else { + if (channelSettings != null && channelSettings.size() > 0) { + return false; + } + } + + if (mExpectedSsids != null) { + List ssidSet = new ArrayList<>(); + for (HiddenNetwork network : hiddenNetworks) { + ssidSet.add(network.ssid); + } + if (!mExpectedSsids.equals(ssidSet)) { + return false; + } + + } else { + if (hiddenNetworks != null && hiddenNetworks.size() > 0) { + return false; + } + } + return true; + } + + @Override + public String toString() { + return "ScanMatcher{mExpectedFreqs=" + mExpectedFreqs + + ", mExpectedSsids=" + mExpectedSsids + '}'; + } + } + + private static class LocalNativeUtil { + private static final int SSID_BYTES_MAX_LEN = 32; + + /** + * Converts an ArrayList of UTF_8 byte values to string. + * The string will either be: + * a) UTF-8 String encapsulated in quotes (if all the bytes are UTF-8 encodeable and non + * null), + * or + * b) Hex string with no delimiters. + * + * @param bytes List of bytes for ssid. + * @throws IllegalArgumentException for null bytes. + */ + public static String bytesToHexOrQuotedString(ArrayList bytes) { + if (bytes == null) { + throw new IllegalArgumentException("null ssid bytes"); + } + byte[] byteArray = byteArrayFromArrayList(bytes); + // Check for 0's in the byte stream in which case we cannot convert this into a string. + if (!bytes.contains(Byte.valueOf((byte) 0))) { + CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder(); + try { + CharBuffer decoded = decoder.decode(ByteBuffer.wrap(byteArray)); + return "\"" + decoded.toString() + "\""; + } catch (CharacterCodingException cce) { + } + } + return hexStringFromByteArray(byteArray); + } + + /** + * Converts an ssid string to an arraylist of UTF_8 byte values. + * These forms are acceptable: + * a) UTF-8 String encapsulated in quotes, or + * b) Hex string with no delimiters. + * + * @param ssidStr String to be converted. + * @throws IllegalArgumentException for null string. + */ + public static ArrayList decodeSsid(String ssidStr) { + ArrayList ssidBytes = hexOrQuotedStringToBytes(ssidStr); + if (ssidBytes.size() > SSID_BYTES_MAX_LEN) { + throw new IllegalArgumentException( + "ssid bytes size out of range: " + ssidBytes.size()); + } + return ssidBytes; + } + + /** + * Convert from an array list of Byte to an array of primitive bytes. + */ + public static byte[] byteArrayFromArrayList(ArrayList bytes) { + byte[] byteArray = new byte[bytes.size()]; + int i = 0; + for (Byte b : bytes) { + byteArray[i++] = b; + } + return byteArray; + } + + /** + * Converts a byte array to hex string. + * + * @param bytes List of bytes for ssid. + * @throws IllegalArgumentException for null bytes. + */ + public static String hexStringFromByteArray(byte[] bytes) { + if (bytes == null) { + throw new IllegalArgumentException("null hex bytes"); + } + return new String(HexEncoding.encode(bytes)).toLowerCase(); + } + + /** + * Converts an string to an arraylist of UTF_8 byte values. + * These forms are acceptable: + * a) UTF-8 String encapsulated in quotes, or + * b) Hex string with no delimiters. + * + * @param str String to be converted. + * @throws IllegalArgumentException for null string. + */ + public static ArrayList hexOrQuotedStringToBytes(String str) { + if (str == null) { + throw new IllegalArgumentException("null string"); + } + int length = str.length(); + if ((length > 1) && (str.charAt(0) == '"') && (str.charAt(length - 1) == '"')) { + str = str.substring(1, str.length() - 1); + return stringToByteArrayList(str); + } else { + return byteArrayToArrayList(hexStringToByteArray(str)); + } + } + + /** + * Convert the string to byte array list. + * + * @return the UTF_8 char byte values of str, as an ArrayList. + * @throws IllegalArgumentException if a null or unencodable string is sent. + */ + public static ArrayList stringToByteArrayList(String str) { + if (str == null) { + throw new IllegalArgumentException("null string"); + } + // Ensure that the provided string is UTF_8 encoded. + CharsetEncoder encoder = StandardCharsets.UTF_8.newEncoder(); + try { + ByteBuffer encoded = encoder.encode(CharBuffer.wrap(str)); + byte[] byteArray = new byte[encoded.remaining()]; + encoded.get(byteArray); + return byteArrayToArrayList(byteArray); + } catch (CharacterCodingException cce) { + throw new IllegalArgumentException("cannot be utf-8 encoded", cce); + } + } + + /** + * Convert from an array of primitive bytes to an array list of Byte. + */ + public static ArrayList byteArrayToArrayList(byte[] bytes) { + ArrayList byteList = new ArrayList<>(); + for (Byte b : bytes) { + byteList.add(b); + } + return byteList; + } + + /** + * Converts a hex string to byte array. + * + * @param hexStr String to be converted. + * @throws IllegalArgumentException for null string. + */ + public static byte[] hexStringToByteArray(String hexStr) { + if (hexStr == null) { + throw new IllegalArgumentException("null hex string"); + } + return HexEncoding.decode(hexStr.toCharArray(), false); + } + } +} diff --git a/wifi/tests/src/android/net/wifi/wificond/DeviceWiphyCapabilitiesTest.java b/wifi/tests/src/android/net/wifi/wificond/DeviceWiphyCapabilitiesTest.java deleted file mode 100644 index 8e3627acd4ed..000000000000 --- a/wifi/tests/src/android/net/wifi/wificond/DeviceWiphyCapabilitiesTest.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2020 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.wificond; - -import static org.junit.Assert.assertEquals; - -import android.net.wifi.ScanResult; -import android.os.Parcel; - -import androidx.test.filters.SmallTest; - -import org.junit.Before; -import org.junit.Test; - -/** - * Unit tests for {@link android.net.wifi.wificond.DeviceWiphyCapabilities}. - */ -@SmallTest -public class DeviceWiphyCapabilitiesTest { - @Before - public void setUp() {} - - /** - * DeviceWiphyCapabilities object can be serialized and deserialized, while keeping the - * values unchanged. - */ - @Test - public void canSerializeAndDeserialize() { - DeviceWiphyCapabilities capa = new DeviceWiphyCapabilities(); - - capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, true); - capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, true); - capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AX, false); - capa.setChannelWidthSupported(ScanResult.CHANNEL_WIDTH_160MHZ, true); - capa.setChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ, false); - capa.setMaxNumberTxSpatialStreams(2); - capa.setMaxNumberRxSpatialStreams(1); - - Parcel parcel = Parcel.obtain(); - capa.writeToParcel(parcel, 0); - // Rewind the pointer to the head of the parcel. - parcel.setDataPosition(0); - DeviceWiphyCapabilities capaDeserialized = - DeviceWiphyCapabilities.CREATOR.createFromParcel(parcel); - - assertEquals(capa, capaDeserialized); - assertEquals(capa.hashCode(), capaDeserialized.hashCode()); - } - - /** - * Test mapping wifi standard support into channel width support - */ - @Test - public void testMappingWifiStandardIntoChannelWidthSupport() { - DeviceWiphyCapabilities capa = new DeviceWiphyCapabilities(); - - capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, false); - capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, false); - capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AX, false); - assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_20MHZ)); - assertEquals(false, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_40MHZ)); - assertEquals(false, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ)); - - capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, true); - assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_20MHZ)); - assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_40MHZ)); - assertEquals(false, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ)); - - capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, true); - assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_20MHZ)); - assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_40MHZ)); - assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ)); - } -} diff --git a/wifi/tests/src/android/net/wifi/wificond/NativeScanResultTest.java b/wifi/tests/src/android/net/wifi/wificond/NativeScanResultTest.java deleted file mode 100644 index 0df170f8786c..000000000000 --- a/wifi/tests/src/android/net/wifi/wificond/NativeScanResultTest.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.wifi.wificond; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import android.os.Parcel; - -import androidx.test.filters.SmallTest; - -import org.junit.Test; - -import java.util.ArrayList; -import java.util.Arrays; - -/** - * Unit tests for {@link android.net.wifi.wificond.NativeScanResult}. - */ -@SmallTest -public class NativeScanResultTest { - - private static final byte[] TEST_SSID = - new byte[] {'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'}; - private static final byte[] TEST_BSSID = - new byte[] {(byte) 0x12, (byte) 0xef, (byte) 0xa1, - (byte) 0x2c, (byte) 0x97, (byte) 0x8b}; - private static final byte[] TEST_INFO_ELEMENT = - new byte[] {(byte) 0x01, (byte) 0x03, (byte) 0x12, (byte) 0xbe, (byte) 0xff}; - private static final int TEST_FREQUENCY = 2456; - private static final int TEST_SIGNAL_MBM = -45; - private static final long TEST_TSF = 34455441; - private static final int TEST_CAPABILITY = (0x1 << 2) | (0x1 << 5); - private static final boolean TEST_ASSOCIATED = true; - private static final int[] RADIO_CHAIN_IDS = { 0, 1 }; - private static final int[] RADIO_CHAIN_LEVELS = { -56, -65 }; - - /** - * NativeScanResult object can be serialized and deserialized, while keeping the - * values unchanged. - */ - @Test - public void canSerializeAndDeserialize() { - NativeScanResult scanResult = new NativeScanResult(); - scanResult.ssid = TEST_SSID; - scanResult.bssid = TEST_BSSID; - scanResult.infoElement = TEST_INFO_ELEMENT; - scanResult.frequency = TEST_FREQUENCY; - scanResult.signalMbm = TEST_SIGNAL_MBM; - scanResult.tsf = TEST_TSF; - scanResult.capability = TEST_CAPABILITY; - scanResult.associated = TEST_ASSOCIATED; - scanResult.radioChainInfos = new ArrayList<>(Arrays.asList( - new RadioChainInfo(RADIO_CHAIN_IDS[0], RADIO_CHAIN_LEVELS[0]), - new RadioChainInfo(RADIO_CHAIN_IDS[1], RADIO_CHAIN_LEVELS[1]))); - Parcel parcel = Parcel.obtain(); - scanResult.writeToParcel(parcel, 0); - // Rewind the pointer to the head of the parcel. - parcel.setDataPosition(0); - NativeScanResult scanResultDeserialized = NativeScanResult.CREATOR.createFromParcel(parcel); - - assertArrayEquals(scanResult.ssid, scanResultDeserialized.ssid); - assertArrayEquals(scanResult.bssid, scanResultDeserialized.bssid); - assertArrayEquals(scanResult.infoElement, scanResultDeserialized.infoElement); - assertEquals(scanResult.frequency, scanResultDeserialized.frequency); - assertEquals(scanResult.signalMbm, scanResultDeserialized.signalMbm); - assertEquals(scanResult.tsf, scanResultDeserialized.tsf); - assertEquals(scanResult.capability, scanResultDeserialized.capability); - assertEquals(scanResult.associated, scanResultDeserialized.associated); - assertTrue(scanResult.radioChainInfos.containsAll(scanResultDeserialized.radioChainInfos)); - } -} diff --git a/wifi/tests/src/android/net/wifi/wificond/PnoSettingsTest.java b/wifi/tests/src/android/net/wifi/wificond/PnoSettingsTest.java deleted file mode 100644 index 9439c796e1a5..000000000000 --- a/wifi/tests/src/android/net/wifi/wificond/PnoSettingsTest.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.wifi.wificond; - -import static org.junit.Assert.assertEquals; - -import android.os.Parcel; - -import androidx.test.filters.SmallTest; - -import org.junit.Before; -import org.junit.Test; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; - -/** - * Unit tests for {@link android.net.wifi.wificond.PnoSettings}. - */ -@SmallTest -public class PnoSettingsTest { - - private static final byte[] TEST_SSID_1 = - new byte[] {'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'}; - private static final byte[] TEST_SSID_2 = - new byte[] {'A', 'n', 'd', 'r', 'o', 'i', 'd', 'T', 'e', 's', 't'}; - private static final int[] TEST_FREQUENCIES_1 = {}; - private static final int[] TEST_FREQUENCIES_2 = {2500, 5124}; - private static final int TEST_INTERVAL_MS = 30000; - private static final int TEST_MIN_2G_RSSI = -60; - private static final int TEST_MIN_5G_RSSI = -65; - private static final int TEST_VALUE = 42; - - private PnoNetwork mPnoNetwork1; - private PnoNetwork mPnoNetwork2; - - @Before - public void setUp() { - mPnoNetwork1 = new PnoNetwork(); - mPnoNetwork1.setSsid(TEST_SSID_1); - mPnoNetwork1.setHidden(true); - mPnoNetwork1.setFrequenciesMhz(TEST_FREQUENCIES_1); - - mPnoNetwork2 = new PnoNetwork(); - mPnoNetwork2.setSsid(TEST_SSID_2); - mPnoNetwork2.setHidden(false); - mPnoNetwork2.setFrequenciesMhz(TEST_FREQUENCIES_2); - } - - /** - * PnoSettings object can be serialized and deserialized, while keeping the - * values unchanged. - */ - @Test - public void canSerializeAndDeserialize() { - PnoSettings pnoSettings = new PnoSettings(); - pnoSettings.setIntervalMillis(TEST_INTERVAL_MS); - pnoSettings.setMin2gRssiDbm(TEST_MIN_2G_RSSI); - pnoSettings.setMin5gRssiDbm(TEST_MIN_5G_RSSI); - pnoSettings.setPnoNetworks(new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2))); - - Parcel parcel = Parcel.obtain(); - pnoSettings.writeToParcel(parcel, 0); - // Rewind the pointer to the head of the parcel. - parcel.setDataPosition(0); - PnoSettings pnoSettingsDeserialized = PnoSettings.CREATOR.createFromParcel(parcel); - - assertEquals(pnoSettings, pnoSettingsDeserialized); - assertEquals(pnoSettings.hashCode(), pnoSettingsDeserialized.hashCode()); - } - - /** - * Tests usage of {@link PnoSettings} as a HashMap key type. - */ - @Test - public void testAsHashMapKey() { - PnoSettings pnoSettings1 = new PnoSettings(); - pnoSettings1.setIntervalMillis(TEST_INTERVAL_MS); - pnoSettings1.setMin2gRssiDbm(TEST_MIN_2G_RSSI); - pnoSettings1.setMin5gRssiDbm(TEST_MIN_5G_RSSI); - pnoSettings1.setPnoNetworks(new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2))); - - PnoSettings pnoSettings2 = new PnoSettings(); - pnoSettings2.setIntervalMillis(TEST_INTERVAL_MS); - pnoSettings2.setMin2gRssiDbm(TEST_MIN_2G_RSSI); - pnoSettings2.setMin5gRssiDbm(TEST_MIN_5G_RSSI); - pnoSettings2.setPnoNetworks(new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2))); - - assertEquals(pnoSettings1, pnoSettings2); - assertEquals(pnoSettings1.hashCode(), pnoSettings2.hashCode()); - - HashMap map = new HashMap<>(); - map.put(pnoSettings1, TEST_VALUE); - - assertEquals(TEST_VALUE, map.get(pnoSettings2).intValue()); - } -} diff --git a/wifi/tests/src/android/net/wifi/wificond/SingleScanSettingsTest.java b/wifi/tests/src/android/net/wifi/wificond/SingleScanSettingsTest.java deleted file mode 100644 index f20ec4788655..000000000000 --- a/wifi/tests/src/android/net/wifi/wificond/SingleScanSettingsTest.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.wifi.wificond; - -import static org.junit.Assert.assertEquals; - -import android.os.Parcel; - -import androidx.test.filters.SmallTest; - -import org.junit.Before; -import org.junit.Test; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; - -/** - * Unit tests for {@link android.net.wifi.wificond.SingleScanSettingsResult}. - */ -@SmallTest -public class SingleScanSettingsTest { - - private static final byte[] TEST_SSID_1 = - new byte[] {'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'}; - private static final byte[] TEST_SSID_2 = - new byte[] {'A', 'n', 'd', 'r', 'o', 'i', 'd', 'T', 'e', 's', 't'}; - private static final int TEST_FREQUENCY_1 = 2456; - private static final int TEST_FREQUENCY_2 = 5215; - private static final int TEST_VALUE = 42; - - private ChannelSettings mChannelSettings1; - private ChannelSettings mChannelSettings2; - private HiddenNetwork mHiddenNetwork1; - private HiddenNetwork mHiddenNetwork2; - - @Before - public void setUp() { - mChannelSettings1 = new ChannelSettings(); - mChannelSettings1.frequency = TEST_FREQUENCY_1; - mChannelSettings2 = new ChannelSettings(); - mChannelSettings2.frequency = TEST_FREQUENCY_2; - - mHiddenNetwork1 = new HiddenNetwork(); - mHiddenNetwork1.ssid = TEST_SSID_1; - mHiddenNetwork2 = new HiddenNetwork(); - mHiddenNetwork2.ssid = TEST_SSID_2; - } - - /** - * SingleScanSettings object can be serialized and deserialized, while keeping the - * values unchanged. - */ - @Test - public void canSerializeAndDeserialize() { - SingleScanSettings scanSettings = new SingleScanSettings(); - scanSettings.scanType = IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY; - - scanSettings.channelSettings = - new ArrayList<>(Arrays.asList(mChannelSettings1, mChannelSettings2)); - scanSettings.hiddenNetworks = - new ArrayList<>(Arrays.asList(mHiddenNetwork1, mHiddenNetwork2)); - - Parcel parcel = Parcel.obtain(); - scanSettings.writeToParcel(parcel, 0); - // Rewind the pointer to the head of the parcel. - parcel.setDataPosition(0); - SingleScanSettings scanSettingsDeserialized = - SingleScanSettings.CREATOR.createFromParcel(parcel); - - assertEquals(scanSettings, scanSettingsDeserialized); - assertEquals(scanSettings.hashCode(), scanSettingsDeserialized.hashCode()); - } - - /** - * Tests usage of {@link SingleScanSettings} as a HashMap key type. - */ - @Test - public void testAsHashMapKey() { - SingleScanSettings scanSettings1 = new SingleScanSettings(); - scanSettings1.scanType = IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY; - scanSettings1.channelSettings = - new ArrayList<>(Arrays.asList(mChannelSettings1, mChannelSettings2)); - scanSettings1.hiddenNetworks = - new ArrayList<>(Arrays.asList(mHiddenNetwork1, mHiddenNetwork2)); - - SingleScanSettings scanSettings2 = new SingleScanSettings(); - scanSettings2.scanType = IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY; - scanSettings2.channelSettings = - new ArrayList<>(Arrays.asList(mChannelSettings1, mChannelSettings2)); - scanSettings2.hiddenNetworks = - new ArrayList<>(Arrays.asList(mHiddenNetwork1, mHiddenNetwork2)); - - assertEquals(scanSettings1, scanSettings2); - assertEquals(scanSettings1.hashCode(), scanSettings2.hashCode()); - - HashMap map = new HashMap<>(); - map.put(scanSettings1, TEST_VALUE); - - assertEquals(TEST_VALUE, map.get(scanSettings2).intValue()); - } -} diff --git a/wifi/tests/src/android/net/wifi/wificond/WifiNl80211ManagerTest.java b/wifi/tests/src/android/net/wifi/wificond/WifiNl80211ManagerTest.java deleted file mode 100644 index a8184068ff5a..000000000000 --- a/wifi/tests/src/android/net/wifi/wificond/WifiNl80211ManagerTest.java +++ /dev/null @@ -1,1265 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.wifi.wificond; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Matchers.argThat; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyLong; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import android.app.AlarmManager; -import android.app.test.TestAlarmManager; -import android.content.Context; -import android.net.MacAddress; -import android.net.wifi.ScanResult; -import android.net.wifi.SoftApInfo; -import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiScanner; -import android.net.wifi.util.HexEncoding; -import android.os.Handler; -import android.os.IBinder; -import android.os.RemoteException; -import android.os.test.TestLooper; - -import androidx.test.filters.SmallTest; - -import org.junit.Before; -import org.junit.Test; -import org.mockito.AdditionalMatchers; -import org.mockito.ArgumentCaptor; -import org.mockito.ArgumentMatcher; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.charset.CharacterCodingException; -import java.nio.charset.CharsetDecoder; -import java.nio.charset.CharsetEncoder; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -/** - * Unit tests for {@link android.net.wifi.wificond.WifiNl80211Manager}. - */ -@SmallTest -public class WifiNl80211ManagerTest { - @Mock - private IWificond mWificond; - @Mock - private IBinder mWifiCondBinder; - @Mock - private IClientInterface mClientInterface; - @Mock - private IWifiScannerImpl mWifiScannerImpl; - @Mock - private IApInterface mApInterface; - @Mock - private WifiNl80211Manager.SoftApCallback mSoftApListener; - @Mock - private WifiNl80211Manager.SendMgmtFrameCallback mSendMgmtFrameCallback; - @Mock - private WifiNl80211Manager.ScanEventCallback mNormalScanCallback; - @Mock - private WifiNl80211Manager.ScanEventCallback mPnoScanCallback; - @Mock - private WifiNl80211Manager.PnoScanRequestCallback mPnoScanRequestCallback; - @Mock - private Context mContext; - private TestLooper mLooper; - private TestAlarmManager mTestAlarmManager; - private AlarmManager mAlarmManager; - private WifiNl80211Manager mWificondControl; - private static final String TEST_INTERFACE_NAME = "test_wlan_if"; - private static final String TEST_INTERFACE_NAME1 = "test_wlan_if1"; - private static final String TEST_INVALID_INTERFACE_NAME = "asdf"; - private static final byte[] TEST_SSID = - new byte[]{'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'}; - private static final byte[] TEST_PSK = - new byte[]{'T', 'e', 's', 't'}; - - private static final Set SCAN_FREQ_SET = - new HashSet() {{ - add(2410); - add(2450); - add(5050); - add(5200); - }}; - private static final String TEST_QUOTED_SSID_1 = "\"testSsid1\""; - private static final String TEST_QUOTED_SSID_2 = "\"testSsid2\""; - private static final int[] TEST_FREQUENCIES_1 = {}; - private static final int[] TEST_FREQUENCIES_2 = {2500, 5124}; - private static final MacAddress TEST_RAW_MAC_BYTES = MacAddress.fromBytes( - new byte[]{0x00, 0x01, 0x02, 0x03, 0x04, 0x05}); - - private static final List SCAN_HIDDEN_NETWORK_SSID_LIST = - new ArrayList() {{ - add(LocalNativeUtil.byteArrayFromArrayList( - LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_1))); - add(LocalNativeUtil.byteArrayFromArrayList( - LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_2))); - }}; - - private static final PnoSettings TEST_PNO_SETTINGS = new PnoSettings(); - static { - TEST_PNO_SETTINGS.setIntervalMillis(6000); - List initPnoNetworks = new ArrayList<>(); - PnoNetwork network = new PnoNetwork(); - network.setSsid(LocalNativeUtil.byteArrayFromArrayList( - LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_1))); - network.setHidden(true); - network.setFrequenciesMhz(TEST_FREQUENCIES_1); - initPnoNetworks.add(network); - network.setSsid(LocalNativeUtil.byteArrayFromArrayList( - LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_2))); - network.setHidden(false); - network.setFrequenciesMhz(TEST_FREQUENCIES_2); - initPnoNetworks.add(network); - TEST_PNO_SETTINGS.setPnoNetworks(initPnoNetworks); - } - - private static final int TEST_MCS_RATE = 5; - private static final int TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS = 100; - private static final byte[] TEST_PROBE_FRAME = { - 0x40, 0x00, 0x3c, 0x00, (byte) 0xa8, (byte) 0xbd, 0x27, 0x5b, - 0x33, 0x72, (byte) 0xf4, (byte) 0xf5, (byte) 0xe8, 0x51, (byte) 0x9e, 0x09, - (byte) 0xa8, (byte) 0xbd, 0x27, 0x5b, 0x33, 0x72, (byte) 0xb0, 0x66, - 0x00, 0x00 - }; - - @Before - public void setUp() throws Exception { - // Setup mocks for successful WificondControl operation. Failure case mocks should be - // created in specific tests - MockitoAnnotations.initMocks(this); - - mTestAlarmManager = new TestAlarmManager(); - mAlarmManager = mTestAlarmManager.getAlarmManager(); - when(mContext.getSystemServiceName(AlarmManager.class)).thenReturn(Context.ALARM_SERVICE); - when(mContext.getSystemService(AlarmManager.class)).thenReturn(mAlarmManager); - - mLooper = new TestLooper(); - when(mContext.getMainLooper()).thenReturn(mLooper.getLooper()); - - when(mWificond.asBinder()).thenReturn(mWifiCondBinder); - when(mClientInterface.getWifiScannerImpl()).thenReturn(mWifiScannerImpl); - when(mWificond.createClientInterface(any())).thenReturn(mClientInterface); - when(mWificond.createApInterface(any())).thenReturn(mApInterface); - when(mWificond.tearDownClientInterface(any())).thenReturn(true); - when(mWificond.tearDownApInterface(any())).thenReturn(true); - when(mClientInterface.getWifiScannerImpl()).thenReturn(mWifiScannerImpl); - when(mClientInterface.getInterfaceName()).thenReturn(TEST_INTERFACE_NAME); - mWificondControl = new WifiNl80211Manager(mContext, mWificond); - assertEquals(true, - mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, Runnable::run, - mNormalScanCallback, mPnoScanCallback)); - } - - /** - * Verifies that setupInterfaceForClientMode(TEST_INTERFACE_NAME) calls Wificond. - */ - @Test - public void testSetupInterfaceForClientMode() throws Exception { - when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); - verify(mWificond).createClientInterface(TEST_INTERFACE_NAME); - } - - /** - * Verifies that setupInterfaceForClientMode(TEST_INTERFACE_NAME) calls subscribeScanEvents(). - */ - @Test - public void testSetupInterfaceForClientModeCallsScanEventSubscripiton() throws Exception { - verify(mWifiScannerImpl).subscribeScanEvents(any(IScanEvent.class)); - } - - /** - * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. - */ - @Test - public void testTeardownClientInterface() throws Exception { - when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(true); - - assertTrue(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); - verify(mWifiScannerImpl).unsubscribeScanEvents(); - verify(mWifiScannerImpl).unsubscribePnoScanEvents(); - verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME); - } - - /** - * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. - */ - @Test - public void testTeardownClientInterfaceOnInvalidIface() throws Exception { - when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME1)).thenReturn(true); - - assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME1)); - verify(mWifiScannerImpl, never()).unsubscribeScanEvents(); - verify(mWifiScannerImpl, never()).unsubscribePnoScanEvents(); - verify(mWificond, never()).tearDownClientInterface(any()); - } - - /** - * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. - */ - @Test - public void testTeardownClientInterfaceFailDueToExceptionScannerUnsubscribe() throws Exception { - when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(true); - doThrow(new RemoteException()).when(mWifiScannerImpl).unsubscribeScanEvents(); - - assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); - verify(mWifiScannerImpl).unsubscribeScanEvents(); - verify(mWifiScannerImpl, never()).unsubscribePnoScanEvents(); - verify(mWificond, never()).tearDownClientInterface(TEST_INTERFACE_NAME); - } - - /** - * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. - */ - @Test - public void testTeardownClientInterfaceErrorWhenWificondFailed() throws Exception { - when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(false); - - assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); - verify(mWifiScannerImpl).unsubscribeScanEvents(); - verify(mWifiScannerImpl).unsubscribePnoScanEvents(); - verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME); - } - - /** - * Verifies that the client handles are cleared after teardown. - */ - @Test - public void testTeardownClientInterfaceClearsHandles() throws Exception { - testTeardownClientInterface(); - - assertNull(mWificondControl.signalPoll(TEST_INTERFACE_NAME)); - verify(mClientInterface, never()).signalPoll(); - - assertFalse(mWificondControl.startScan( - TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_LATENCY, - SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); - verify(mWifiScannerImpl, never()).scan(any()); - } - - /** - * Verifies that setupInterfaceForSoftApMode(TEST_INTERFACE_NAME) calls wificond. - */ - @Test - public void testSetupInterfaceForSoftApMode() throws Exception { - when(mWificond.createApInterface(TEST_INTERFACE_NAME)).thenReturn(mApInterface); - - assertEquals(true, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME)); - verify(mWificond).createApInterface(TEST_INTERFACE_NAME); - } - - /** - * Verifies that setupInterfaceForSoftAp() returns null when wificond is not started. - */ - @Test - public void testSetupInterfaceForSoftApModeErrorWhenWificondIsNotStarted() throws Exception { - // Invoke wificond death handler to clear the handle. - mWificondControl.binderDied(); - mLooper.dispatchAll(); - - assertEquals(false, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME)); - } - - /** - * Verifies that setupInterfaceForSoftApMode(TEST_INTERFACE_NAME) returns null when wificond - * failed to setup AP interface. - */ - @Test - public void testSetupInterfaceForSoftApModeErrorWhenWificondFailedToSetupInterface() - throws Exception { - when(mWificond.createApInterface(TEST_INTERFACE_NAME)).thenReturn(null); - - assertEquals(false, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME)); - } - - /** - * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. - */ - @Test - public void testTeardownSoftApInterface() throws Exception { - testSetupInterfaceForSoftApMode(); - when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME)).thenReturn(true); - - assertTrue(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME)); - verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME); - } - - /** - * Verifies that tearDownSoftapInterface(TEST_INTERFACE_NAME) calls Wificond. - */ - @Test - public void testTeardownSoftApInterfaceOnInvalidIface() throws Exception { - testSetupInterfaceForSoftApMode(); - when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME1)).thenReturn(true); - - assertFalse(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME1)); - verify(mWificond, never()).tearDownApInterface(any()); - } - - /** - * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. - */ - @Test - public void testTeardownSoftApInterfaceErrorWhenWificondFailed() throws Exception { - testSetupInterfaceForSoftApMode(); - when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME)).thenReturn(false); - - assertFalse(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME)); - verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME); - } - - /** - * Verifies that the SoftAp handles are cleared after teardown. - */ - @Test - public void testTeardownSoftApInterfaceClearsHandles() throws Exception { - testTeardownSoftApInterface(); - - assertFalse(mWificondControl.registerApCallback( - TEST_INTERFACE_NAME, Runnable::run, mSoftApListener)); - verify(mApInterface, never()).registerCallback(any()); - } - - /** - * Verifies that we can setup concurrent interfaces. - */ - @Test - public void testSetupMultipleInterfaces() throws Exception { - when(mWificond.createApInterface(TEST_INTERFACE_NAME1)).thenReturn(mApInterface); - - assertEquals(true, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME1)); - - verify(mWificond).createClientInterface(TEST_INTERFACE_NAME); - verify(mWificond).createApInterface(TEST_INTERFACE_NAME1); - } - - /** - * Verifies that we can setup concurrent interfaces. - */ - @Test - public void testTeardownMultipleInterfaces() throws Exception { - testSetupMultipleInterfaces(); - assertTrue(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); - assertTrue(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME1)); - - verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME); - verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME1); - } - - /** - * Verifies that tearDownInterfaces() calls wificond. - */ - @Test - public void testTearDownInterfaces() throws Exception { - assertTrue(mWificondControl.tearDownInterfaces()); - verify(mWificond).tearDownInterfaces(); - } - - /** - * Verifies that tearDownInterfaces() calls unsubscribeScanEvents() when there was - * a configured client interface. - */ - @Test - public void testTearDownInterfacesRemovesScanEventSubscription() throws Exception { - assertTrue(mWificondControl.tearDownInterfaces()); - verify(mWifiScannerImpl).unsubscribeScanEvents(); - } - - /** - * Verifies that tearDownInterfaces() returns false when wificond is not started. - */ - @Test - public void testTearDownInterfacesErrorWhenWificondIsNotStarterd() throws Exception { - // Invoke wificond death handler to clear the handle. - mWificondControl.binderDied(); - mLooper.dispatchAll(); - assertFalse(mWificondControl.tearDownInterfaces()); - } - - /** - * Verifies that signalPoll() calls wificond. - */ - @Test - public void testSignalPoll() throws Exception { - when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); - - mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, Runnable::run, - mNormalScanCallback, mPnoScanCallback); - mWificondControl.signalPoll(TEST_INTERFACE_NAME); - verify(mClientInterface).signalPoll(); - } - - /** - * Verifies that signalPoll() returns null when there is no configured client interface. - */ - @Test - public void testSignalPollErrorWhenNoClientInterfaceConfigured() throws Exception { - when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); - - // Configure client interface. - assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, - Runnable::run, mNormalScanCallback, mPnoScanCallback)); - - // Tear down interfaces. - assertTrue(mWificondControl.tearDownInterfaces()); - - // Signal poll should fail. - assertEquals(null, mWificondControl.signalPoll(TEST_INTERFACE_NAME)); - } - - /** - * Verifies that getTxPacketCounters() calls wificond. - */ - @Test - public void testGetTxPacketCounters() throws Exception { - when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); - - mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, Runnable::run, - mNormalScanCallback, mPnoScanCallback); - mWificondControl.getTxPacketCounters(TEST_INTERFACE_NAME); - verify(mClientInterface).getPacketCounters(); - } - - /** - * Verifies that getTxPacketCounters() returns null when there is no configured client - * interface. - */ - @Test - public void testGetTxPacketCountersErrorWhenNoClientInterfaceConfigured() throws Exception { - when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); - - // Configure client interface. - assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, - Runnable::run, mNormalScanCallback, mPnoScanCallback)); - - // Tear down interfaces. - assertTrue(mWificondControl.tearDownInterfaces()); - - // Signal poll should fail. - assertEquals(null, mWificondControl.getTxPacketCounters(TEST_INTERFACE_NAME)); - } - - /** - * Verifies that getScanResults() returns null when there is no configured client - * interface. - */ - @Test - public void testGetScanResultsErrorWhenNoClientInterfaceConfigured() throws Exception { - when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); - - // Configure client interface. - assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, - Runnable::run, mNormalScanCallback, mPnoScanCallback)); - - // Tear down interfaces. - assertTrue(mWificondControl.tearDownInterfaces()); - - // getScanResults should fail. - assertEquals(0, - mWificondControl.getScanResults(TEST_INTERFACE_NAME, - WifiNl80211Manager.SCAN_TYPE_SINGLE_SCAN).size()); - } - - /** - * Verifies that Scan() can convert input parameters to SingleScanSettings correctly. - */ - @Test - public void testScan() throws Exception { - when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true); - assertTrue(mWificondControl.startScan( - TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_POWER, - SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); - verify(mWifiScannerImpl).scan(argThat(new ScanMatcher( - IWifiScannerImpl.SCAN_TYPE_LOW_POWER, - SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST))); - } - - /** - * Verifies that Scan() removes duplicates hiddenSsids passed in from input. - */ - @Test - public void testScanWithDuplicateHiddenSsids() throws Exception { - when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true); - // Create a list of hiddenSsid that has a duplicate element - List hiddenSsidWithDup = new ArrayList<>(SCAN_HIDDEN_NETWORK_SSID_LIST); - hiddenSsidWithDup.add(SCAN_HIDDEN_NETWORK_SSID_LIST.get(0)); - assertEquals(hiddenSsidWithDup.get(0), - hiddenSsidWithDup.get(hiddenSsidWithDup.size() - 1)); - // Pass the List with duplicate elements into scan() - assertTrue(mWificondControl.startScan( - TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_POWER, - SCAN_FREQ_SET, hiddenSsidWithDup)); - // But the argument passed down should have the duplicate removed. - verify(mWifiScannerImpl).scan(argThat(new ScanMatcher( - IWifiScannerImpl.SCAN_TYPE_LOW_POWER, - SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST))); - } - - /** - * Verifies that Scan() can handle null input parameters correctly. - */ - @Test - public void testScanNullParameters() throws Exception { - when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true); - assertTrue(mWificondControl.startScan( - TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_HIGH_ACCURACY, null, null)); - verify(mWifiScannerImpl).scan(argThat(new ScanMatcher( - IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY, null, null))); - } - - /** - * Verifies that Scan() can handle wificond scan failure. - */ - @Test - public void testScanFailure() throws Exception { - when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(false); - assertFalse(mWificondControl.startScan( - TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_LATENCY, - SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); - verify(mWifiScannerImpl).scan(any(SingleScanSettings.class)); - } - - /** - * Verifies that Scan() can handle invalid type. - */ - @Test - public void testScanFailureDueToInvalidType() throws Exception { - assertFalse(mWificondControl.startScan( - TEST_INTERFACE_NAME, 100, - SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); - verify(mWifiScannerImpl, never()).scan(any(SingleScanSettings.class)); - } - - /** - * Verifies that startPnoScan() can convert input parameters to PnoSettings correctly. - */ - @Test - public void testStartPnoScan() throws Exception { - when(mWifiScannerImpl.startPnoScan(any(PnoSettings.class))).thenReturn(true); - assertTrue( - mWificondControl.startPnoScan(TEST_INTERFACE_NAME, TEST_PNO_SETTINGS, Runnable::run, - mPnoScanRequestCallback)); - verify(mWifiScannerImpl).startPnoScan(eq(TEST_PNO_SETTINGS)); - verify(mPnoScanRequestCallback).onPnoRequestSucceeded(); - } - - /** - * Verifies that stopPnoScan() calls underlying wificond. - */ - @Test - public void testStopPnoScan() throws Exception { - when(mWifiScannerImpl.stopPnoScan()).thenReturn(true); - assertTrue(mWificondControl.stopPnoScan(TEST_INTERFACE_NAME)); - verify(mWifiScannerImpl).stopPnoScan(); - } - - /** - * Verifies that stopPnoScan() can handle wificond failure. - */ - @Test - public void testStopPnoScanFailure() throws Exception { - - when(mWifiScannerImpl.stopPnoScan()).thenReturn(false); - assertFalse(mWificondControl.stopPnoScan(TEST_INTERFACE_NAME)); - verify(mWifiScannerImpl).stopPnoScan(); - } - - /** - * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon scan - * result event. - */ - @Test - public void testScanResultEvent() throws Exception { - ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(IScanEvent.class); - verify(mWifiScannerImpl).subscribeScanEvents(messageCaptor.capture()); - IScanEvent scanEvent = messageCaptor.getValue(); - assertNotNull(scanEvent); - scanEvent.OnScanResultReady(); - - verify(mNormalScanCallback).onScanResultReady(); - } - - /** - * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon scan - * failed event. - */ - @Test - public void testScanFailedEvent() throws Exception { - ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(IScanEvent.class); - verify(mWifiScannerImpl).subscribeScanEvents(messageCaptor.capture()); - IScanEvent scanEvent = messageCaptor.getValue(); - assertNotNull(scanEvent); - scanEvent.OnScanFailed(); - - verify(mNormalScanCallback).onScanFailed(); - } - - /** - * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon pno scan - * result event. - */ - @Test - public void testPnoScanResultEvent() throws Exception { - ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(IPnoScanEvent.class); - verify(mWifiScannerImpl).subscribePnoScanEvents(messageCaptor.capture()); - IPnoScanEvent pnoScanEvent = messageCaptor.getValue(); - assertNotNull(pnoScanEvent); - pnoScanEvent.OnPnoNetworkFound(); - verify(mPnoScanCallback).onScanResultReady(); - } - - /** - * Verifies that WificondControl can invoke WifiMetrics pno scan count methods upon pno event. - */ - @Test - public void testPnoScanEventsForMetrics() throws Exception { - ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(IPnoScanEvent.class); - verify(mWifiScannerImpl).subscribePnoScanEvents(messageCaptor.capture()); - IPnoScanEvent pnoScanEvent = messageCaptor.getValue(); - assertNotNull(pnoScanEvent); - - pnoScanEvent.OnPnoNetworkFound(); - verify(mPnoScanCallback).onScanResultReady(); - - pnoScanEvent.OnPnoScanFailed(); - verify(mPnoScanCallback).onScanFailed(); - } - - /** - * Verifies that startPnoScan() can invoke WifiMetrics pno scan count methods correctly. - */ - @Test - public void testStartPnoScanForMetrics() throws Exception { - when(mWifiScannerImpl.startPnoScan(any(PnoSettings.class))).thenReturn(false); - - assertFalse( - mWificondControl.startPnoScan(TEST_INTERFACE_NAME, TEST_PNO_SETTINGS, Runnable::run, - mPnoScanRequestCallback)); - verify(mPnoScanRequestCallback).onPnoRequestFailed(); - } - - /** - * Verifies that abortScan() calls underlying wificond. - */ - @Test - public void testAbortScan() throws Exception { - mWificondControl.abortScan(TEST_INTERFACE_NAME); - verify(mWifiScannerImpl).abortScan(); - } - - /** - * Ensures that the Ap interface callbacks are forwarded to the - * SoftApListener used for starting soft AP. - */ - @Test - public void testSoftApListenerInvocation() throws Exception { - testSetupInterfaceForSoftApMode(); - - WifiConfiguration config = new WifiConfiguration(); - config.SSID = new String(TEST_SSID, StandardCharsets.UTF_8); - - when(mApInterface.registerCallback(any())).thenReturn(true); - - final ArgumentCaptor apInterfaceCallbackCaptor = - ArgumentCaptor.forClass(IApInterfaceEventCallback.class); - - assertTrue(mWificondControl.registerApCallback( - TEST_INTERFACE_NAME, Runnable::run, mSoftApListener)); - verify(mApInterface).registerCallback(apInterfaceCallbackCaptor.capture()); - - final NativeWifiClient testClient = new NativeWifiClient(TEST_RAW_MAC_BYTES); - apInterfaceCallbackCaptor.getValue().onConnectedClientsChanged(testClient, true); - verify(mSoftApListener).onConnectedClientsChanged(eq(testClient), eq(true)); - - int channelFrequency = 2437; - int channelBandwidth = IApInterfaceEventCallback.BANDWIDTH_20; - apInterfaceCallbackCaptor.getValue().onSoftApChannelSwitched(channelFrequency, - channelBandwidth); - verify(mSoftApListener).onSoftApChannelSwitched(eq(channelFrequency), - eq(SoftApInfo.CHANNEL_WIDTH_20MHZ)); - } - - /** - * Verifies registration and invocation of wificond death handler. - */ - @Test - public void testRegisterDeathHandler() throws Exception { - Runnable deathHandler = mock(Runnable.class); - mWificondControl.setOnServiceDeadCallback(deathHandler); - mWificondControl.binderDied(); - mLooper.dispatchAll(); - verify(deathHandler).run(); - } - - /** - * Verifies handling of wificond death and ensures that all internal state is cleared and - * handlers are invoked. - */ - @Test - public void testDeathHandling() throws Exception { - Runnable deathHandler = mock(Runnable.class); - mWificondControl.setOnServiceDeadCallback(deathHandler); - - testSetupInterfaceForClientMode(); - - mWificondControl.binderDied(); - mLooper.dispatchAll(); - verify(deathHandler).run(); - - // The handles should be cleared after death. - assertEquals(0, mWificondControl.getChannelsMhzForBand(WifiScanner.WIFI_BAND_5_GHZ).length); - verify(mWificond, never()).getAvailable5gNonDFSChannels(); - } - - /** - * sendMgmtFrame() should fail if a null callback is passed in. - */ - @Test - public void testSendMgmtFrameNullCallback() throws Exception { - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, - Runnable::run, null); - - verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt()); - } - - /** - * sendMgmtFrame() should fail if a null frame is passed in. - */ - @Test - public void testSendMgmtFrameNullFrame() throws Exception { - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, null, TEST_MCS_RATE, Runnable::run, - mSendMgmtFrameCallback); - - verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt()); - verify(mSendMgmtFrameCallback).onFailure(anyInt()); - } - - /** - * sendMgmtFrame() should fail if an interface name that does not exist is passed in. - */ - @Test - public void testSendMgmtFrameInvalidInterfaceName() throws Exception { - mWificondControl.sendMgmtFrame(TEST_INVALID_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, - Runnable::run, mSendMgmtFrameCallback); - - verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt()); - verify(mSendMgmtFrameCallback).onFailure(anyInt()); - } - - /** - * sendMgmtFrame() should fail if it is called a second time before the first call completed. - */ - @Test - public void testSendMgmtFrameCalledTwiceBeforeFinished() throws Exception { - WifiNl80211Manager.SendMgmtFrameCallback cb1 = mock( - WifiNl80211Manager.SendMgmtFrameCallback.class); - WifiNl80211Manager.SendMgmtFrameCallback cb2 = mock( - WifiNl80211Manager.SendMgmtFrameCallback.class); - - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, - Runnable::run, cb1); - verify(cb1, never()).onFailure(anyInt()); - verify(mClientInterface, times(1)) - .SendMgmtFrame(AdditionalMatchers.aryEq(TEST_PROBE_FRAME), - any(), eq(TEST_MCS_RATE)); - - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, - Runnable::run, cb2); - verify(cb2).onFailure(WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_ALREADY_STARTED); - // verify SendMgmtFrame() still was only called once i.e. not called again - verify(mClientInterface, times(1)) - .SendMgmtFrame(any(), any(), anyInt()); - } - - /** - * Tests that when a RemoteException is triggered on AIDL call, onFailure() is called only once. - */ - @Test - public void testSendMgmtFrameThrowsException() throws Exception { - WifiNl80211Manager.SendMgmtFrameCallback cb = mock( - WifiNl80211Manager.SendMgmtFrameCallback.class); - - final ArgumentCaptor sendMgmtFrameEventCaptor = - ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); - - doThrow(new RemoteException()).when(mClientInterface) - .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); - - final ArgumentCaptor alarmListenerCaptor = - ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); - final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); - doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), - alarmListenerCaptor.capture(), handlerCaptor.capture()); - - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, - Runnable::run, cb); - mLooper.dispatchAll(); - - verify(cb).onFailure(anyInt()); - verify(mAlarmManager).cancel(eq(alarmListenerCaptor.getValue())); - - sendMgmtFrameEventCaptor.getValue().OnFailure( - WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_UNKNOWN); - mLooper.dispatchAll(); - - handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); - mLooper.dispatchAll(); - - verifyNoMoreInteractions(cb); - } - - /** - * Tests that the onAck() callback is triggered correctly. - */ - @Test - public void testSendMgmtFrameSuccess() throws Exception { - WifiNl80211Manager.SendMgmtFrameCallback cb = mock( - WifiNl80211Manager.SendMgmtFrameCallback.class); - - final ArgumentCaptor sendMgmtFrameEventCaptor = - ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); - doNothing().when(mClientInterface) - .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); - final ArgumentCaptor alarmListenerCaptor = - ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); - final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); - doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), - alarmListenerCaptor.capture(), handlerCaptor.capture()); - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, - Runnable::run, cb); - - sendMgmtFrameEventCaptor.getValue().OnAck(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS); - mLooper.dispatchAll(); - verify(cb).onAck(eq(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS)); - verify(cb, never()).onFailure(anyInt()); - verify(mAlarmManager).cancel(eq(alarmListenerCaptor.getValue())); - - // verify that even if timeout is triggered afterwards, SendMgmtFrameCallback is not - // triggered again - handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); - mLooper.dispatchAll(); - verify(cb, times(1)).onAck(anyInt()); - verify(cb, never()).onFailure(anyInt()); - } - - /** - * Tests that the onFailure() callback is triggered correctly. - */ - @Test - public void testSendMgmtFrameFailure() throws Exception { - WifiNl80211Manager.SendMgmtFrameCallback cb = mock( - WifiNl80211Manager.SendMgmtFrameCallback.class); - - final ArgumentCaptor sendMgmtFrameEventCaptor = - ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); - doNothing().when(mClientInterface) - .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); - final ArgumentCaptor alarmListenerCaptor = - ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); - final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); - doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), - alarmListenerCaptor.capture(), handlerCaptor.capture()); - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, - Runnable::run, cb); - - sendMgmtFrameEventCaptor.getValue().OnFailure( - WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_UNKNOWN); - mLooper.dispatchAll(); - verify(cb, never()).onAck(anyInt()); - verify(cb).onFailure(WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_UNKNOWN); - verify(mAlarmManager).cancel(eq(alarmListenerCaptor.getValue())); - - // verify that even if timeout is triggered afterwards, SendMgmtFrameCallback is not - // triggered again - handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); - mLooper.dispatchAll(); - verify(cb, never()).onAck(anyInt()); - verify(cb, times(1)).onFailure(anyInt()); - } - - /** - * Tests that the onTimeout() callback is triggered correctly. - */ - @Test - public void testSendMgmtFrameTimeout() throws Exception { - WifiNl80211Manager.SendMgmtFrameCallback cb = mock( - WifiNl80211Manager.SendMgmtFrameCallback.class); - - final ArgumentCaptor sendMgmtFrameEventCaptor = - ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); - doNothing().when(mClientInterface) - .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); - final ArgumentCaptor alarmListenerCaptor = - ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); - final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); - doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), - alarmListenerCaptor.capture(), handlerCaptor.capture()); - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, - Runnable::run, cb); - - handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); - mLooper.dispatchAll(); - verify(cb, never()).onAck(anyInt()); - verify(cb).onFailure(WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_TIMEOUT); - - // verify that even if onAck() callback is triggered after timeout, - // SendMgmtFrameCallback is not triggered again - sendMgmtFrameEventCaptor.getValue().OnAck(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS); - mLooper.dispatchAll(); - verify(cb, never()).onAck(anyInt()); - verify(cb, times(1)).onFailure(anyInt()); - } - - /** - * Tests every possible test outcome followed by every other test outcome to ensure that the - * internal state is reset correctly between calls. - * i.e. (success, success), (success, failure), (success, timeout), - * (failure, failure), (failure, success), (failure, timeout), - * (timeout, timeout), (timeout, success), (timeout, failure) - * - * Also tests that internal state is reset correctly after a transient AIDL RemoteException. - */ - @Test - public void testSendMgmtFrameMixed() throws Exception { - testSendMgmtFrameThrowsException(); - testSendMgmtFrameSuccess(); - testSendMgmtFrameSuccess(); - testSendMgmtFrameFailure(); - testSendMgmtFrameFailure(); - testSendMgmtFrameTimeout(); - testSendMgmtFrameTimeout(); - testSendMgmtFrameSuccess(); - testSendMgmtFrameTimeout(); - testSendMgmtFrameFailure(); - testSendMgmtFrameSuccess(); - } - - /** - * Tests that OnAck() does not perform any non-thread-safe operations on the binder thread. - * - * The sequence of instructions are: - * 1. post onAlarm() onto main thread - * 2. OnAck() - * 3. mLooper.dispatchAll() - * - * The actual order of execution is: - * 1. binder thread portion of OnAck() - * 2. onAlarm() (which purely executes on the main thread) - * 3. main thread portion of OnAck() - * - * If the binder thread portion of OnAck() is not thread-safe, it can possibly mess up - * onAlarm(). Tests that this does not occur. - */ - @Test - public void testSendMgmtFrameTimeoutAckThreadSafe() throws Exception { - final ArgumentCaptor sendMgmtFrameEventCaptor = - ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); - doNothing().when(mClientInterface) - .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); - final ArgumentCaptor alarmListenerCaptor = - ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); - final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); - doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), - alarmListenerCaptor.capture(), handlerCaptor.capture()); - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, - Runnable::run, mSendMgmtFrameCallback); - - // AlarmManager should post the onAlarm() callback onto the handler, but since we are - // triggering onAlarm() ourselves during the test, manually post onto handler - handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); - // OnAck posts to the handler - sendMgmtFrameEventCaptor.getValue().OnAck(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS); - mLooper.dispatchAll(); - verify(mSendMgmtFrameCallback, never()).onAck(anyInt()); - verify(mSendMgmtFrameCallback).onFailure( - WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_TIMEOUT); - } - - /** - * See {@link #testSendMgmtFrameTimeoutAckThreadSafe()}. This test replaces OnAck() with - * OnFailure(). - */ - @Test - public void testSendMgmtFrameTimeoutFailureThreadSafe() throws Exception { - final ArgumentCaptor sendMgmtFrameEventCaptor = - ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); - doNothing().when(mClientInterface) - .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); - final ArgumentCaptor alarmListenerCaptor = - ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); - final ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(Handler.class); - doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), - alarmListenerCaptor.capture(), handlerCaptor.capture()); - mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, - Runnable::run, mSendMgmtFrameCallback); - - // AlarmManager should post the onAlarm() callback onto the handler, but since we are - // triggering onAlarm() ourselves during the test, manually post onto handler - handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); - // OnFailure posts to the handler - sendMgmtFrameEventCaptor.getValue().OnFailure( - WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_UNKNOWN); - mLooper.dispatchAll(); - verify(mSendMgmtFrameCallback).onFailure( - WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_TIMEOUT); - } - - /** - * Tests getDeviceWiphyCapabililties - */ - @Test - public void testGetDeviceWiphyCapabilities() throws Exception { - DeviceWiphyCapabilities capaExpected = new DeviceWiphyCapabilities(); - - capaExpected.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, true); - capaExpected.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, true); - capaExpected.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AX, false); - capaExpected.setChannelWidthSupported(ScanResult.CHANNEL_WIDTH_160MHZ, true); - capaExpected.setChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ, false); - capaExpected.setMaxNumberTxSpatialStreams(2); - capaExpected.setMaxNumberRxSpatialStreams(1); - - when(mWificond.getDeviceWiphyCapabilities(TEST_INTERFACE_NAME)) - .thenReturn(capaExpected); - - DeviceWiphyCapabilities capaActual = - mWificondControl.getDeviceWiphyCapabilities(TEST_INTERFACE_NAME); - assertEquals(capaExpected, capaActual); - } - - // Create a ArgumentMatcher which captures a SingleScanSettings parameter and checks if it - // matches the provided frequency set and ssid set. - private class ScanMatcher implements ArgumentMatcher { - int mExpectedScanType; - private final Set mExpectedFreqs; - private final List mExpectedSsids; - - ScanMatcher(int expectedScanType, Set expectedFreqs, List expectedSsids) { - this.mExpectedScanType = expectedScanType; - this.mExpectedFreqs = expectedFreqs; - this.mExpectedSsids = expectedSsids; - } - - @Override - public boolean matches(SingleScanSettings settings) { - if (settings.scanType != mExpectedScanType) { - return false; - } - ArrayList channelSettings = settings.channelSettings; - ArrayList hiddenNetworks = settings.hiddenNetworks; - if (mExpectedFreqs != null) { - Set freqSet = new HashSet(); - for (ChannelSettings channel : channelSettings) { - freqSet.add(channel.frequency); - } - if (!mExpectedFreqs.equals(freqSet)) { - return false; - } - } else { - if (channelSettings != null && channelSettings.size() > 0) { - return false; - } - } - - if (mExpectedSsids != null) { - List ssidSet = new ArrayList<>(); - for (HiddenNetwork network : hiddenNetworks) { - ssidSet.add(network.ssid); - } - if (!mExpectedSsids.equals(ssidSet)) { - return false; - } - - } else { - if (hiddenNetworks != null && hiddenNetworks.size() > 0) { - return false; - } - } - return true; - } - - @Override - public String toString() { - return "ScanMatcher{mExpectedFreqs=" + mExpectedFreqs - + ", mExpectedSsids=" + mExpectedSsids + '}'; - } - } - - private static class LocalNativeUtil { - private static final int SSID_BYTES_MAX_LEN = 32; - - /** - * Converts an ArrayList of UTF_8 byte values to string. - * The string will either be: - * a) UTF-8 String encapsulated in quotes (if all the bytes are UTF-8 encodeable and non - * null), - * or - * b) Hex string with no delimiters. - * - * @param bytes List of bytes for ssid. - * @throws IllegalArgumentException for null bytes. - */ - public static String bytesToHexOrQuotedString(ArrayList bytes) { - if (bytes == null) { - throw new IllegalArgumentException("null ssid bytes"); - } - byte[] byteArray = byteArrayFromArrayList(bytes); - // Check for 0's in the byte stream in which case we cannot convert this into a string. - if (!bytes.contains(Byte.valueOf((byte) 0))) { - CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder(); - try { - CharBuffer decoded = decoder.decode(ByteBuffer.wrap(byteArray)); - return "\"" + decoded.toString() + "\""; - } catch (CharacterCodingException cce) { - } - } - return hexStringFromByteArray(byteArray); - } - - /** - * Converts an ssid string to an arraylist of UTF_8 byte values. - * These forms are acceptable: - * a) UTF-8 String encapsulated in quotes, or - * b) Hex string with no delimiters. - * - * @param ssidStr String to be converted. - * @throws IllegalArgumentException for null string. - */ - public static ArrayList decodeSsid(String ssidStr) { - ArrayList ssidBytes = hexOrQuotedStringToBytes(ssidStr); - if (ssidBytes.size() > SSID_BYTES_MAX_LEN) { - throw new IllegalArgumentException( - "ssid bytes size out of range: " + ssidBytes.size()); - } - return ssidBytes; - } - - /** - * Convert from an array list of Byte to an array of primitive bytes. - */ - public static byte[] byteArrayFromArrayList(ArrayList bytes) { - byte[] byteArray = new byte[bytes.size()]; - int i = 0; - for (Byte b : bytes) { - byteArray[i++] = b; - } - return byteArray; - } - - /** - * Converts a byte array to hex string. - * - * @param bytes List of bytes for ssid. - * @throws IllegalArgumentException for null bytes. - */ - public static String hexStringFromByteArray(byte[] bytes) { - if (bytes == null) { - throw new IllegalArgumentException("null hex bytes"); - } - return new String(HexEncoding.encode(bytes)).toLowerCase(); - } - - /** - * Converts an string to an arraylist of UTF_8 byte values. - * These forms are acceptable: - * a) UTF-8 String encapsulated in quotes, or - * b) Hex string with no delimiters. - * - * @param str String to be converted. - * @throws IllegalArgumentException for null string. - */ - public static ArrayList hexOrQuotedStringToBytes(String str) { - if (str == null) { - throw new IllegalArgumentException("null string"); - } - int length = str.length(); - if ((length > 1) && (str.charAt(0) == '"') && (str.charAt(length - 1) == '"')) { - str = str.substring(1, str.length() - 1); - return stringToByteArrayList(str); - } else { - return byteArrayToArrayList(hexStringToByteArray(str)); - } - } - - /** - * Convert the string to byte array list. - * - * @return the UTF_8 char byte values of str, as an ArrayList. - * @throws IllegalArgumentException if a null or unencodable string is sent. - */ - public static ArrayList stringToByteArrayList(String str) { - if (str == null) { - throw new IllegalArgumentException("null string"); - } - // Ensure that the provided string is UTF_8 encoded. - CharsetEncoder encoder = StandardCharsets.UTF_8.newEncoder(); - try { - ByteBuffer encoded = encoder.encode(CharBuffer.wrap(str)); - byte[] byteArray = new byte[encoded.remaining()]; - encoded.get(byteArray); - return byteArrayToArrayList(byteArray); - } catch (CharacterCodingException cce) { - throw new IllegalArgumentException("cannot be utf-8 encoded", cce); - } - } - - /** - * Convert from an array of primitive bytes to an array list of Byte. - */ - public static ArrayList byteArrayToArrayList(byte[] bytes) { - ArrayList byteList = new ArrayList<>(); - for (Byte b : bytes) { - byteList.add(b); - } - return byteList; - } - - /** - * Converts a hex string to byte array. - * - * @param hexStr String to be converted. - * @throws IllegalArgumentException for null string. - */ - public static byte[] hexStringToByteArray(String hexStr) { - if (hexStr == null) { - throw new IllegalArgumentException("null hex string"); - } - return HexEncoding.decode(hexStr.toCharArray(), false); - } - } -} -- cgit v1.2.3 From 1caf57d5cabd2353321bb37fe586fc23ab22add3 Mon Sep 17 00:00:00 2001 From: Arc Wang Date: Thu, 13 Feb 2020 15:17:03 +0800 Subject: Rename PasspointConfiguration#getSubscriptionExpirationTimeInMillis Rename to getSubscriptionExpirationTimeMillis. Bug: 149434940 Test: compiles Change-Id: I34f395d14bc03432170ecf2d331cf1bf5088ae68 --- wifi/Android.bp | 1 + .../net/wifi/hotspot2/PasspointConfiguration.java | 22 ++++++++++++---------- 2 files changed, 13 insertions(+), 10 deletions(-) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 1763975e7770..7669983f20aa 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -86,6 +86,7 @@ java_library { // TODO(b/146757305): should be unnecessary once // sdk_version="module_lib_current" "android_system_stubs_current", + "framework_mediaprovider_annotation", // for android.annotation.CurrentTimeMillisLong ], srcs: [ ":framework-wifi-updatable-sources", diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java index 9f581849efca..ba2ae73872bc 100644 --- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java +++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java @@ -19,6 +19,7 @@ package android.net.wifi.hotspot2; import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_NONE; import static android.net.wifi.WifiConfiguration.MeteredOverride; +import android.annotation.CurrentTimeMillisLong; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; @@ -247,12 +248,12 @@ public final class PasspointConfiguration implements Parcelable { * * Use Long.MIN_VALUE to indicate unset value. */ - private long mSubscriptionExpirationTimeInMillis = Long.MIN_VALUE; + private long mSubscriptionExpirationTimeMillis = Long.MIN_VALUE; /** * @hide */ public void setSubscriptionExpirationTimeInMillis(long subscriptionExpirationTimeInMillis) { - mSubscriptionExpirationTimeInMillis = subscriptionExpirationTimeInMillis; + mSubscriptionExpirationTimeMillis = subscriptionExpirationTimeInMillis; } /** * Utility method to get the time this subscription will expire. It is in the format of number @@ -260,8 +261,9 @@ public final class PasspointConfiguration implements Parcelable { * * @return The time this subscription will expire, or Long.MIN_VALUE to indicate unset value */ - public long getSubscriptionExpirationTimeInMillis() { - return mSubscriptionExpirationTimeInMillis; + @CurrentTimeMillisLong + public long getSubscriptionExpirationTimeMillis() { + return mSubscriptionExpirationTimeMillis; } /** @@ -561,7 +563,7 @@ public final class PasspointConfiguration implements Parcelable { mUpdateIdentifier = source.mUpdateIdentifier; mCredentialPriority = source.mCredentialPriority; mSubscriptionCreationTimeInMillis = source.mSubscriptionCreationTimeInMillis; - mSubscriptionExpirationTimeInMillis = source.mSubscriptionExpirationTimeInMillis; + mSubscriptionExpirationTimeMillis = source.mSubscriptionExpirationTimeMillis; mSubscriptionType = source.mSubscriptionType; mUsageLimitDataLimit = source.mUsageLimitDataLimit; mUsageLimitStartTimeInMillis = source.mUsageLimitStartTimeInMillis; @@ -590,7 +592,7 @@ public final class PasspointConfiguration implements Parcelable { dest.writeInt(mUpdateIdentifier); dest.writeInt(mCredentialPriority); dest.writeLong(mSubscriptionCreationTimeInMillis); - dest.writeLong(mSubscriptionExpirationTimeInMillis); + dest.writeLong(mSubscriptionExpirationTimeMillis); dest.writeString(mSubscriptionType); dest.writeLong(mUsageLimitUsageTimePeriodInMinutes); dest.writeLong(mUsageLimitStartTimeInMillis); @@ -628,7 +630,7 @@ public final class PasspointConfiguration implements Parcelable { && mUpdateIdentifier == that.mUpdateIdentifier && mCredentialPriority == that.mCredentialPriority && mSubscriptionCreationTimeInMillis == that.mSubscriptionCreationTimeInMillis - && mSubscriptionExpirationTimeInMillis == that.mSubscriptionExpirationTimeInMillis + && mSubscriptionExpirationTimeMillis == that.mSubscriptionExpirationTimeMillis && TextUtils.equals(mSubscriptionType, that.mSubscriptionType) && mUsageLimitUsageTimePeriodInMinutes == that.mUsageLimitUsageTimePeriodInMinutes && mUsageLimitStartTimeInMillis == that.mUsageLimitStartTimeInMillis @@ -646,7 +648,7 @@ public final class PasspointConfiguration implements Parcelable { public int hashCode() { return Objects.hash(mHomeSp, mCredential, mPolicy, mSubscriptionUpdate, mTrustRootCertList, mUpdateIdentifier, mCredentialPriority, mSubscriptionCreationTimeInMillis, - mSubscriptionExpirationTimeInMillis, mUsageLimitUsageTimePeriodInMinutes, + mSubscriptionExpirationTimeMillis, mUsageLimitUsageTimePeriodInMinutes, mUsageLimitStartTimeInMillis, mUsageLimitDataLimit, mUsageLimitTimeLimitInMinutes, mServiceFriendlyNames, mCarrierId, mIsAutojoinEnabled, mIsMacRandomizationEnabled, mMeteredOverride); @@ -661,8 +663,8 @@ public final class PasspointConfiguration implements Parcelable { mSubscriptionCreationTimeInMillis != Long.MIN_VALUE ? new Date(mSubscriptionCreationTimeInMillis) : "Not specified").append("\n"); builder.append("SubscriptionExpirationTime: ").append( - mSubscriptionExpirationTimeInMillis != Long.MIN_VALUE - ? new Date(mSubscriptionExpirationTimeInMillis) : "Not specified").append("\n"); + mSubscriptionExpirationTimeMillis != Long.MIN_VALUE + ? new Date(mSubscriptionExpirationTimeMillis) : "Not specified").append("\n"); builder.append("UsageLimitStartTime: ").append(mUsageLimitStartTimeInMillis != Long.MIN_VALUE ? new Date(mUsageLimitStartTimeInMillis) : "Not specified").append("\n"); builder.append("UsageTimePeriod: ").append(mUsageLimitUsageTimePeriodInMinutes) -- cgit v1.2.3 From 1861fa18bec911426c4645eb8a2236d328d47fa1 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Mon, 10 Feb 2020 11:53:26 -0800 Subject: SoftApConfiguration: Add shutdown enabled method This allows us to stop relying on the @hide Settings.Global value. Bug: 147779354 Bug: 148514485 Test: atest android.net.wifi Change-Id: Iacd5553f971cf5bfe1e794b01179e29cb65a1925 --- .../java/android/net/wifi/SoftApConfiguration.java | 71 ++++++++++++++++++---- .../android/net/wifi/SoftApConfigurationTest.java | 2 + 2 files changed, 61 insertions(+), 12 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java index 0db3313ae137..ae5bf7d5ae84 100644 --- a/wifi/java/android/net/wifi/SoftApConfiguration.java +++ b/wifi/java/android/net/wifi/SoftApConfiguration.java @@ -17,6 +17,7 @@ package android.net.wifi; import android.annotation.IntDef; +import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; @@ -201,6 +202,11 @@ public final class SoftApConfiguration implements Parcelable { */ private final List mAllowedClientList; + /** + * Whether auto shutdown of soft AP is enabled or not. + */ + private final boolean mAutoShutdownEnabled; + /** * Delay in milliseconds before shutting down soft AP when * there are no connected devices. @@ -240,9 +246,9 @@ public final class SoftApConfiguration implements Parcelable { /** Private constructor for Builder and Parcelable implementation. */ private SoftApConfiguration(@Nullable String ssid, @Nullable MacAddress bssid, @Nullable String passphrase, boolean hiddenSsid, @BandType int band, int channel, - @SecurityType int securityType, int maxNumberOfClients, int shutdownTimeoutMillis, - boolean clientControlByUser, @NonNull List blockedList, - @NonNull List allowedList) { + @SecurityType int securityType, int maxNumberOfClients, boolean shutdownTimeoutEnabled, + int shutdownTimeoutMillis, boolean clientControlByUser, + @NonNull List blockedList, @NonNull List allowedList) { mSsid = ssid; mBssid = bssid; mPassphrase = passphrase; @@ -251,6 +257,7 @@ public final class SoftApConfiguration implements Parcelable { mChannel = channel; mSecurityType = securityType; mMaxNumberOfClients = maxNumberOfClients; + mAutoShutdownEnabled = shutdownTimeoutEnabled; mShutdownTimeoutMillis = shutdownTimeoutMillis; mClientControlByUser = clientControlByUser; mBlockedClientList = new ArrayList<>(blockedList); @@ -274,6 +281,7 @@ public final class SoftApConfiguration implements Parcelable { && mChannel == other.mChannel && mSecurityType == other.mSecurityType && mMaxNumberOfClients == other.mMaxNumberOfClients + && mAutoShutdownEnabled == other.mAutoShutdownEnabled && mShutdownTimeoutMillis == other.mShutdownTimeoutMillis && mClientControlByUser == other.mClientControlByUser && Objects.equals(mBlockedClientList, other.mBlockedClientList) @@ -283,8 +291,9 @@ public final class SoftApConfiguration implements Parcelable { @Override public int hashCode() { return Objects.hash(mSsid, mBssid, mPassphrase, mHiddenSsid, - mBand, mChannel, mSecurityType, mMaxNumberOfClients, mShutdownTimeoutMillis, - mClientControlByUser, mBlockedClientList, mAllowedClientList); + mBand, mChannel, mSecurityType, mMaxNumberOfClients, mAutoShutdownEnabled, + mShutdownTimeoutMillis, mClientControlByUser, mBlockedClientList, + mAllowedClientList); } @Override @@ -299,6 +308,7 @@ public final class SoftApConfiguration implements Parcelable { sbuf.append(" \n Channel =").append(mChannel); sbuf.append(" \n SecurityType=").append(getSecurityType()); sbuf.append(" \n MaxClient=").append(mMaxNumberOfClients); + sbuf.append(" \n AutoShutdownEnabled=").append(mAutoShutdownEnabled); sbuf.append(" \n ShutdownTimeoutMillis=").append(mShutdownTimeoutMillis); sbuf.append(" \n ClientControlByUser=").append(mClientControlByUser); sbuf.append(" \n BlockedClientList=").append(mBlockedClientList); @@ -316,6 +326,7 @@ public final class SoftApConfiguration implements Parcelable { dest.writeInt(mChannel); dest.writeInt(mSecurityType); dest.writeInt(mMaxNumberOfClients); + dest.writeBoolean(mAutoShutdownEnabled); dest.writeInt(mShutdownTimeoutMillis); dest.writeBoolean(mClientControlByUser); dest.writeTypedList(mBlockedClientList); @@ -335,7 +346,7 @@ public final class SoftApConfiguration implements Parcelable { in.readString(), in.readParcelable(MacAddress.class.getClassLoader()), in.readString(), in.readBoolean(), in.readInt(), in.readInt(), in.readInt(), - in.readInt(), in.readInt(), in.readBoolean(), + in.readInt(), in.readBoolean(), in.readInt(), in.readBoolean(), in.createTypedArrayList(MacAddress.CREATOR), in.createTypedArrayList(MacAddress.CREATOR)); } @@ -428,6 +439,18 @@ public final class SoftApConfiguration implements Parcelable { return mMaxNumberOfClients; } + /** + * Returns whether auto shutdown is enabled or not. + * The Soft AP will shutdown when there are no devices associated to it for + * the timeout duration. See {@link Builder#setAutoShutdownEnabled(boolean)}. + * + * @hide + */ + @SystemApi + public boolean isAutoShutdownEnabled() { + return mAutoShutdownEnabled; + } + /** * Returns the shutdown timeout in milliseconds. * The Soft AP will shutdown when there are no devices associated to it for @@ -551,6 +574,7 @@ public final class SoftApConfiguration implements Parcelable { private int mChannel; private int mMaxNumberOfClients; private int mSecurityType; + private boolean mAutoShutdownEnabled; private int mShutdownTimeoutMillis; private boolean mClientControlByUser; private List mBlockedClientList; @@ -568,6 +592,7 @@ public final class SoftApConfiguration implements Parcelable { mChannel = 0; mMaxNumberOfClients = 0; mSecurityType = SECURITY_TYPE_OPEN; + mAutoShutdownEnabled = true; // enabled by default. mShutdownTimeoutMillis = 0; mClientControlByUser = false; mBlockedClientList = new ArrayList<>(); @@ -588,6 +613,7 @@ public final class SoftApConfiguration implements Parcelable { mChannel = other.mChannel; mMaxNumberOfClients = other.mMaxNumberOfClients; mSecurityType = other.mSecurityType; + mAutoShutdownEnabled = other.mAutoShutdownEnabled; mShutdownTimeoutMillis = other.mShutdownTimeoutMillis; mClientControlByUser = other.mClientControlByUser; mBlockedClientList = new ArrayList<>(other.mBlockedClientList); @@ -603,8 +629,8 @@ public final class SoftApConfiguration implements Parcelable { public SoftApConfiguration build() { return new SoftApConfiguration(mSsid, mBssid, mPassphrase, mHiddenSsid, mBand, mChannel, mSecurityType, mMaxNumberOfClients, - mShutdownTimeoutMillis, mClientControlByUser, mBlockedClientList, - mAllowedClientList); + mAutoShutdownEnabled, mShutdownTimeoutMillis, mClientControlByUser, + mBlockedClientList, mAllowedClientList); } /** @@ -789,7 +815,7 @@ public final class SoftApConfiguration implements Parcelable { * @return Builder for chaining. */ @NonNull - public Builder setMaxNumberOfClients(int maxNumberOfClients) { + public Builder setMaxNumberOfClients(@IntRange(from = 0) int maxNumberOfClients) { if (maxNumberOfClients < 0) { throw new IllegalArgumentException("maxNumberOfClients should be not negative"); } @@ -797,6 +823,25 @@ public final class SoftApConfiguration implements Parcelable { return this; } + /** + * Specifies whether auto shutdown is enabled or not. + * The Soft AP will shut down when there are no devices connected to it for + * the timeout duration. + * + *

    + *

  • If not set, defaults to true
  • + * + * @param enable true to enable, false to disable. + * @return Builder for chaining. + * + * @see #setShutdownTimeoutMillis(int) + */ + @NonNull + public Builder setAutoShutdownEnabled(boolean enable) { + mAutoShutdownEnabled = enable; + return this; + } + /** * Specifies the shutdown timeout in milliseconds. * The Soft AP will shut down when there are no devices connected to it for @@ -807,14 +852,16 @@ public final class SoftApConfiguration implements Parcelable { * *

    *

  • If not set, defaults to 0
  • - *
  • The shut down timout will apply when - * {@link Settings.Global.SOFT_AP_TIMEOUT_ENABLED} is true
  • + *
  • The shut down timeout will apply when {@link #setAutoShutdownEnabled(boolean)} is + * set to true
  • * * @param timeoutMillis milliseconds of the timeout delay. * @return Builder for chaining. + * + * @see #setAutoShutdownEnabled(boolean) */ @NonNull - public Builder setShutdownTimeoutMillis(int timeoutMillis) { + public Builder setShutdownTimeoutMillis(@IntRange(from = 0) int timeoutMillis) { if (timeoutMillis < 0) { throw new IllegalArgumentException("Invalid timeout value"); } diff --git a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java index d9584885a045..060ddf05b8d7 100644 --- a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java @@ -125,6 +125,7 @@ public class SoftApConfigurationTest { .setChannel(149, SoftApConfiguration.BAND_5GHZ) .setHiddenSsid(true) .setMaxNumberOfClients(10) + .setAutoShutdownEnabled(true) .setShutdownTimeoutMillis(500000) .enableClientControlByUser(true) .setClientList(testBlockedClientList, testAllowedClientList) @@ -136,6 +137,7 @@ public class SoftApConfigurationTest { assertThat(original.getChannel()).isEqualTo(149); assertThat(original.isHiddenSsid()).isEqualTo(true); assertThat(original.getMaxNumberOfClients()).isEqualTo(10); + assertThat(original.isAutoShutdownEnabled()).isEqualTo(true); assertThat(original.getShutdownTimeoutMillis()).isEqualTo(500000); assertThat(original.isClientControlByUserEnabled()).isEqualTo(true); assertThat(original.getBlockedClientList()).isEqualTo(testBlockedClientList); -- cgit v1.2.3 From 6398957728f963c04fa4f1b7379ebc140c8e5503 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Wed, 12 Feb 2020 12:48:00 -0800 Subject: WifiManager: Add API for scan always available toggle Needed for moving away from using Settings.Global values as pseudo APIs. Bug: 148514485 Test: atest android.net.wifi Test: Verified wifi wifi scan toggle in location settings. Change-Id: Iec75d331c7866180a55a327813466323c565319a --- wifi/java/android/net/wifi/IWifiManager.aidl | 2 ++ wifi/java/android/net/wifi/WifiManager.java | 20 ++++++++++++++++++++ wifi/tests/src/android/net/wifi/WifiManagerTest.java | 11 +++++++++++ 3 files changed, 33 insertions(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 1c330e263d7e..3025caf74000 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -125,6 +125,8 @@ interface IWifiManager DhcpInfo getDhcpInfo(); + void setScanAlwaysAvailable(boolean isAvailable); + boolean isScanAlwaysAvailable(); boolean acquireWifiLock(IBinder lock, int lockType, String tag, in WorkSource ws); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index f693315c6cff..af2f2461ac94 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -2754,6 +2754,26 @@ public class WifiManager { } } + /** + * Set if scanning is always available. + * + * If set to {@code true}, apps can issue {@link #startScan} and fetch scan results + * even when Wi-Fi is turned off. + * + * @param isAvailable true to enable, false to disable. + * @hide + * @see #isScanAlwaysAvailable() + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) + public void setScanAlwaysAvailable(boolean isAvailable) { + try { + mService.setScanAlwaysAvailable(isAvailable); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Check if scanning is always available. * diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 853212aafcdf..234d929fc05a 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -2401,4 +2401,15 @@ public class WifiManagerTest { assertFalse(mWifiManager.isAutoWakeupEnabled()); verify(mWifiService).isAutoWakeupEnabled(); } + + + @Test + public void testScanAvailable() throws Exception { + mWifiManager.setScanAlwaysAvailable(true); + verify(mWifiService).setScanAlwaysAvailable(true); + + when(mWifiService.isScanAlwaysAvailable()).thenReturn(false); + assertFalse(mWifiManager.isScanAlwaysAvailable()); + verify(mWifiService).isScanAlwaysAvailable(); + } } -- cgit v1.2.3 From 6d4cb9cdc78cf920ec91ecac41a2b8f127706eb4 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Fri, 7 Feb 2020 06:57:14 -0800 Subject: WifiOemMigrationHook: Migrate Settings global values Changes: a) Add a method to migrate Settings values from platform. b) Marked all of those settings back to @hide. c) Also, deprecated couple of public Settings keys which are no longer used in the wifi stack. Bug: 148514485 Test: Compiles Test: TBD: Add unit tests for this class. Change-Id: I3566cdb53fc997fbb2cc5bceadd865ff8b01539b --- .../android/net/wifi/WifiOemMigrationHook.java | 266 ++++++++++++++++++++- 1 file changed, 264 insertions(+), 2 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiOemMigrationHook.java b/wifi/java/android/net/wifi/WifiOemMigrationHook.java index 22d778637101..44dbb98a8ab8 100755 --- a/wifi/java/android/net/wifi/WifiOemMigrationHook.java +++ b/wifi/java/android/net/wifi/WifiOemMigrationHook.java @@ -21,8 +21,10 @@ import static com.android.internal.util.Preconditions.checkNotNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; +import android.content.Context; import android.os.Parcel; import android.os.Parcelable; +import android.provider.Settings; import java.util.List; @@ -33,6 +35,9 @@ import java.util.List; */ @SystemApi public final class WifiOemMigrationHook { + + private WifiOemMigrationHook() { } + /** * Container for all the wifi config data to migrate. */ @@ -152,8 +157,6 @@ public final class WifiOemMigrationHook { } } - private WifiOemMigrationHook() { } - /** * Load data from OEM's config store. *

    @@ -178,4 +181,263 @@ public final class WifiOemMigrationHook { // Note: OEM's should add code to parse data from their config store format here! return null; } + + /** + * Container for all the wifi settings data to migrate. + */ + public static final class SettingsMigrationData implements Parcelable { + private final boolean mScanAlwaysAvailable; + private final boolean mP2pFactoryResetPending; + private final String mP2pDeviceName; + private final boolean mSoftApTimeoutEnabled; + private final boolean mWakeupEnabled; + private final boolean mScanThrottleEnabled; + private final boolean mVerboseLoggingEnabled; + + private SettingsMigrationData(boolean scanAlwaysAvailable, boolean p2pFactoryResetPending, + @Nullable String p2pDeviceName, boolean softApTimeoutEnabled, boolean wakeupEnabled, + boolean scanThrottleEnabled, boolean verboseLoggingEnabled) { + mScanAlwaysAvailable = scanAlwaysAvailable; + mP2pFactoryResetPending = p2pFactoryResetPending; + mP2pDeviceName = p2pDeviceName; + mSoftApTimeoutEnabled = softApTimeoutEnabled; + mWakeupEnabled = wakeupEnabled; + mScanThrottleEnabled = scanThrottleEnabled; + mVerboseLoggingEnabled = verboseLoggingEnabled; + } + + public static final @NonNull Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @Override + public SettingsMigrationData createFromParcel(Parcel in) { + boolean scanAlwaysAvailable = in.readBoolean(); + boolean p2pFactoryResetPending = in.readBoolean(); + String p2pDeviceName = in.readString(); + boolean softApTimeoutEnabled = in.readBoolean(); + boolean wakeupEnabled = in.readBoolean(); + boolean scanThrottleEnabled = in.readBoolean(); + boolean verboseLoggingEnabled = in.readBoolean(); + return new SettingsMigrationData( + scanAlwaysAvailable, p2pFactoryResetPending, + p2pDeviceName, softApTimeoutEnabled, wakeupEnabled, + scanThrottleEnabled, verboseLoggingEnabled); + } + + @Override + public SettingsMigrationData[] newArray(int size) { + return new SettingsMigrationData[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeBoolean(mScanAlwaysAvailable); + dest.writeBoolean(mP2pFactoryResetPending); + dest.writeString(mP2pDeviceName); + dest.writeBoolean(mSoftApTimeoutEnabled); + dest.writeBoolean(mWakeupEnabled); + dest.writeBoolean(mScanThrottleEnabled); + dest.writeBoolean(mVerboseLoggingEnabled); + } + + /** + * @return True if scans are allowed even when wifi is toggled off, false otherwise. + */ + public boolean isScanAlwaysAvailable() { + return mScanAlwaysAvailable; + } + + /** + * @return indicate whether factory reset request is pending. + */ + public boolean isP2pFactoryResetPending() { + return mP2pFactoryResetPending; + } + + /** + * @return the Wi-Fi peer-to-peer device name + */ + public @Nullable String getP2pDeviceName() { + return mP2pDeviceName; + } + + /** + * @return Whether soft AP will shut down after a timeout period when no devices are + * connected. + */ + public boolean isSoftApTimeoutEnabled() { + return mSoftApTimeoutEnabled; + } + + /** + * @return whether Wi-Fi Wakeup feature is enabled. + */ + public boolean isWakeUpEnabled() { + return mWakeupEnabled; + } + + /** + * @return Whether wifi scan throttle is enabled or not. + */ + public boolean isScanThrottleEnabled() { + return mScanThrottleEnabled; + } + + /** + * @return Whether to enable verbose logging in Wi-Fi. + */ + public boolean isVerboseLoggingEnabled() { + return mVerboseLoggingEnabled; + } + + /** + * Builder to create instance of {@link SettingsMigrationData}. + */ + public static final class Builder { + private boolean mScanAlwaysAvailable; + private boolean mP2pFactoryResetPending; + private String mP2pDeviceName; + private boolean mSoftApTimeoutEnabled; + private boolean mWakeupEnabled; + private boolean mScanThrottleEnabled; + private boolean mVerboseLoggingEnabled; + + public Builder() { + } + + /** + * Setting to allow scans even when wifi is toggled off. + * + * @param available true if available, false otherwise. + * @return Instance of {@link Builder} to enable chaining of the builder method. + */ + public @NonNull Builder setScanAlwaysAvailable(boolean available) { + mScanAlwaysAvailable = available; + return this; + } + + /** + * Indicate whether factory reset request is pending. + * + * @param pending true if pending, false otherwise. + * @return Instance of {@link Builder} to enable chaining of the builder method. + */ + public @NonNull Builder setP2pFactoryResetPending(boolean pending) { + mP2pFactoryResetPending = pending; + return this; + } + + /** + * The Wi-Fi peer-to-peer device name + * + * @param name Name if set, null otherwise. + * @return Instance of {@link Builder} to enable chaining of the builder method. + */ + public @NonNull Builder setP2pDeviceName(@Nullable String name) { + mP2pDeviceName = name; + return this; + } + + /** + * Whether soft AP will shut down after a timeout period when no devices are connected. + * + * @param enabled true if enabled, false otherwise. + * @return Instance of {@link Builder} to enable chaining of the builder method. + */ + public @NonNull Builder setSoftApTimeoutEnabled(boolean enabled) { + mSoftApTimeoutEnabled = enabled; + return this; + } + + /** + * Value to specify if Wi-Fi Wakeup feature is enabled. + * + * @param enabled true if enabled, false otherwise. + * @return Instance of {@link Builder} to enable chaining of the builder method. + */ + public @NonNull Builder setWakeUpEnabled(boolean enabled) { + mWakeupEnabled = enabled; + return this; + } + + /** + * Whether wifi scan throttle is enabled or not. + * + * @param enabled true if enabled, false otherwise. + * @return Instance of {@link Builder} to enable chaining of the builder method. + */ + public @NonNull Builder setScanThrottleEnabled(boolean enabled) { + mScanThrottleEnabled = enabled; + return this; + } + + /** + * Setting to enable verbose logging in Wi-Fi. + * + * @param enabled true if enabled, false otherwise. + * @return Instance of {@link Builder} to enable chaining of the builder method. + */ + public @NonNull Builder setVerboseLoggingEnabled(boolean enabled) { + mVerboseLoggingEnabled = enabled; + return this; + } + + /** + * Build an instance of {@link SettingsMigrationData}. + * + * @return Instance of {@link SettingsMigrationData}. + */ + public @NonNull SettingsMigrationData build() { + return new SettingsMigrationData(mScanAlwaysAvailable, mP2pFactoryResetPending, + mP2pDeviceName, mSoftApTimeoutEnabled, mWakeupEnabled, mScanThrottleEnabled, + mVerboseLoggingEnabled); + } + } + } + + /** + * Load data from Settings.Global values. + * + *

    + * Note: + *

  • This is method is invoked once on the first bootup. OEM can safely delete these settings + * once the migration is complete. The first & only relevant invocation of + * {@link #loadFromSettings(Context)} ()} occurs when a previously released + * device upgrades to the wifi mainline module from an OEM implementation of the wifi stack. + *
  • + * + * @param context Context to use for loading the settings provider. + * @return Instance of {@link SettingsMigrationData} for migrating data. + */ + @NonNull + public static SettingsMigrationData loadFromSettings(@NonNull Context context) { + return new SettingsMigrationData.Builder() + .setScanAlwaysAvailable( + Settings.Global.getInt(context.getContentResolver(), + Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 1) + .setP2pFactoryResetPending( + Settings.Global.getInt(context.getContentResolver(), + Settings.Global.WIFI_P2P_PENDING_FACTORY_RESET, 0) == 1) + .setP2pDeviceName( + Settings.Global.getString(context.getContentResolver(), + Settings.Global.WIFI_P2P_DEVICE_NAME)) + .setSoftApTimeoutEnabled( + Settings.Global.getInt(context.getContentResolver(), + Settings.Global.SOFT_AP_TIMEOUT_ENABLED, 1) == 1) + .setWakeUpEnabled( + Settings.Global.getInt(context.getContentResolver(), + Settings.Global.WIFI_WAKEUP_ENABLED, 0) == 1) + .setScanThrottleEnabled( + Settings.Global.getInt(context.getContentResolver(), + Settings.Global.WIFI_SCAN_THROTTLE_ENABLED, 1) == 1) + .setVerboseLoggingEnabled( + Settings.Global.getInt(context.getContentResolver(), + Settings.Global.WIFI_VERBOSE_LOGGING_ENABLED, 1) == 1) + .build(); + } } -- cgit v1.2.3 From efc940ff3fe1559d00f44586cd6274f2789e9ad0 Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Tue, 18 Feb 2020 14:48:30 -0800 Subject: [Passpoint] Remove throws IllegalStateException form getUniqueId API Following up on feedback from API council: Remove throws IllegalStateException form PasspointConfiguration#getUniqueId API. No need to explicitly declare runtime exceptions. Bug: 149758065 Test: PasspointConfigurationTest Change-Id: I9022a7c87ef9839c6b60fdfd8394915779fa708b --- .../net/wifi/hotspot2/PasspointConfiguration.java | 9 ++++++--- .../wifi/hotspot2/PasspointConfigurationTest.java | 20 ++++---------------- 2 files changed, 10 insertions(+), 19 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java index 7d9bdba81a76..4507cc2707d4 100644 --- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java +++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java @@ -900,12 +900,15 @@ public final class PasspointConfiguration implements Parcelable { } /** - * Get a unique identifier for a PasspointConfiguration object. + * Get a unique identifier for a PasspointConfiguration object. The identifier depends on the + * configuration that identify the service provider under the HomeSp subtree, and on the + * credential configuration under the Credential subtree. + * The method throws an {@link IllegalStateException} if the configuration under HomeSp subtree + * or the configuration under Credential subtree are not initialized. * * @return A unique identifier - * @throws IllegalStateException if Credential or HomeSP nodes are not initialized */ - public @NonNull String getUniqueId() throws IllegalStateException { + public @NonNull String getUniqueId() { if (mCredential == null || mHomeSp == null || TextUtils.isEmpty(mHomeSp.getFqdn())) { throw new IllegalStateException("Credential or HomeSP are not initialized"); } diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java index 8f6beb19091b..638efb9f14ee 100644 --- a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java @@ -426,17 +426,11 @@ public class PasspointConfigurationTest { * * @throws Exception */ - @Test + @Test (expected = IllegalStateException.class) public void validateUniqueIdExceptionWithEmptyHomeSp() throws Exception { PasspointConfiguration config = PasspointTestUtils.createConfig(); config.setHomeSp(null); - boolean exceptionCaught = false; - try { - String uniqueId = config.getUniqueId(); - } catch (IllegalStateException e) { - exceptionCaught = true; - } - assertTrue(exceptionCaught); + String uniqueId = config.getUniqueId(); } /** @@ -445,16 +439,10 @@ public class PasspointConfigurationTest { * * @throws Exception */ - @Test + @Test (expected = IllegalStateException.class) public void validateUniqueIdExceptionWithEmptyCredential() throws Exception { PasspointConfiguration config = PasspointTestUtils.createConfig(); config.setCredential(null); - boolean exceptionCaught = false; - try { - String uniqueId = config.getUniqueId(); - } catch (IllegalStateException e) { - exceptionCaught = true; - } - assertTrue(exceptionCaught); + String uniqueId = config.getUniqueId(); } } -- cgit v1.2.3 From 7751734bb78d9060f61c3f782e296b7f373d820e Mon Sep 17 00:00:00 2001 From: David Su Date: Tue, 18 Feb 2020 18:10:07 -0800 Subject: CurrentTimeMillisLong: Move to framework-annotations Move CurrentTimeMillisLong to framework-annotations since it is used by other modules besides MediaProvider (e.g. Wifi). Bug: 149605228 Test: compiles Change-Id: If5a3c77391a63eb11e682b7654864c2bef8b87d4 --- wifi/Android.bp | 1 - 1 file changed, 1 deletion(-) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 9f26203a3842..5c9fb4e86bc7 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -86,7 +86,6 @@ java_library { // TODO(b/146757305): should be unnecessary once // sdk_version="module_lib_current" "android_system_stubs_current", - "framework_mediaprovider_annotation", // for android.annotation.CurrentTimeMillisLong ], srcs: [ ":framework-wifi-updatable-sources", -- cgit v1.2.3 From 740e68c2aec1df8d8057dc2a109b739311dcb274 Mon Sep 17 00:00:00 2001 From: David Su Date: Wed, 19 Feb 2020 13:37:39 -0800 Subject: Verbose Logging: Add maxTargetSdk Add maxTargetSdk = Q for @UnsupportedAppUsage Wifi Verbose Logging APIs. Callers on Android R+ should use formal @SystemApi's. Bug: 148967842 Test: compiles Change-Id: I27798f2ae97f07c3452e13ff8f82fdc90b36298d --- wifi/java/android/net/wifi/WifiManager.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index f693315c6cff..2dd12dbff6fa 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -46,6 +46,7 @@ import android.net.wifi.hotspot2.OsuProvider; import android.net.wifi.hotspot2.PasspointConfiguration; 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; @@ -4900,7 +4901,10 @@ public class WifiManager { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage( + maxTargetSdk = Build.VERSION_CODES.Q, + publicAlternatives = "Use {@code #setVerboseLoggingEnabled(boolean)} instead." + ) @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void enableVerboseLogging (int verbose) { try { @@ -4928,7 +4932,10 @@ public class WifiManager { /** @hide */ // TODO(b/145484145): remove once SUW stops calling this via reflection - @UnsupportedAppUsage + @UnsupportedAppUsage( + maxTargetSdk = Build.VERSION_CODES.Q, + publicAlternatives = "Use {@code #isVerboseLoggingEnabled()} instead." + ) public int getVerboseLoggingLevel() { try { return mService.getVerboseLoggingLevel(); -- cgit v1.2.3 From fc4ff5dc46ba0b7b1c0f94cd1da44f029e3a52bd Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Wed, 19 Feb 2020 20:02:23 -0800 Subject: WifiOemMigrationHook: Default to false for verbose logging flag Bug: 149879075 Test: Compiles Change-Id: Ib7154a6e5fe3b74c4df3b326c82de6304f779d34 --- wifi/java/android/net/wifi/WifiOemMigrationHook.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiOemMigrationHook.java b/wifi/java/android/net/wifi/WifiOemMigrationHook.java index 44dbb98a8ab8..5301dd013363 100755 --- a/wifi/java/android/net/wifi/WifiOemMigrationHook.java +++ b/wifi/java/android/net/wifi/WifiOemMigrationHook.java @@ -437,7 +437,7 @@ public final class WifiOemMigrationHook { Settings.Global.WIFI_SCAN_THROTTLE_ENABLED, 1) == 1) .setVerboseLoggingEnabled( Settings.Global.getInt(context.getContentResolver(), - Settings.Global.WIFI_VERBOSE_LOGGING_ENABLED, 1) == 1) + Settings.Global.WIFI_VERBOSE_LOGGING_ENABLED, 0) == 1) .build(); } } -- cgit v1.2.3 From d41a299561ee6d057aff830b30056f1d549174dc Mon Sep 17 00:00:00 2001 From: lesl Date: Thu, 20 Feb 2020 17:30:58 +0800 Subject: wifi: Use long to replace int for softap feature set Bug: 149871866 Test: atest frameworks/base/wifi/tests/ Change-Id: I58a408150325054af809bdb18c77748ead3a0b17 --- wifi/java/android/net/wifi/SoftApCapability.java | 20 ++++++++++---------- .../src/android/net/wifi/SoftApCapabilityTest.java | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/SoftApCapability.java b/wifi/java/android/net/wifi/SoftApCapability.java index 2bbe7d2aa4ec..a831984f3968 100644 --- a/wifi/java/android/net/wifi/SoftApCapability.java +++ b/wifi/java/android/net/wifi/SoftApCapability.java @@ -16,7 +16,7 @@ package android.net.wifi; -import android.annotation.IntDef; +import android.annotation.LongDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; @@ -47,7 +47,7 @@ public final class SoftApCapability implements Parcelable { * {@link SoftApInfo#getFrequency} and {@link SoftApInfo#getBandwidth} to get * driver channel selection result. */ - public static final int SOFTAP_FEATURE_ACS_OFFLOAD = 1 << 0; + public static final long SOFTAP_FEATURE_ACS_OFFLOAD = 1 << 0; /** * Support for client force disconnect. @@ -59,7 +59,7 @@ public final class SoftApCapability implements Parcelable { * Check feature support before invoking * {@link SoftApConfiguration.Builder#setMaxNumberOfClients(int)} */ - public static final int SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT = 1 << 1; + public static final long SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT = 1 << 1; /** @@ -67,18 +67,18 @@ public final class SoftApCapability implements Parcelable { * * flag when {@link config_wifi_softap_sae_supported)} is true. */ - public static final int SOFTAP_FEATURE_WPA3_SAE = 1 << 2; + public static final long SOFTAP_FEATURE_WPA3_SAE = 1 << 2; /** @hide */ @Retention(RetentionPolicy.SOURCE) - @IntDef(flag = true, prefix = { "SOFTAP_FEATURE_" }, value = { + @LongDef(flag = true, prefix = { "SOFTAP_FEATURE_" }, value = { SOFTAP_FEATURE_ACS_OFFLOAD, SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT, SOFTAP_FEATURE_WPA3_SAE, }) public @interface HotspotFeatures {} - private @HotspotFeatures int mSupportedFeatures = 0; + private @HotspotFeatures long mSupportedFeatures = 0; private int mMaximumSupportedClientNumber; @@ -104,7 +104,7 @@ public final class SoftApCapability implements Parcelable { * * @param feature one of feature from {@link HotspotFeatures} */ - public boolean isFeatureSupported(@HotspotFeatures int feature) { + public boolean isFeatureSupported(@HotspotFeatures long feature) { return (mSupportedFeatures & feature) == feature; } @@ -125,7 +125,7 @@ public final class SoftApCapability implements Parcelable { * @param features One or combination of the feature from {@link @HotspotFeatures}. * @hide */ - public SoftApCapability(@HotspotFeatures int features) { + public SoftApCapability(@HotspotFeatures long features) { mSupportedFeatures = features; } @@ -138,7 +138,7 @@ public final class SoftApCapability implements Parcelable { @Override /** Implement the Parcelable interface */ public void writeToParcel(@NonNull Parcel dest, int flags) { - dest.writeInt(mSupportedFeatures); + dest.writeLong(mSupportedFeatures); dest.writeInt(mMaximumSupportedClientNumber); } @@ -146,7 +146,7 @@ public final class SoftApCapability implements Parcelable { /** Implement the Parcelable interface */ public static final Creator CREATOR = new Creator() { public SoftApCapability createFromParcel(Parcel in) { - int supportedFeatures = in.readInt(); + long supportedFeatures = in.readLong(); SoftApCapability capability = new SoftApCapability(supportedFeatures); capability.mMaximumSupportedClientNumber = in.readInt(); return capability; diff --git a/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java b/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java index ef476ebc2667..73b501a4d8f2 100644 --- a/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java +++ b/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java @@ -35,7 +35,7 @@ public class SoftApCapabilityTest { */ @Test public void testCopyOperator() throws Exception { - int testSoftApFeature = SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT + long testSoftApFeature = SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT | SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD; SoftApCapability capability = new SoftApCapability(testSoftApFeature); capability.setMaxSupportedClients(10); @@ -51,7 +51,7 @@ public class SoftApCapabilityTest { */ @Test public void testParcelOperation() throws Exception { - int testSoftApFeature = SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT + long testSoftApFeature = SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT | SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD; SoftApCapability capability = new SoftApCapability(testSoftApFeature); capability.setMaxSupportedClients(10); -- cgit v1.2.3 From 72f9d6352e3293834fbcdc908b0576d301669d33 Mon Sep 17 00:00:00 2001 From: David Su Date: Mon, 10 Feb 2020 15:58:26 -0800 Subject: framework-wifi: Stop linking all frameworks/base/core/java AIDLs Instead only link ParceledListSlice.aidl, which is the only one used by framework-wifi. Bug: 149127842 Test: "couldn't find import for class android.content.pm.ParceledListSlice" no longer appears when building Change-Id: Ie9f67c58c3694bbf1f45ae8e1d99e6e65fbc3163 --- wifi/Android.bp | 1 + 1 file changed, 1 insertion(+) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 5c9fb4e86bc7..0c6cf1c170f5 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -89,6 +89,7 @@ java_library { ], srcs: [ ":framework-wifi-updatable-sources", + ":framework-wifi-util-lib-aidls", ], // java_api_finder must accompany `srcs` plugins: ["java_api_finder"], -- cgit v1.2.3 From ded221230455b39d853f6c48a49ea3396424ed06 Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Wed, 19 Feb 2020 20:33:22 -0800 Subject: [Passpoint] Print home or roaming in WifiConfiguration Print provider network home or roaming in the toString() method of WifiConfiguration. Bug: 149881869 Test: Verify new field is printed Change-Id: Iddcd03435eb416bd6dc73bd0e7e32f180e0265d6 --- wifi/java/android/net/wifi/WifiConfiguration.java | 1 + 1 file changed, 1 insertion(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index e1450cb794f6..1a12af341910 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -2167,6 +2167,7 @@ public class WifiConfiguration implements Parcelable { sbuf.append("ID: ").append(this.networkId).append(" SSID: ").append(this.SSID). append(" PROVIDER-NAME: ").append(this.providerFriendlyName). append(" BSSID: ").append(this.BSSID).append(" FQDN: ").append(this.FQDN) + .append(" HOME-PROVIDER-NETWORK: ").append(this.isHomeProviderNetwork) .append(" PRIO: ").append(this.priority) .append(" HIDDEN: ").append(this.hiddenSSID) .append(" PMF: ").append(this.requirePmf) -- cgit v1.2.3 From d90bc26a07fed241e8dec23cf0c676033dde9d71 Mon Sep 17 00:00:00 2001 From: Charles Chen Date: Fri, 21 Feb 2020 17:00:22 +0800 Subject: Exempt-From-Owner-Approval: Workaround for build break on WifiNl80211Manager Test: build pass Bug: 149969343 Change-Id: I11c981a6e743f1f3b1f5c7581fdc851d81904322 --- .../android/net/wifi/nl80211/WifiNl80211Manager.java | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/nl80211/WifiNl80211Manager.java b/wifi/java/android/net/wifi/nl80211/WifiNl80211Manager.java index 3215246a9c1f..7d24142ba135 100644 --- a/wifi/java/android/net/wifi/nl80211/WifiNl80211Manager.java +++ b/wifi/java/android/net/wifi/nl80211/WifiNl80211Manager.java @@ -25,7 +25,6 @@ import android.annotation.SystemService; import android.app.AlarmManager; import android.content.Context; import android.net.wifi.SoftApInfo; -import android.net.wifi.WifiAnnotations; import android.net.wifi.WifiScanner; import android.os.Binder; import android.os.Handler; @@ -245,7 +244,7 @@ public class WifiNl80211Manager { * indication that the SoftAp is not enabled. * @param bandwidth The new bandwidth of the SoftAp. */ - void onSoftApChannelSwitched(int frequencyMhz, @WifiAnnotations.Bandwidth int bandwidth); + void onSoftApChannelSwitched(int frequencyMhz, int bandwidth); } /** @@ -383,7 +382,7 @@ public class WifiNl80211Manager { toFrameworkBandwidth(bandwidth))); } - private @WifiAnnotations.Bandwidth int toFrameworkBandwidth(int bandwidth) { + private int toFrameworkBandwidth(int bandwidth) { switch(bandwidth) { case IApInterfaceEventCallback.BANDWIDTH_INVALID: return SoftApInfo.CHANNEL_WIDTH_INVALID; @@ -856,7 +855,7 @@ public class WifiNl80211Manager { /** * Return scan type for the parcelable {@link SingleScanSettings} */ - private static int getScanType(@WifiAnnotations.ScanType int scanType) { + private static int getScanType(int scanType) { switch (scanType) { case WifiScanner.SCAN_TYPE_LOW_LATENCY: return IWifiScannerImpl.SCAN_TYPE_LOW_SPAN; @@ -891,7 +890,7 @@ public class WifiNl80211Manager { * @return Returns true on success, false on failure (e.g. when called before the interface * has been set up). */ - public boolean startScan(@NonNull String ifaceName, @WifiAnnotations.ScanType int scanType, + public boolean startScan(@NonNull String ifaceName, int scanType, @Nullable Set freqs, @Nullable List hiddenNetworkSSIDs) { IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); if (scannerImpl == null) { @@ -1047,7 +1046,7 @@ public class WifiNl80211Manager { * @return frequencies vector of valid frequencies (MHz), or an empty array for error. * @throws IllegalArgumentException if band is not recognized. */ - public @NonNull int[] getChannelsMhzForBand(@WifiAnnotations.WifiBandBasic int band) { + public @NonNull int[] getChannelsMhzForBand(int band) { if (mWificond == null) { Log.e(TAG, "No valid wificond scanner interface handler"); return new int[0]; @@ -1226,7 +1225,7 @@ public class WifiNl80211Manager { */ public static class OemSecurityType { /** The protocol defined in {@link android.net.wifi.WifiAnnotations.Protocol}. */ - public final @WifiAnnotations.Protocol int protocol; + public final int protocol; /** * Supported key management types defined * in {@link android.net.wifi.WifiAnnotations.KeyMgmt}. @@ -1238,7 +1237,7 @@ public class WifiNl80211Manager { */ @NonNull public final List pairwiseCipher; /** The group cipher type defined in {@link android.net.wifi.WifiAnnotations.Cipher}. */ - public final @WifiAnnotations.Cipher int groupCipher; + public final int groupCipher; /** * Default constructor for OemSecurityType * @@ -1252,10 +1251,10 @@ public class WifiNl80211Manager { * in {@link android.net.wifi.WifiAnnotations.Cipher}. */ public OemSecurityType( - @WifiAnnotations.Protocol int protocol, + int protocol, @NonNull List keyManagement, @NonNull List pairwiseCipher, - @WifiAnnotations.Cipher int groupCipher) { + int groupCipher) { this.protocol = protocol; this.keyManagement = (keyManagement != null) ? keyManagement : new ArrayList(); -- cgit v1.2.3 From 1adb838636cc114e79d5af3b8eb276c83363d9aa Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Fri, 21 Feb 2020 07:39:35 -0800 Subject: Revert "Exempt-From-Owner-Approval: Workaround for build break on WifiNl80211Manager" This reverts commit d90bc26a07fed241e8dec23cf0c676033dde9d71. Sharding jarjar'd classes is fixed. Bug: 149969343 Test: m framework-minus-apex Change-Id: I12ae9d4870a3fad5c61c143368e0ef9025202ccd --- .../android/net/wifi/nl80211/WifiNl80211Manager.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/nl80211/WifiNl80211Manager.java b/wifi/java/android/net/wifi/nl80211/WifiNl80211Manager.java index 7d24142ba135..3215246a9c1f 100644 --- a/wifi/java/android/net/wifi/nl80211/WifiNl80211Manager.java +++ b/wifi/java/android/net/wifi/nl80211/WifiNl80211Manager.java @@ -25,6 +25,7 @@ import android.annotation.SystemService; import android.app.AlarmManager; import android.content.Context; import android.net.wifi.SoftApInfo; +import android.net.wifi.WifiAnnotations; import android.net.wifi.WifiScanner; import android.os.Binder; import android.os.Handler; @@ -244,7 +245,7 @@ public class WifiNl80211Manager { * indication that the SoftAp is not enabled. * @param bandwidth The new bandwidth of the SoftAp. */ - void onSoftApChannelSwitched(int frequencyMhz, int bandwidth); + void onSoftApChannelSwitched(int frequencyMhz, @WifiAnnotations.Bandwidth int bandwidth); } /** @@ -382,7 +383,7 @@ public class WifiNl80211Manager { toFrameworkBandwidth(bandwidth))); } - private int toFrameworkBandwidth(int bandwidth) { + private @WifiAnnotations.Bandwidth int toFrameworkBandwidth(int bandwidth) { switch(bandwidth) { case IApInterfaceEventCallback.BANDWIDTH_INVALID: return SoftApInfo.CHANNEL_WIDTH_INVALID; @@ -855,7 +856,7 @@ public class WifiNl80211Manager { /** * Return scan type for the parcelable {@link SingleScanSettings} */ - private static int getScanType(int scanType) { + private static int getScanType(@WifiAnnotations.ScanType int scanType) { switch (scanType) { case WifiScanner.SCAN_TYPE_LOW_LATENCY: return IWifiScannerImpl.SCAN_TYPE_LOW_SPAN; @@ -890,7 +891,7 @@ public class WifiNl80211Manager { * @return Returns true on success, false on failure (e.g. when called before the interface * has been set up). */ - public boolean startScan(@NonNull String ifaceName, int scanType, + public boolean startScan(@NonNull String ifaceName, @WifiAnnotations.ScanType int scanType, @Nullable Set freqs, @Nullable List hiddenNetworkSSIDs) { IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); if (scannerImpl == null) { @@ -1046,7 +1047,7 @@ public class WifiNl80211Manager { * @return frequencies vector of valid frequencies (MHz), or an empty array for error. * @throws IllegalArgumentException if band is not recognized. */ - public @NonNull int[] getChannelsMhzForBand(int band) { + public @NonNull int[] getChannelsMhzForBand(@WifiAnnotations.WifiBandBasic int band) { if (mWificond == null) { Log.e(TAG, "No valid wificond scanner interface handler"); return new int[0]; @@ -1225,7 +1226,7 @@ public class WifiNl80211Manager { */ public static class OemSecurityType { /** The protocol defined in {@link android.net.wifi.WifiAnnotations.Protocol}. */ - public final int protocol; + public final @WifiAnnotations.Protocol int protocol; /** * Supported key management types defined * in {@link android.net.wifi.WifiAnnotations.KeyMgmt}. @@ -1237,7 +1238,7 @@ public class WifiNl80211Manager { */ @NonNull public final List pairwiseCipher; /** The group cipher type defined in {@link android.net.wifi.WifiAnnotations.Cipher}. */ - public final int groupCipher; + public final @WifiAnnotations.Cipher int groupCipher; /** * Default constructor for OemSecurityType * @@ -1251,10 +1252,10 @@ public class WifiNl80211Manager { * in {@link android.net.wifi.WifiAnnotations.Cipher}. */ public OemSecurityType( - int protocol, + @WifiAnnotations.Protocol int protocol, @NonNull List keyManagement, @NonNull List pairwiseCipher, - int groupCipher) { + @WifiAnnotations.Cipher int groupCipher) { this.protocol = protocol; this.keyManagement = (keyManagement != null) ? keyManagement : new ArrayList(); -- cgit v1.2.3 From 6656c50d9248ff2809a1971c39afc2a852f4a037 Mon Sep 17 00:00:00 2001 From: Anton Hansson Date: Wed, 5 Feb 2020 09:49:35 +0000 Subject: Re-submit "Create all variants of stubs for wifi" Use sdk_version: module_current instead. This reverts commit d20f03011f95bd04bace0977d246cdc737ce5627. Bug: 147768409 Test: m Test: build/soong/soong_ui.bash --make-mode dist ANDROID_BUILDSPEC=vendor/google/build/app_build_spec.mk Exempt-From-Owner-Approval: clean cp Change-Id: I36cf007a4813027721dfb6389e10cf95085f85e4 Merged-In: I36cf007a4813027721dfb6389e10cf95085f85e4 (cherry picked from commit 21f0ed2a0aceddd4ce3dfcf792cb1ae9a144547b) --- wifi/Android.bp | 71 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 56 insertions(+), 15 deletions(-) (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index 0c6cf1c170f5..e253d6d4f6cb 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -132,27 +132,68 @@ java_library { ], } -droidstubs { - name: "framework-wifi-stubs-srcs", +stubs_defaults { + name: "framework-wifi-stubs-srcs-defaults", srcs: [ - ":framework-annotations", ":framework-wifi-updatable-sources", + ":framework-wifi-util-lib-aidls", + ], + libs: [ "framework-annotations-lib" ], + sdk_version: "module_current", +} + +droidstubs { + name: "framework-wifi-stubs-srcs-publicapi", + defaults: [ + "framework-module-stubs-defaults-publicapi", + "framework-wifi-stubs-srcs-defaults", + ], +} + +droidstubs { + name: "framework-wifi-stubs-srcs-systemapi", + defaults: [ + "framework-module-stubs-defaults-systemapi", + "framework-wifi-stubs-srcs-defaults", + ], +} + +droidstubs { + name: "framework-wifi-api-module_libs_api", + defaults: [ + "framework-module-api-defaults-module_libs_api", + "framework-wifi-stubs-srcs-defaults", + ], +} + +droidstubs { + name: "framework-wifi-stubs-srcs-module_libs_api", + defaults: [ + "framework-module-stubs-defaults-module_libs_api", + "framework-wifi-stubs-srcs-defaults", ], - // This is needed as IOnWifiActivityEnergyInfoListener.aidl in framework-wifi depends on - // WifiActivityEnergyInfo.aidl in framework-minus-apex - aidl: { - include_dirs: ["frameworks/base/core/java"], - }, - defaults: [ "framework-module-stubs-defaults-systemapi" ], - sdk_version: "core_current", - libs: ["android_system_stubs_current"], } java_library { - name: "framework-wifi-stubs", - srcs: [":framework-wifi-stubs-srcs"], - sdk_version: "core_current", - libs: ["android_system_stubs_current"], + name: "framework-wifi-stubs-publicapi", + srcs: [":framework-wifi-stubs-srcs-publicapi"], + sdk_version: "module_current", + installable: false, +} + +java_library { + name: "framework-wifi-stubs-systemapi", + srcs: [":framework-wifi-stubs-srcs-systemapi"], + sdk_version: "module_current", + libs: ["framework-annotations-lib"], + installable: false, +} + +java_library { + name: "framework-wifi-stubs-module_libs_api", + srcs: [":framework-wifi-stubs-srcs-module_libs_api"], + sdk_version: "module_current", + libs: ["framework-annotations-lib"], installable: false, } -- cgit v1.2.3 From 842950053905fad80810636501f1b8310b7ef4b4 Mon Sep 17 00:00:00 2001 From: "Nate(Qiang) Jiang" Date: Thu, 13 Feb 2020 17:44:53 -0800 Subject: Override hashcode, equals function for PnoNetwork Bug: 148535554 Test: atest android.net.wifi Change-Id: I9f6ea75966b97ac67234b73a8198492a8edfacb2 --- wifi/java/android/net/wifi/WifiScanner.java | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index b4eb30b8cfe6..5e4891950466 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -36,6 +36,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.os.RemoteException; import android.os.WorkSource; +import android.text.TextUtils; import android.util.Log; import android.util.SparseArray; @@ -744,6 +745,25 @@ public class WifiScanner { public PnoNetwork(String ssid) { this.ssid = ssid; } + + @Override + public int hashCode() { + return Objects.hash(ssid, flags, authBitField); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof PnoNetwork)) { + return false; + } + PnoNetwork lhs = (PnoNetwork) obj; + return TextUtils.equals(this.ssid, lhs.ssid) + && this.flags == lhs.flags + && this.authBitField == lhs.authBitField; + } } /** Connected vs Disconnected PNO flag {@hide} */ -- cgit v1.2.3 From 692a70d5706666a49ee0a566560d9eb03d3b89d2 Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 20 Feb 2020 16:25:13 -0800 Subject: Wifi: Clean up APIs - Made WifiInfo.Builder public - Made ScanResult::new public - Added public getters for WifiNetworkSuggestion Bug: 149912516 Test: compiles Test: Will add CTS for new WifiNetworkSuggestion APIs Change-Id: I868477f0d149cb4e96f9313dbaa1ef66d4723309 --- wifi/java/android/net/wifi/ScanResult.java | 16 +--- wifi/java/android/net/wifi/WifiInfo.java | 17 +--- .../android/net/wifi/WifiNetworkSuggestion.java | 101 ++++++++++++++++++++- 3 files changed, 99 insertions(+), 35 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java index 51927af17888..9256c57ab4b9 100644 --- a/wifi/java/android/net/wifi/ScanResult.java +++ b/wifi/java/android/net/wifi/ScanResult.java @@ -24,8 +24,6 @@ import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; -import com.android.internal.annotations.VisibleForTesting; - import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.nio.ByteBuffer; @@ -861,19 +859,7 @@ public class ScanResult implements Parcelable { } } - /** - * Construct an empty scan result. - * - * Test code has a need to construct a ScanResult in a specific state. - * (Note that mocking using Mockito does not work if the object needs to be parceled and - * unparceled.) - * Export a @SystemApi default constructor to allow tests to construct an empty ScanResult - * object. The test can then directly set the fields it cares about. - * - * @hide - */ - @SystemApi - @VisibleForTesting + /** Construct an empty scan result. */ public ScanResult() { } diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java index 0c306b4fb8cc..142854a9e41b 100644 --- a/wifi/java/android/net/wifi/WifiInfo.java +++ b/wifi/java/android/net/wifi/WifiInfo.java @@ -28,8 +28,6 @@ import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; -import com.android.internal.annotations.VisibleForTesting; - import java.net.Inet4Address; import java.net.InetAddress; import java.net.UnknownHostException; @@ -380,20 +378,7 @@ public class WifiInfo implements Parcelable { } } - /** - * WifiInfo exports an immutable public API. - * However, test code has a need to construct a WifiInfo in a specific state. - * (Note that mocking using Mockito does not work if the object needs to be parceled and - * unparceled.) - * Export a @SystemApi Builder to allow tests to construct a WifiInfo object - * in the desired state, without sacrificing WifiInfo's immutability. - * - * @hide - */ - // This builder was not made public to reduce confusion for external developers as there are - // no legitimate uses for this builder except for testing. - @SystemApi - @VisibleForTesting + /** Builder for WifiInfo */ public static final class Builder { private final WifiInfo mWifiInfo = new WifiInfo(); diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java index a854a4ba3ae5..6dbb0bd757d8 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java +++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java @@ -753,7 +753,7 @@ public final class WifiNetworkSuggestion implements Parcelable { boolean isUserInteractionRequired, boolean isUserAllowedToManuallyConnect, boolean isInitialAutoJoinEnabled, - boolean isNetworkUntrusted) { + boolean isNetworkUntrusted) { checkNotNull(networkConfiguration); this.wifiConfiguration = networkConfiguration; this.passpointConfiguration = passpointConfiguration; @@ -857,14 +857,107 @@ public final class WifiNetworkSuggestion implements Parcelable { return wifiConfiguration; } + /** + * Get the BSSID, or null if unset. + * @see Builder#setBssid(MacAddress) + */ + @Nullable + public MacAddress getBssid() { + if (wifiConfiguration.BSSID == null) { + return null; + } + return MacAddress.fromString(wifiConfiguration.BSSID); + } + + /** @see Builder#setCredentialSharedWithUser(boolean) */ + public boolean isCredentialSharedWithUser() { + return isUserAllowedToManuallyConnect; + } + + /** @see Builder#setIsAppInteractionRequired(boolean) */ + public boolean isAppInteractionRequired() { + return isAppInteractionRequired; + } + + /** @see Builder#setIsEnhancedOpen(boolean) */ + public boolean isEnhancedOpen() { + return wifiConfiguration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.OWE); + } + + /** @see Builder#setIsHiddenSsid(boolean) */ + public boolean isHiddenSsid() { + return wifiConfiguration.hiddenSSID; + } + + /** @see Builder#setIsInitialAutojoinEnabled(boolean) */ + public boolean isInitialAutojoinEnabled() { + return isInitialAutoJoinEnabled; + } + + /** @see Builder#setIsMetered(boolean) */ + public boolean isMetered() { + return wifiConfiguration.meteredOverride == WifiConfiguration.METERED_OVERRIDE_METERED; + } + + /** @see Builder#setIsUserInteractionRequired(boolean) */ + public boolean isUserInteractionRequired() { + return isUserInteractionRequired; + } + /** * Get the {@link PasspointConfiguration} associated with this Suggestion, or null if this * Suggestion is not for a Passpoint network. - * @hide */ - @SystemApi @Nullable - public PasspointConfiguration getPasspointConfiguration() { + public PasspointConfiguration getPasspointConfig() { return passpointConfiguration; } + + /** @see Builder#setPriority(int) */ + @IntRange(from = 0) + public int getPriority() { + return wifiConfiguration.priority; + } + + /** + * Return the SSID of the network, or null if this is a Passpoint network. + * @see Builder#setSsid(String) + */ + @Nullable + public String getSsid() { + if (wifiConfiguration.SSID == null) { + return null; + } + return WifiInfo.sanitizeSsid(wifiConfiguration.SSID); + } + + /** @see Builder#setUntrusted(boolean) */ + public boolean isUntrusted() { + return isNetworkUntrusted; + } + + /** + * Get the WifiEnterpriseConfig, or null if unset. + * @see Builder#setWapiEnterpriseConfig(WifiEnterpriseConfig) + * @see Builder#setWpa2EnterpriseConfig(WifiEnterpriseConfig) + * @see Builder#setWpa3EnterpriseConfig(WifiEnterpriseConfig) + */ + @Nullable + public WifiEnterpriseConfig getEnterpriseConfig() { + return wifiConfiguration.enterpriseConfig; + } + + /** + * Get the passphrase, or null if unset. + * @see Builder#setWapiPassphrase(String) + * @see Builder#setWpa2Passphrase(String) + * @see Builder#setWpa3Passphrase(String) + */ + @Nullable + public String getPassphrase() { + if (wifiConfiguration.preSharedKey == null) { + return null; + } + return WifiInfo.removeDoubleQuotes(wifiConfiguration.preSharedKey); + } } -- cgit v1.2.3 From b17fc5d2e581a6d7178bc5b3ba21f0f138c4ccc5 Mon Sep 17 00:00:00 2001 From: lesl Date: Thu, 20 Feb 2020 19:32:17 +0800 Subject: wifi: Revise java doc to add more explanation 1. restoreSoftApBackupData - document return value and behavior if input is invalid 2. onCapabilityChanged - document behavior on register Bug: 149871866 Test: make docs frameworks/base/wifi/ Mergrd-In: I02085e614a35b0bf07dbc47cffe7255555a0deb8 Change-Id: I02085e614a35b0bf07dbc47cffe7255555a0deb8 (cherry picked from commit dba305d37d9d0214c231ae8a168f17268f4966c2) --- wifi/java/android/net/wifi/WifiManager.java | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 7d4b63285eea..b1a4cac5864a 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -3769,11 +3769,19 @@ public class WifiManager { } /** - * Registers a callback for Soft AP. See {@link SoftApCallback}. Caller will receive the current - * soft AP state and number of connected devices immediately after a successful call to this API - * via callback. Note that receiving an immediate WIFI_AP_STATE_FAILED value for soft AP state - * indicates that the latest attempt to start soft AP has failed. Caller can unregister a - * previously registered callback using {@link #unregisterSoftApCallback} + * Registers a callback for Soft AP. See {@link SoftApCallback}. Caller will receive the + * following callbacks on registration: + *
      + *
    • {@link SoftApCallback#onStateChanged(int, int)}
    • + *
    • {@link SoftApCallback#onConnectedClientsChanged(List)}
    • + *
    • {@link SoftApCallback#onInfoChanged(SoftApInfo)}
    • + *
    • {@link SoftApCallback#onCapabilityChanged(SoftApCapability)}
    • + *
    + * These will be dispatched on registration to provide the caller with the current state + * (and are not an indication of any current change). Note that receiving an immediate + * WIFI_AP_STATE_FAILED value for soft AP state indicates that the latest attempt to start + * soft AP has failed. Caller can unregister a previously registered callback using + * {@link #unregisterSoftApCallback} *

    * Applications should have the * {@link android.Manifest.permission#NETWORK_SETTINGS NETWORK_SETTINGS} permission. Callers @@ -5075,7 +5083,7 @@ public class WifiManager { } /** - * Returns soft ap config from the backed up data. + * Returns soft ap config from the backed up data or null if data is invalid. * @param data byte stream in the same format produced by {@link #retrieveSoftApBackupData()} * * @hide -- cgit v1.2.3 From 7a0c18c8846344ce8b591da738ba9590ad32df2c Mon Sep 17 00:00:00 2001 From: lesl Date: Fri, 21 Feb 2020 16:28:00 +0800 Subject: wifi: correct API name The API:isFeatureSupported accept one or combination of required features, update the jave doc & rename to areFeaturesSupporte Bug: 149871866 Test: make docs frameworks/base/wifi/ Test: atest frameworks/base/wifi/tests/ Merged-In: I3bcbcfd04dced36b63436b5a96835fb0d8f35f3b Change-Id: I3bcbcfd04dced36b63436b5a96835fb0d8f35f3b (cherry picked from commit dd8f942e815381c2636b5981d91b3c59c7f27745) --- wifi/java/android/net/wifi/SoftApCapability.java | 10 +++++----- wifi/java/android/net/wifi/SoftApConfiguration.java | 7 ++++--- 2 files changed, 9 insertions(+), 8 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/SoftApCapability.java b/wifi/java/android/net/wifi/SoftApCapability.java index a831984f3968..18b26db1b020 100644 --- a/wifi/java/android/net/wifi/SoftApCapability.java +++ b/wifi/java/android/net/wifi/SoftApCapability.java @@ -100,12 +100,12 @@ public final class SoftApCapability implements Parcelable { } /** - * Returns true when feature supported, otherwise false. + * Returns true when all of the queried features are supported, otherwise false. * - * @param feature one of feature from {@link HotspotFeatures} + * @param features One or combination of the features from {@link @HotspotFeatures} */ - public boolean isFeatureSupported(@HotspotFeatures long feature) { - return (mSupportedFeatures & feature) == feature; + public boolean areFeaturesSupported(@HotspotFeatures long features) { + return (mSupportedFeatures & features) == features; } /** @@ -122,7 +122,7 @@ public final class SoftApCapability implements Parcelable { * Constructor with combination of the feature. * Zero to no supported feature. * - * @param features One or combination of the feature from {@link @HotspotFeatures}. + * @param features One or combination of the features from {@link @HotspotFeatures}. * @hide */ public SoftApCapability(@HotspotFeatures long features) { diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java index ae5bf7d5ae84..2b4762320f52 100644 --- a/wifi/java/android/net/wifi/SoftApConfiguration.java +++ b/wifi/java/android/net/wifi/SoftApConfiguration.java @@ -762,7 +762,8 @@ public final class SoftApConfiguration implements Parcelable { * {@link #setBand(@BandType int)}. * * The channel auto selection will offload to driver when - * {@link SoftApCapability#isFeatureSupported(SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD)} + * {@link SoftApCapability#areFeaturesSupported( + * SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD)} * return true. Driver will auto select best channel which based on environment * interference to get best performance. Check {@link SoftApCapability} to get more detail. * @@ -807,7 +808,7 @@ public final class SoftApConfiguration implements Parcelable { * *

    * Use {@link WifiManager.SoftApCallback#onCapabilityChanged(SoftApCapability)} and - * {@link SoftApCapability#isFeatureSupported(int)} + * {@link SoftApCapability#areFeaturesSupported(int)} * with {@link SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT} to determine whether * or not this feature is supported. * @@ -882,7 +883,7 @@ public final class SoftApConfiguration implements Parcelable { *

    * This method requires hardware support. Hardware support can be determined using * {@link WifiManager.SoftApCallback#onCapabilityChanged(SoftApCapability)} and - * {@link SoftApCapability#isFeatureSupported(int)} + * {@link SoftApCapability#areFeaturesSupported(int)} * with {@link SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT} * *

    -- cgit v1.2.3 From dea9593d23bc19f4f0fa7423545b650bd69f73d2 Mon Sep 17 00:00:00 2001 From: Mingguang Xu Date: Thu, 20 Feb 2020 23:52:20 -0800 Subject: Extension API: Replace NetworkScore object with integer in API surface NetworkScore object is removed as part of punting the network selection refoundation feature out of Android 11. Test: atest android.net.wifi Bug: 135573686, 122133502, 136312816, 135572156 Change-Id: Ib4226a4d66ab29fc4b31226d5ece8ad14a14d1e1 Signed-off-by: Mingguang Xu (cherry picked from commit 705d110d853358ed62588973cbc106f4ed009b66) --- wifi/java/android/net/wifi/IScoreChangeCallback.aidl | 6 ++---- wifi/java/android/net/wifi/WifiManager.java | 10 ++++------ 2 files changed, 6 insertions(+), 10 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IScoreChangeCallback.aidl b/wifi/java/android/net/wifi/IScoreChangeCallback.aidl index 462a97844d76..d691f41b2858 100644 --- a/wifi/java/android/net/wifi/IScoreChangeCallback.aidl +++ b/wifi/java/android/net/wifi/IScoreChangeCallback.aidl @@ -16,16 +16,14 @@ package android.net.wifi; -import android.net.NetworkScore; - /** - * Interface for Wi-Fi network score callback. + * Interface for Wi-Fi score callback. * * @hide */ oneway interface IScoreChangeCallback { - void onScoreChange(int sessionId, in NetworkScore score); + void onScoreChange(int sessionId, int score); void onTriggerUpdateOfWifiUsabilityStats(int sessionId); } diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 7d4b63285eea..85a2a6931e91 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -39,7 +39,6 @@ import android.net.ConnectivityManager; import android.net.DhcpInfo; import android.net.MacAddress; import android.net.Network; -import android.net.NetworkScore; import android.net.NetworkStack; import android.net.wifi.hotspot2.IProvisioningCallback; import android.net.wifi.hotspot2.OsuProvider; @@ -5986,11 +5985,10 @@ public class WifiManager { * * @param sessionId The ID to indicate current Wi-Fi network connection obtained from * {@link WifiConnectedNetworkScorer#start(int)}. - * @param score The {@link android.net.NetworkScore} object representing the - * characteristics of current Wi-Fi network. Populated by connected network - * scorer in applications. + * @param score The score representing link quality of current Wi-Fi network connection. + * Populated by connected network scorer in applications.. */ - void onScoreChange(int sessionId, @NonNull NetworkScore score); + void onScoreChange(int sessionId, int score); /** * Called by applications to trigger an update of {@link WifiUsabilityStatsEntry}. @@ -6016,7 +6014,7 @@ public class WifiManager { } @Override - public void onScoreChange(int sessionId, @NonNull NetworkScore score) { + public void onScoreChange(int sessionId, int score) { try { mScoreChangeCallback.onScoreChange(sessionId, score); } catch (RemoteException e) { -- cgit v1.2.3 From 807b34a2c6cc739aba3f0bd41d7849713f308c33 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Mon, 24 Feb 2020 09:12:52 -0800 Subject: WifiOemMigrationHook: Rename class to address API council feedback Bug: 149418926 Test: Compiles Change-Id: I59a6e893599b1ccaec51a39c9594f157622668a0 --- wifi/Android.bp | 2 +- wifi/java/android/net/wifi/WifiMigration.java | 443 +++++++++++++++++++++ .../android/net/wifi/WifiOemMigrationHook.java | 443 --------------------- 3 files changed, 444 insertions(+), 444 deletions(-) create mode 100755 wifi/java/android/net/wifi/WifiMigration.java delete mode 100755 wifi/java/android/net/wifi/WifiOemMigrationHook.java (limited to 'wifi') diff --git a/wifi/Android.bp b/wifi/Android.bp index e253d6d4f6cb..91174d3c3be2 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -47,7 +47,7 @@ filegroup { // framework-wifi.jar. This is not a good idea, should move WifiNetworkScoreCache // to a separate package. "java/android/net/wifi/WifiNetworkScoreCache.java", - "java/android/net/wifi/WifiOemMigrationHook.java", + "java/android/net/wifi/WifiMigration.java", "java/android/net/wifi/nl80211/*.java", ":libwificond_ipc_aidl", ], diff --git a/wifi/java/android/net/wifi/WifiMigration.java b/wifi/java/android/net/wifi/WifiMigration.java new file mode 100755 index 000000000000..695f00f643ad --- /dev/null +++ b/wifi/java/android/net/wifi/WifiMigration.java @@ -0,0 +1,443 @@ +/* + * Copyright (C) 2020 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 com.android.internal.util.Preconditions.checkNotNull; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.content.Context; +import android.os.Parcel; +import android.os.Parcelable; +import android.provider.Settings; + +import java.util.List; + +/** + * Class used to provide one time hooks for existing OEM devices to migrate their config store + * data and other settings to the wifi mainline module. + * @hide + */ +@SystemApi +public final class WifiMigration { + + private WifiMigration() { } + + /** + * Container for all the wifi config data to migrate. + */ + public static final class ConfigStoreMigrationData implements Parcelable { + /** + * Builder to create instance of {@link ConfigStoreMigrationData}. + */ + public static final class Builder { + private List mUserSavedNetworkConfigurations; + private SoftApConfiguration mUserSoftApConfiguration; + + public Builder() { + mUserSavedNetworkConfigurations = null; + mUserSoftApConfiguration = null; + } + + /** + * Sets the list of all user's saved network configurations parsed from OEM config + * store files. + * + * @param userSavedNetworkConfigurations List of {@link WifiConfiguration} representing + * the list of user's saved networks + * @return Instance of {@link Builder} to enable chaining of the builder method. + */ + public @NonNull Builder setUserSavedNetworkConfigurations( + @NonNull List userSavedNetworkConfigurations) { + checkNotNull(userSavedNetworkConfigurations); + mUserSavedNetworkConfigurations = userSavedNetworkConfigurations; + return this; + } + + /** + * Sets the user's softap configuration parsed from OEM config store files. + * + * @param userSoftApConfiguration {@link SoftApConfiguration} representing user's + * SoftAp configuration + * @return Instance of {@link Builder} to enable chaining of the builder method. + */ + public @NonNull Builder setUserSoftApConfiguration( + @NonNull SoftApConfiguration userSoftApConfiguration) { + checkNotNull(userSoftApConfiguration); + mUserSoftApConfiguration = userSoftApConfiguration; + return this; + } + + /** + * Build an instance of {@link ConfigStoreMigrationData}. + * + * @return Instance of {@link ConfigStoreMigrationData}. + */ + public @NonNull ConfigStoreMigrationData build() { + return new ConfigStoreMigrationData( + mUserSavedNetworkConfigurations, mUserSoftApConfiguration); + } + } + + private final List mUserSavedNetworkConfigurations; + private final SoftApConfiguration mUserSoftApConfiguration; + + private ConfigStoreMigrationData( + @Nullable List userSavedNetworkConfigurations, + @Nullable SoftApConfiguration userSoftApConfiguration) { + mUserSavedNetworkConfigurations = userSavedNetworkConfigurations; + mUserSoftApConfiguration = userSoftApConfiguration; + } + + public static final @NonNull Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @Override + public ConfigStoreMigrationData createFromParcel(Parcel in) { + List userSavedNetworkConfigurations = + in.readArrayList(null); + SoftApConfiguration userSoftApConfiguration = in.readParcelable(null); + return new ConfigStoreMigrationData( + userSavedNetworkConfigurations, userSoftApConfiguration); + } + + @Override + public ConfigStoreMigrationData[] newArray(int size) { + return new ConfigStoreMigrationData[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeList(mUserSavedNetworkConfigurations); + dest.writeParcelable(mUserSoftApConfiguration, flags); + } + + /** + * Returns list of all user's saved network configurations. + * + * Note: Only to be returned if there is any format change in how OEM persisted this info. + * @return List of {@link WifiConfiguration} representing the list of user's saved networks, + * or null if no migration necessary. + */ + @Nullable + public List getUserSavedNetworkConfigurations() { + return mUserSavedNetworkConfigurations; + } + + /** + * Returns user's softap configuration. + * + * Note: Only to be returned if there is any format change in how OEM persisted this info. + * @return {@link SoftApConfiguration} representing user's SoftAp configuration, + * or null if no migration necessary. + */ + @Nullable + public SoftApConfiguration getUserSoftApConfiguration() { + return mUserSoftApConfiguration; + } + } + + /** + * Load data from OEM's config store. + *

    + * Note: + *

  • OEM's need to implement {@link #loadFromConfigStore()} ()} only if their + * existing config store format or file locations differs from the vanilla AOSP implementation ( + * which is what the wifi mainline module understands). + *
  • + *
  • The wifi mainline module will invoke {@link #loadFromConfigStore()} method on every + * bootup, its the responsibility of the OEM implementation to ensure that this method returns + * non-null data only on the first bootup. Once the migration is done, the OEM can safely delete + * their config store files and then return null on any subsequent reboots. The first & only + * relevant invocation of {@link #loadFromConfigStore()} occurs when a previously released + * device upgrades to the wifi mainline module from an OEM implementation of the wifi stack. + *
  • + * + * @return Instance of {@link ConfigStoreMigrationData} for migrating data, null if no + * migration is necessary. + */ + @Nullable + public static ConfigStoreMigrationData loadFromConfigStore() { + // Note: OEM's should add code to parse data from their config store format here! + return null; + } + + /** + * Container for all the wifi settings data to migrate. + */ + public static final class SettingsMigrationData implements Parcelable { + private final boolean mScanAlwaysAvailable; + private final boolean mP2pFactoryResetPending; + private final String mP2pDeviceName; + private final boolean mSoftApTimeoutEnabled; + private final boolean mWakeupEnabled; + private final boolean mScanThrottleEnabled; + private final boolean mVerboseLoggingEnabled; + + private SettingsMigrationData(boolean scanAlwaysAvailable, boolean p2pFactoryResetPending, + @Nullable String p2pDeviceName, boolean softApTimeoutEnabled, boolean wakeupEnabled, + boolean scanThrottleEnabled, boolean verboseLoggingEnabled) { + mScanAlwaysAvailable = scanAlwaysAvailable; + mP2pFactoryResetPending = p2pFactoryResetPending; + mP2pDeviceName = p2pDeviceName; + mSoftApTimeoutEnabled = softApTimeoutEnabled; + mWakeupEnabled = wakeupEnabled; + mScanThrottleEnabled = scanThrottleEnabled; + mVerboseLoggingEnabled = verboseLoggingEnabled; + } + + public static final @NonNull Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @Override + public SettingsMigrationData createFromParcel(Parcel in) { + boolean scanAlwaysAvailable = in.readBoolean(); + boolean p2pFactoryResetPending = in.readBoolean(); + String p2pDeviceName = in.readString(); + boolean softApTimeoutEnabled = in.readBoolean(); + boolean wakeupEnabled = in.readBoolean(); + boolean scanThrottleEnabled = in.readBoolean(); + boolean verboseLoggingEnabled = in.readBoolean(); + return new SettingsMigrationData( + scanAlwaysAvailable, p2pFactoryResetPending, + p2pDeviceName, softApTimeoutEnabled, wakeupEnabled, + scanThrottleEnabled, verboseLoggingEnabled); + } + + @Override + public SettingsMigrationData[] newArray(int size) { + return new SettingsMigrationData[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeBoolean(mScanAlwaysAvailable); + dest.writeBoolean(mP2pFactoryResetPending); + dest.writeString(mP2pDeviceName); + dest.writeBoolean(mSoftApTimeoutEnabled); + dest.writeBoolean(mWakeupEnabled); + dest.writeBoolean(mScanThrottleEnabled); + dest.writeBoolean(mVerboseLoggingEnabled); + } + + /** + * @return True if scans are allowed even when wifi is toggled off, false otherwise. + */ + public boolean isScanAlwaysAvailable() { + return mScanAlwaysAvailable; + } + + /** + * @return indicate whether factory reset request is pending. + */ + public boolean isP2pFactoryResetPending() { + return mP2pFactoryResetPending; + } + + /** + * @return the Wi-Fi peer-to-peer device name + */ + public @Nullable String getP2pDeviceName() { + return mP2pDeviceName; + } + + /** + * @return Whether soft AP will shut down after a timeout period when no devices are + * connected. + */ + public boolean isSoftApTimeoutEnabled() { + return mSoftApTimeoutEnabled; + } + + /** + * @return whether Wi-Fi Wakeup feature is enabled. + */ + public boolean isWakeUpEnabled() { + return mWakeupEnabled; + } + + /** + * @return Whether wifi scan throttle is enabled or not. + */ + public boolean isScanThrottleEnabled() { + return mScanThrottleEnabled; + } + + /** + * @return Whether to enable verbose logging in Wi-Fi. + */ + public boolean isVerboseLoggingEnabled() { + return mVerboseLoggingEnabled; + } + + /** + * Builder to create instance of {@link SettingsMigrationData}. + */ + public static final class Builder { + private boolean mScanAlwaysAvailable; + private boolean mP2pFactoryResetPending; + private String mP2pDeviceName; + private boolean mSoftApTimeoutEnabled; + private boolean mWakeupEnabled; + private boolean mScanThrottleEnabled; + private boolean mVerboseLoggingEnabled; + + public Builder() { + } + + /** + * Setting to allow scans even when wifi is toggled off. + * + * @param available true if available, false otherwise. + * @return Instance of {@link Builder} to enable chaining of the builder method. + */ + public @NonNull Builder setScanAlwaysAvailable(boolean available) { + mScanAlwaysAvailable = available; + return this; + } + + /** + * Indicate whether factory reset request is pending. + * + * @param pending true if pending, false otherwise. + * @return Instance of {@link Builder} to enable chaining of the builder method. + */ + public @NonNull Builder setP2pFactoryResetPending(boolean pending) { + mP2pFactoryResetPending = pending; + return this; + } + + /** + * The Wi-Fi peer-to-peer device name + * + * @param name Name if set, null otherwise. + * @return Instance of {@link Builder} to enable chaining of the builder method. + */ + public @NonNull Builder setP2pDeviceName(@Nullable String name) { + mP2pDeviceName = name; + return this; + } + + /** + * Whether soft AP will shut down after a timeout period when no devices are connected. + * + * @param enabled true if enabled, false otherwise. + * @return Instance of {@link Builder} to enable chaining of the builder method. + */ + public @NonNull Builder setSoftApTimeoutEnabled(boolean enabled) { + mSoftApTimeoutEnabled = enabled; + return this; + } + + /** + * Value to specify if Wi-Fi Wakeup feature is enabled. + * + * @param enabled true if enabled, false otherwise. + * @return Instance of {@link Builder} to enable chaining of the builder method. + */ + public @NonNull Builder setWakeUpEnabled(boolean enabled) { + mWakeupEnabled = enabled; + return this; + } + + /** + * Whether wifi scan throttle is enabled or not. + * + * @param enabled true if enabled, false otherwise. + * @return Instance of {@link Builder} to enable chaining of the builder method. + */ + public @NonNull Builder setScanThrottleEnabled(boolean enabled) { + mScanThrottleEnabled = enabled; + return this; + } + + /** + * Setting to enable verbose logging in Wi-Fi. + * + * @param enabled true if enabled, false otherwise. + * @return Instance of {@link Builder} to enable chaining of the builder method. + */ + public @NonNull Builder setVerboseLoggingEnabled(boolean enabled) { + mVerboseLoggingEnabled = enabled; + return this; + } + + /** + * Build an instance of {@link SettingsMigrationData}. + * + * @return Instance of {@link SettingsMigrationData}. + */ + public @NonNull SettingsMigrationData build() { + return new SettingsMigrationData(mScanAlwaysAvailable, mP2pFactoryResetPending, + mP2pDeviceName, mSoftApTimeoutEnabled, mWakeupEnabled, mScanThrottleEnabled, + mVerboseLoggingEnabled); + } + } + } + + /** + * Load data from Settings.Global values. + * + *

    + * Note: + *

  • This is method is invoked once on the first bootup. OEM can safely delete these settings + * once the migration is complete. The first & only relevant invocation of + * {@link #loadFromSettings(Context)} ()} occurs when a previously released + * device upgrades to the wifi mainline module from an OEM implementation of the wifi stack. + *
  • + * + * @param context Context to use for loading the settings provider. + * @return Instance of {@link SettingsMigrationData} for migrating data. + */ + @NonNull + public static SettingsMigrationData loadFromSettings(@NonNull Context context) { + return new SettingsMigrationData.Builder() + .setScanAlwaysAvailable( + Settings.Global.getInt(context.getContentResolver(), + Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 1) + .setP2pFactoryResetPending( + Settings.Global.getInt(context.getContentResolver(), + Settings.Global.WIFI_P2P_PENDING_FACTORY_RESET, 0) == 1) + .setP2pDeviceName( + Settings.Global.getString(context.getContentResolver(), + Settings.Global.WIFI_P2P_DEVICE_NAME)) + .setSoftApTimeoutEnabled( + Settings.Global.getInt(context.getContentResolver(), + Settings.Global.SOFT_AP_TIMEOUT_ENABLED, 1) == 1) + .setWakeUpEnabled( + Settings.Global.getInt(context.getContentResolver(), + Settings.Global.WIFI_WAKEUP_ENABLED, 0) == 1) + .setScanThrottleEnabled( + Settings.Global.getInt(context.getContentResolver(), + Settings.Global.WIFI_SCAN_THROTTLE_ENABLED, 1) == 1) + .setVerboseLoggingEnabled( + Settings.Global.getInt(context.getContentResolver(), + Settings.Global.WIFI_VERBOSE_LOGGING_ENABLED, 0) == 1) + .build(); + } +} diff --git a/wifi/java/android/net/wifi/WifiOemMigrationHook.java b/wifi/java/android/net/wifi/WifiOemMigrationHook.java deleted file mode 100755 index 5301dd013363..000000000000 --- a/wifi/java/android/net/wifi/WifiOemMigrationHook.java +++ /dev/null @@ -1,443 +0,0 @@ -/* - * Copyright (C) 2020 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 com.android.internal.util.Preconditions.checkNotNull; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.content.Context; -import android.os.Parcel; -import android.os.Parcelable; -import android.provider.Settings; - -import java.util.List; - -/** - * Class used to provide one time hooks for existing OEM devices to migrate their config store - * data and other settings to the wifi mainline module. - * @hide - */ -@SystemApi -public final class WifiOemMigrationHook { - - private WifiOemMigrationHook() { } - - /** - * Container for all the wifi config data to migrate. - */ - public static final class ConfigStoreMigrationData implements Parcelable { - /** - * Builder to create instance of {@link ConfigStoreMigrationData}. - */ - public static final class Builder { - private List mUserSavedNetworkConfigurations; - private SoftApConfiguration mUserSoftApConfiguration; - - public Builder() { - mUserSavedNetworkConfigurations = null; - mUserSoftApConfiguration = null; - } - - /** - * Sets the list of all user's saved network configurations parsed from OEM config - * store files. - * - * @param userSavedNetworkConfigurations List of {@link WifiConfiguration} representing - * the list of user's saved networks - * @return Instance of {@link Builder} to enable chaining of the builder method. - */ - public @NonNull Builder setUserSavedNetworkConfigurations( - @NonNull List userSavedNetworkConfigurations) { - checkNotNull(userSavedNetworkConfigurations); - mUserSavedNetworkConfigurations = userSavedNetworkConfigurations; - return this; - } - - /** - * Sets the user's softap configuration parsed from OEM config store files. - * - * @param userSoftApConfiguration {@link SoftApConfiguration} representing user's - * SoftAp configuration - * @return Instance of {@link Builder} to enable chaining of the builder method. - */ - public @NonNull Builder setUserSoftApConfiguration( - @NonNull SoftApConfiguration userSoftApConfiguration) { - checkNotNull(userSoftApConfiguration); - mUserSoftApConfiguration = userSoftApConfiguration; - return this; - } - - /** - * Build an instance of {@link ConfigStoreMigrationData}. - * - * @return Instance of {@link ConfigStoreMigrationData}. - */ - public @NonNull ConfigStoreMigrationData build() { - return new ConfigStoreMigrationData( - mUserSavedNetworkConfigurations, mUserSoftApConfiguration); - } - } - - private final List mUserSavedNetworkConfigurations; - private final SoftApConfiguration mUserSoftApConfiguration; - - private ConfigStoreMigrationData( - @Nullable List userSavedNetworkConfigurations, - @Nullable SoftApConfiguration userSoftApConfiguration) { - mUserSavedNetworkConfigurations = userSavedNetworkConfigurations; - mUserSoftApConfiguration = userSoftApConfiguration; - } - - public static final @NonNull Parcelable.Creator CREATOR = - new Parcelable.Creator() { - @Override - public ConfigStoreMigrationData createFromParcel(Parcel in) { - List userSavedNetworkConfigurations = - in.readArrayList(null); - SoftApConfiguration userSoftApConfiguration = in.readParcelable(null); - return new ConfigStoreMigrationData( - userSavedNetworkConfigurations, userSoftApConfiguration); - } - - @Override - public ConfigStoreMigrationData[] newArray(int size) { - return new ConfigStoreMigrationData[size]; - } - }; - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(@NonNull Parcel dest, int flags) { - dest.writeList(mUserSavedNetworkConfigurations); - dest.writeParcelable(mUserSoftApConfiguration, flags); - } - - /** - * Returns list of all user's saved network configurations. - * - * Note: Only to be returned if there is any format change in how OEM persisted this info. - * @return List of {@link WifiConfiguration} representing the list of user's saved networks, - * or null if no migration necessary. - */ - @Nullable - public List getUserSavedNetworkConfigurations() { - return mUserSavedNetworkConfigurations; - } - - /** - * Returns user's softap configuration. - * - * Note: Only to be returned if there is any format change in how OEM persisted this info. - * @return {@link SoftApConfiguration} representing user's SoftAp configuration, - * or null if no migration necessary. - */ - @Nullable - public SoftApConfiguration getUserSoftApConfiguration() { - return mUserSoftApConfiguration; - } - } - - /** - * Load data from OEM's config store. - *

    - * Note: - *

  • OEM's need to implement {@link #loadFromConfigStore()} ()} only if their - * existing config store format or file locations differs from the vanilla AOSP implementation ( - * which is what the wifi mainline module understands). - *
  • - *
  • The wifi mainline module will invoke {@link #loadFromConfigStore()} method on every - * bootup, its the responsibility of the OEM implementation to ensure that this method returns - * non-null data only on the first bootup. Once the migration is done, the OEM can safely delete - * their config store files and then return null on any subsequent reboots. The first & only - * relevant invocation of {@link #loadFromConfigStore()} occurs when a previously released - * device upgrades to the wifi mainline module from an OEM implementation of the wifi stack. - *
  • - * - * @return Instance of {@link ConfigStoreMigrationData} for migrating data, null if no - * migration is necessary. - */ - @Nullable - public static ConfigStoreMigrationData loadFromConfigStore() { - // Note: OEM's should add code to parse data from their config store format here! - return null; - } - - /** - * Container for all the wifi settings data to migrate. - */ - public static final class SettingsMigrationData implements Parcelable { - private final boolean mScanAlwaysAvailable; - private final boolean mP2pFactoryResetPending; - private final String mP2pDeviceName; - private final boolean mSoftApTimeoutEnabled; - private final boolean mWakeupEnabled; - private final boolean mScanThrottleEnabled; - private final boolean mVerboseLoggingEnabled; - - private SettingsMigrationData(boolean scanAlwaysAvailable, boolean p2pFactoryResetPending, - @Nullable String p2pDeviceName, boolean softApTimeoutEnabled, boolean wakeupEnabled, - boolean scanThrottleEnabled, boolean verboseLoggingEnabled) { - mScanAlwaysAvailable = scanAlwaysAvailable; - mP2pFactoryResetPending = p2pFactoryResetPending; - mP2pDeviceName = p2pDeviceName; - mSoftApTimeoutEnabled = softApTimeoutEnabled; - mWakeupEnabled = wakeupEnabled; - mScanThrottleEnabled = scanThrottleEnabled; - mVerboseLoggingEnabled = verboseLoggingEnabled; - } - - public static final @NonNull Parcelable.Creator CREATOR = - new Parcelable.Creator() { - @Override - public SettingsMigrationData createFromParcel(Parcel in) { - boolean scanAlwaysAvailable = in.readBoolean(); - boolean p2pFactoryResetPending = in.readBoolean(); - String p2pDeviceName = in.readString(); - boolean softApTimeoutEnabled = in.readBoolean(); - boolean wakeupEnabled = in.readBoolean(); - boolean scanThrottleEnabled = in.readBoolean(); - boolean verboseLoggingEnabled = in.readBoolean(); - return new SettingsMigrationData( - scanAlwaysAvailable, p2pFactoryResetPending, - p2pDeviceName, softApTimeoutEnabled, wakeupEnabled, - scanThrottleEnabled, verboseLoggingEnabled); - } - - @Override - public SettingsMigrationData[] newArray(int size) { - return new SettingsMigrationData[size]; - } - }; - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(@NonNull Parcel dest, int flags) { - dest.writeBoolean(mScanAlwaysAvailable); - dest.writeBoolean(mP2pFactoryResetPending); - dest.writeString(mP2pDeviceName); - dest.writeBoolean(mSoftApTimeoutEnabled); - dest.writeBoolean(mWakeupEnabled); - dest.writeBoolean(mScanThrottleEnabled); - dest.writeBoolean(mVerboseLoggingEnabled); - } - - /** - * @return True if scans are allowed even when wifi is toggled off, false otherwise. - */ - public boolean isScanAlwaysAvailable() { - return mScanAlwaysAvailable; - } - - /** - * @return indicate whether factory reset request is pending. - */ - public boolean isP2pFactoryResetPending() { - return mP2pFactoryResetPending; - } - - /** - * @return the Wi-Fi peer-to-peer device name - */ - public @Nullable String getP2pDeviceName() { - return mP2pDeviceName; - } - - /** - * @return Whether soft AP will shut down after a timeout period when no devices are - * connected. - */ - public boolean isSoftApTimeoutEnabled() { - return mSoftApTimeoutEnabled; - } - - /** - * @return whether Wi-Fi Wakeup feature is enabled. - */ - public boolean isWakeUpEnabled() { - return mWakeupEnabled; - } - - /** - * @return Whether wifi scan throttle is enabled or not. - */ - public boolean isScanThrottleEnabled() { - return mScanThrottleEnabled; - } - - /** - * @return Whether to enable verbose logging in Wi-Fi. - */ - public boolean isVerboseLoggingEnabled() { - return mVerboseLoggingEnabled; - } - - /** - * Builder to create instance of {@link SettingsMigrationData}. - */ - public static final class Builder { - private boolean mScanAlwaysAvailable; - private boolean mP2pFactoryResetPending; - private String mP2pDeviceName; - private boolean mSoftApTimeoutEnabled; - private boolean mWakeupEnabled; - private boolean mScanThrottleEnabled; - private boolean mVerboseLoggingEnabled; - - public Builder() { - } - - /** - * Setting to allow scans even when wifi is toggled off. - * - * @param available true if available, false otherwise. - * @return Instance of {@link Builder} to enable chaining of the builder method. - */ - public @NonNull Builder setScanAlwaysAvailable(boolean available) { - mScanAlwaysAvailable = available; - return this; - } - - /** - * Indicate whether factory reset request is pending. - * - * @param pending true if pending, false otherwise. - * @return Instance of {@link Builder} to enable chaining of the builder method. - */ - public @NonNull Builder setP2pFactoryResetPending(boolean pending) { - mP2pFactoryResetPending = pending; - return this; - } - - /** - * The Wi-Fi peer-to-peer device name - * - * @param name Name if set, null otherwise. - * @return Instance of {@link Builder} to enable chaining of the builder method. - */ - public @NonNull Builder setP2pDeviceName(@Nullable String name) { - mP2pDeviceName = name; - return this; - } - - /** - * Whether soft AP will shut down after a timeout period when no devices are connected. - * - * @param enabled true if enabled, false otherwise. - * @return Instance of {@link Builder} to enable chaining of the builder method. - */ - public @NonNull Builder setSoftApTimeoutEnabled(boolean enabled) { - mSoftApTimeoutEnabled = enabled; - return this; - } - - /** - * Value to specify if Wi-Fi Wakeup feature is enabled. - * - * @param enabled true if enabled, false otherwise. - * @return Instance of {@link Builder} to enable chaining of the builder method. - */ - public @NonNull Builder setWakeUpEnabled(boolean enabled) { - mWakeupEnabled = enabled; - return this; - } - - /** - * Whether wifi scan throttle is enabled or not. - * - * @param enabled true if enabled, false otherwise. - * @return Instance of {@link Builder} to enable chaining of the builder method. - */ - public @NonNull Builder setScanThrottleEnabled(boolean enabled) { - mScanThrottleEnabled = enabled; - return this; - } - - /** - * Setting to enable verbose logging in Wi-Fi. - * - * @param enabled true if enabled, false otherwise. - * @return Instance of {@link Builder} to enable chaining of the builder method. - */ - public @NonNull Builder setVerboseLoggingEnabled(boolean enabled) { - mVerboseLoggingEnabled = enabled; - return this; - } - - /** - * Build an instance of {@link SettingsMigrationData}. - * - * @return Instance of {@link SettingsMigrationData}. - */ - public @NonNull SettingsMigrationData build() { - return new SettingsMigrationData(mScanAlwaysAvailable, mP2pFactoryResetPending, - mP2pDeviceName, mSoftApTimeoutEnabled, mWakeupEnabled, mScanThrottleEnabled, - mVerboseLoggingEnabled); - } - } - } - - /** - * Load data from Settings.Global values. - * - *

    - * Note: - *

  • This is method is invoked once on the first bootup. OEM can safely delete these settings - * once the migration is complete. The first & only relevant invocation of - * {@link #loadFromSettings(Context)} ()} occurs when a previously released - * device upgrades to the wifi mainline module from an OEM implementation of the wifi stack. - *
  • - * - * @param context Context to use for loading the settings provider. - * @return Instance of {@link SettingsMigrationData} for migrating data. - */ - @NonNull - public static SettingsMigrationData loadFromSettings(@NonNull Context context) { - return new SettingsMigrationData.Builder() - .setScanAlwaysAvailable( - Settings.Global.getInt(context.getContentResolver(), - Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 1) - .setP2pFactoryResetPending( - Settings.Global.getInt(context.getContentResolver(), - Settings.Global.WIFI_P2P_PENDING_FACTORY_RESET, 0) == 1) - .setP2pDeviceName( - Settings.Global.getString(context.getContentResolver(), - Settings.Global.WIFI_P2P_DEVICE_NAME)) - .setSoftApTimeoutEnabled( - Settings.Global.getInt(context.getContentResolver(), - Settings.Global.SOFT_AP_TIMEOUT_ENABLED, 1) == 1) - .setWakeUpEnabled( - Settings.Global.getInt(context.getContentResolver(), - Settings.Global.WIFI_WAKEUP_ENABLED, 0) == 1) - .setScanThrottleEnabled( - Settings.Global.getInt(context.getContentResolver(), - Settings.Global.WIFI_SCAN_THROTTLE_ENABLED, 1) == 1) - .setVerboseLoggingEnabled( - Settings.Global.getInt(context.getContentResolver(), - Settings.Global.WIFI_VERBOSE_LOGGING_ENABLED, 0) == 1) - .build(); - } -} -- cgit v1.2.3 From 4c7baf7ba29f4e0afd446f0c2b3501bbb1e6f7ea Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Mon, 24 Feb 2020 13:14:02 -0800 Subject: WifiMigration: Add a method for removing config store Adding a new method to trigger OEM config store removal after migration is complete. Bug: 149418926 Test: Compiles Change-Id: Ie22ff99931cc5f2ccbc47a55a2ac6e3b2baa41d7 --- wifi/java/android/net/wifi/WifiMigration.java | 32 ++++++++++++++++++++------- 1 file changed, 24 insertions(+), 8 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiMigration.java b/wifi/java/android/net/wifi/WifiMigration.java index 695f00f643ad..a3482d732a1b 100755 --- a/wifi/java/android/net/wifi/WifiMigration.java +++ b/wifi/java/android/net/wifi/WifiMigration.java @@ -161,16 +161,16 @@ public final class WifiMigration { * Load data from OEM's config store. *

    * Note: - *

  • OEM's need to implement {@link #loadFromConfigStore()} ()} only if their - * existing config store format or file locations differs from the vanilla AOSP implementation ( - * which is what the wifi mainline module understands). + *
  • OEMs need to implement {@link #loadFromConfigStore()} ()} only if their + * existing config store format or file locations differs from the vanilla AOSP implementation. *
  • - *
  • The wifi mainline module will invoke {@link #loadFromConfigStore()} method on every + *
  • The wifi mainline module will invoke {@link #loadFromConfigStore()} method on every * bootup, its the responsibility of the OEM implementation to ensure that this method returns * non-null data only on the first bootup. Once the migration is done, the OEM can safely delete - * their config store files and then return null on any subsequent reboots. The first & only - * relevant invocation of {@link #loadFromConfigStore()} occurs when a previously released - * device upgrades to the wifi mainline module from an OEM implementation of the wifi stack. + * their config store files when {@link #removeConfigStore()} is invoked. + *
  • The first & only relevant invocation of {@link #loadFromConfigStore()} occurs when a + * previously released device upgrades to the wifi mainline module from an OEM implementation + * of the wifi stack. *
  • * * @return Instance of {@link ConfigStoreMigrationData} for migrating data, null if no @@ -178,10 +178,26 @@ public final class WifiMigration { */ @Nullable public static ConfigStoreMigrationData loadFromConfigStore() { - // Note: OEM's should add code to parse data from their config store format here! + // Note: OEMs should add code to parse data from their config store format here! return null; } + /** + * Remove OEM's config store. + *

    + * Note: + *

  • OEMs need to implement {@link #removeConfigStore()} only if their + * existing config store format or file locations differs from the vanilla AOSP implementation ( + * which is what the wifi mainline module understands). + *
  • + *
  • The wifi mainline module will invoke {@link #removeConfigStore()} after it migrates + * all the existing data retrieved from {@link #loadFromConfigStore()}. + *
  • + */ + public static void removeConfigStore() { + // Note: OEMs should remove their custom config store files here! + } + /** * Container for all the wifi settings data to migrate. */ -- cgit v1.2.3 From e4956075daf73bd58fdef463483e49b6acbe8aff Mon Sep 17 00:00:00 2001 From: David Su Date: Tue, 25 Feb 2020 14:24:54 -0800 Subject: Rename NetworkSelectionStatus#getNetworkDisableReasonString Renamed to getNetworkSelectionDisableReasonString to be more descriptive. Bug: 146046526 Test: compiles Change-Id: I8d67906e31e66f4cf839be1637ecb6a58edbbc52 --- wifi/java/android/net/wifi/WifiConfiguration.java | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index c48e89526ae0..0229b846bc6d 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -1713,7 +1713,7 @@ public class WifiConfiguration implements Parcelable { * @return network disable reason string, or null if the reason is invalid. */ @Nullable - public static String getNetworkDisableReasonString( + public static String getNetworkSelectionDisableReasonString( @NetworkSelectionDisableReason int reason) { DisableReasonInfo info = DISABLE_REASON_INFOS.get(reason); if (info == null) { @@ -1727,8 +1727,8 @@ public class WifiConfiguration implements Parcelable { * @return current network disable reason in String (for debug purpose) * @hide */ - public String getNetworkDisableReasonString() { - return getNetworkDisableReasonString(mNetworkSelectionDisableReason); + public String getNetworkSelectionDisableReasonString() { + return getNetworkSelectionDisableReasonString(mNetworkSelectionDisableReason); } /** @@ -2189,17 +2189,21 @@ public class WifiConfiguration implements Parcelable { sbuf.append(" NetworkSelectionStatus ") - .append(mNetworkSelectionStatus.getNetworkStatusString() + "\n"); + .append(mNetworkSelectionStatus.getNetworkStatusString()) + .append("\n"); if (mNetworkSelectionStatus.getNetworkSelectionDisableReason() > 0) { sbuf.append(" mNetworkSelectionDisableReason ") - .append(mNetworkSelectionStatus.getNetworkDisableReasonString() + "\n"); + .append(mNetworkSelectionStatus.getNetworkSelectionDisableReasonString()) + .append("\n"); for (int index = NetworkSelectionStatus.DISABLED_NONE; index < NetworkSelectionStatus.NETWORK_SELECTION_DISABLED_MAX; index++) { if (mNetworkSelectionStatus.getDisableReasonCounter(index) != 0) { - sbuf.append(NetworkSelectionStatus.getNetworkDisableReasonString(index) - + " counter:" + mNetworkSelectionStatus.getDisableReasonCounter(index) - + "\n"); + sbuf.append( + NetworkSelectionStatus.getNetworkSelectionDisableReasonString(index)) + .append(" counter:") + .append(mNetworkSelectionStatus.getDisableReasonCounter(index)) + .append("\n"); } } } -- cgit v1.2.3 From 4146fb0bcffb4830638f8d0c90b0dcff6970a8c5 Mon Sep 17 00:00:00 2001 From: "Nate(Qiang) Jiang" Date: Wed, 26 Feb 2020 10:28:43 -0800 Subject: Add Doc about app disable or netowrk reset will remove suggeestion Bug: 150247605 Test: build Change-Id: Iaeec1404311bb3eea1d0be83d20a4bf0c8962d61 --- wifi/java/android/net/wifi/WifiManager.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 7d4b63285eea..d97379e5fea4 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1881,9 +1881,11 @@ public class WifiManager { * NOTE: *
  • These networks are just a suggestion to the platform. The platform will ultimately * decide on which network the device connects to.
  • - *
  • When an app is uninstalled, all its suggested networks are discarded. If the device is - * currently connected to a suggested network which is being removed then the device will - * disconnect from that network.
  • + *
  • When an app is uninstalled or disabled, all its suggested networks are discarded. + * If the device is currently connected to a suggested network which is being removed then the + * device will disconnect from that network.
  • + *
  • If user reset network settings, all added suggestions will be discarded. Apps can use + * {@link #getNetworkSuggestions()} to check if their suggestions are in the device.
  • *
  • In-place modification of existing suggestions are allowed. * If the provided suggestions {@link WifiNetworkSuggestion#equals(Object)} any previously * provided suggestions by the app. Previous suggestions will be updated
  • -- cgit v1.2.3 From 715d5cad5fdd0e8e0f7ceae76289f5e71118db80 Mon Sep 17 00:00:00 2001 From: "Nate(Qiang) Jiang" Date: Wed, 26 Feb 2020 16:02:08 -0800 Subject: Change the doc for disableEphemeralNetwork. Expend the usage of this API to all network type. Bug: 136005248 Test: build Change-Id: I54853431aad9ccb7db18eea39a2a1df830814d4f --- wifi/java/android/net/wifi/WifiManager.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 7d4b63285eea..0611bdfea729 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -4430,10 +4430,11 @@ public class WifiManager { } /** - * Disable an ephemeral network. - * - * @param ssid in the format of WifiConfiguration's SSID. + * Temporarily disable a network. Should always trigger with user disconnect network. * + * @param network Input can be SSID or FQDN. And caller must ensure that the SSID passed thru + * this API matched the WifiConfiguration.SSID rules, and thus be surrounded by + * quotes. * @hide */ @SystemApi @@ -4441,12 +4442,12 @@ public class WifiManager { android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK }) - public void disableEphemeralNetwork(@NonNull String ssid) { - if (TextUtils.isEmpty(ssid)) { + public void disableEphemeralNetwork(@NonNull String network) { + if (TextUtils.isEmpty(network)) { throw new IllegalArgumentException("SSID cannot be null or empty!"); } try { - mService.disableEphemeralNetwork(ssid, mContext.getOpPackageName()); + mService.disableEphemeralNetwork(network, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } -- cgit v1.2.3 From ef8cfa2a46ab4a81245b71d67e7d5020297715dd Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Thu, 27 Feb 2020 15:47:38 -0800 Subject: [Passpoint] Allow profile installations with no Root CA certificate Allow Passpoint R1 profile installations with no Root CA certificate. The system will use the default trust root in such case. Bug: 150410562 Test: atest CredentialTest Change-Id: I2f11ba7330aae8a8c9e0b8922bcf320eb95c5e0e --- .../net/wifi/hotspot2/PasspointConfiguration.java | 8 +- .../android/net/wifi/hotspot2/pps/Credential.java | 29 ++----- .../net/wifi/hotspot2/pps/CredentialTest.java | 98 ++++++++++------------ 3 files changed, 57 insertions(+), 78 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java index 4507cc2707d4..d1d1780a25fd 100644 --- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java +++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java @@ -722,7 +722,7 @@ public final class PasspointConfiguration implements Parcelable { if (mSubscriptionUpdate != null && !mSubscriptionUpdate.validate()) { return false; } - return validateForCommonR1andR2(true); + return validateForCommonR1andR2(); } /** @@ -741,17 +741,17 @@ public final class PasspointConfiguration implements Parcelable { if (mSubscriptionUpdate == null || !mSubscriptionUpdate.validate()) { return false; } - return validateForCommonR1andR2(false); + return validateForCommonR1andR2(); } - private boolean validateForCommonR1andR2(boolean isR1) { + private boolean validateForCommonR1andR2() { // Required: PerProviderSubscription//HomeSP if (mHomeSp == null || !mHomeSp.validate()) { return false; } // Required: PerProviderSubscription//Credential - if (mCredential == null || !mCredential.validate(isR1)) { + if (mCredential == null || !mCredential.validate()) { return false; } diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java index 9c01d3643c19..65e8b3d9283d 100644 --- a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java +++ b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java @@ -1081,11 +1081,10 @@ public final class Credential implements Parcelable { /** * Validate the configuration data. * - * @param isR1 {@code true} if the configuration is for R1 * @return true on success or false on failure * @hide */ - public boolean validate(boolean isR1) { + public boolean validate() { if (TextUtils.isEmpty(mRealm)) { Log.d(TAG, "Missing realm"); return false; @@ -1098,11 +1097,11 @@ public final class Credential implements Parcelable { // Verify the credential. if (mUserCredential != null) { - if (!verifyUserCredential(isR1)) { + if (!verifyUserCredential()) { return false; } } else if (mCertCredential != null) { - if (!verifyCertCredential(isR1)) { + if (!verifyCertCredential()) { return false; } } else if (mSimCredential != null) { @@ -1143,11 +1142,11 @@ public final class Credential implements Parcelable { /** * Verify user credential. + * If no CA certificate is provided, then the system uses the CAs in the trust store. * - * @param isR1 {@code true} if credential is for R1 * @return true if user credential is valid, false otherwise. */ - private boolean verifyUserCredential(boolean isR1) { + private boolean verifyUserCredential() { if (mUserCredential == null) { Log.d(TAG, "Missing user credential"); return false; @@ -1160,24 +1159,17 @@ public final class Credential implements Parcelable { return false; } - // CA certificate is required for R1 Passpoint profile. - // For R2, it is downloaded using cert URL provided in PPS MO after validation completes. - if (isR1 && mCaCertificates == null) { - Log.d(TAG, "Missing CA Certificate for user credential"); - return false; - } - return true; } /** * Verify certificate credential, which is used for EAP-TLS. This will verify * that the necessary client key and certificates are provided. + * If no CA certificate is provided, then the system uses the CAs in the trust store. * - * @param isR1 {@code true} if credential is for R1 * @return true if certificate credential is valid, false otherwise. */ - private boolean verifyCertCredential(boolean isR1) { + private boolean verifyCertCredential() { if (mCertCredential == null) { Log.d(TAG, "Missing certificate credential"); return false; @@ -1191,13 +1183,6 @@ public final class Credential implements Parcelable { return false; } - // Verify required key and certificates for certificate credential. - // CA certificate is required for R1 Passpoint profile. - // For R2, it is downloaded using cert URL provided in PPS MO after validation completes. - if (isR1 && mCaCertificates == null) { - Log.d(TAG, "Missing CA Certificate for certificate credential"); - return false; - } if (mClientPrivateKey == null) { Log.d(TAG, "Missing client private key for certificate credential"); return false; diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java index 0a3e989d18f0..c6825822f4cc 100644 --- a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java +++ b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java @@ -158,7 +158,7 @@ public class CredentialTest { } /** - * Verify parcel read/write for an user credential. + * Verify parcel read/write for a user credential. * * @throws Exception */ @@ -176,14 +176,14 @@ public class CredentialTest { Credential cred = createCredentialWithUserCredential(); // For R1 validation - assertTrue(cred.validate(true)); + assertTrue(cred.validate()); // For R2 validation - assertTrue(cred.validate(false)); + assertTrue(cred.validate()); } /** - * Verify that an user credential without CA Certificate is invalid. + * Verify that a user credential without CA Certificate is valid. * * @throws Exception */ @@ -192,15 +192,12 @@ public class CredentialTest { Credential cred = createCredentialWithUserCredential(); cred.setCaCertificate(null); - // For R1 validation - assertFalse(cred.validate(true)); - - // For R2 validation - assertTrue(cred.validate(false)); + // Accept a configuration with no CA certificate, the system will use the default cert store + assertTrue(cred.validate()); } /** - * Verify that an user credential with EAP type other than EAP-TTLS is invalid. + * Verify that a user credential with EAP type other than EAP-TTLS is invalid. * * @throws Exception */ @@ -210,15 +207,15 @@ public class CredentialTest { cred.getUserCredential().setEapType(EAPConstants.EAP_TLS); // For R1 validation - assertFalse(cred.validate(true)); + assertFalse(cred.validate()); // For R2 validation - assertFalse(cred.validate(false)); + assertFalse(cred.validate()); } /** - * Verify that an user credential without realm is invalid. + * Verify that a user credential without realm is invalid. * * @throws Exception */ @@ -228,14 +225,14 @@ public class CredentialTest { cred.setRealm(null); // For R1 validation - assertFalse(cred.validate(true)); + assertFalse(cred.validate()); // For R2 validation - assertFalse(cred.validate(false)); + assertFalse(cred.validate()); } /** - * Verify that an user credential without username is invalid. + * Verify that a user credential without username is invalid. * * @throws Exception */ @@ -245,14 +242,14 @@ public class CredentialTest { cred.getUserCredential().setUsername(null); // For R1 validation - assertFalse(cred.validate(true)); + assertFalse(cred.validate()); // For R2 validation - assertFalse(cred.validate(false)); + assertFalse(cred.validate()); } /** - * Verify that an user credential without password is invalid. + * Verify that a user credential without password is invalid. * * @throws Exception */ @@ -262,14 +259,14 @@ public class CredentialTest { cred.getUserCredential().setPassword(null); // For R1 validation - assertFalse(cred.validate(true)); + assertFalse(cred.validate()); // For R2 validation - assertFalse(cred.validate(false)); + assertFalse(cred.validate()); } /** - * Verify that an user credential without auth methoh (non-EAP inner method) is invalid. + * Verify that a user credential without auth methoh (non-EAP inner method) is invalid. * * @throws Exception */ @@ -279,10 +276,10 @@ public class CredentialTest { cred.getUserCredential().setNonEapInnerMethod(null); // For R1 validation - assertFalse(cred.validate(true)); + assertFalse(cred.validate()); // For R2 validation - assertFalse(cred.validate(false)); + assertFalse(cred.validate()); } /** @@ -297,10 +294,10 @@ public class CredentialTest { Credential cred = createCredentialWithCertificateCredential(); // For R1 validation - assertTrue(cred.validate(true)); + assertTrue(cred.validate()); // For R2 validation - assertTrue(cred.validate(true)); + assertTrue(cred.validate()); } /** @@ -313,11 +310,8 @@ public class CredentialTest { Credential cred = createCredentialWithCertificateCredential(); cred.setCaCertificate(null); - // For R1 validation - assertFalse(cred.validate(true)); - - // For R2 validation - assertTrue(cred.validate(false)); + // Accept a configuration with no CA certificate, the system will use the default cert store + assertTrue(cred.validate()); } /** @@ -331,10 +325,10 @@ public class CredentialTest { cred.setClientCertificateChain(null); // For R1 validation - assertFalse(cred.validate(true)); + assertFalse(cred.validate()); // For R2 validation - assertFalse(cred.validate(false)); + assertFalse(cred.validate()); } /** @@ -348,10 +342,10 @@ public class CredentialTest { cred.setClientPrivateKey(null); // For R1 validation - assertFalse(cred.validate(true)); + assertFalse(cred.validate()); // For R2 validation - assertFalse(cred.validate(false)); + assertFalse(cred.validate()); } /** @@ -366,10 +360,10 @@ public class CredentialTest { cred.getCertCredential().setCertSha256Fingerprint(new byte[32]); // For R1 validation - assertFalse(cred.validate(true)); + assertFalse(cred.validate()); // For R2 validation - assertFalse(cred.validate(false)); + assertFalse(cred.validate()); } /** @@ -382,10 +376,10 @@ public class CredentialTest { Credential cred = createCredentialWithSimCredential(); // For R1 validation - assertTrue(cred.validate(true)); + assertTrue(cred.validate()); // For R2 validation - assertTrue(cred.validate(false)); + assertTrue(cred.validate()); } /** @@ -399,10 +393,10 @@ public class CredentialTest { cred.getSimCredential().setEapType(EAPConstants.EAP_AKA); // For R1 validation - assertTrue(cred.validate(true)); + assertTrue(cred.validate()); // For R2 validation - assertTrue(cred.validate(false)); + assertTrue(cred.validate()); } /** @@ -416,10 +410,10 @@ public class CredentialTest { cred.getSimCredential().setEapType(EAPConstants.EAP_AKA_PRIME); // For R1 validation - assertTrue(cred.validate(true)); + assertTrue(cred.validate()); // For R2 validation - assertTrue(cred.validate(false)); + assertTrue(cred.validate()); } /** @@ -433,10 +427,10 @@ public class CredentialTest { cred.getSimCredential().setImsi(null); // For R1 validation - assertFalse(cred.validate(true)); + assertFalse(cred.validate()); // For R2 validation - assertFalse(cred.validate(false)); + assertFalse(cred.validate()); } /** @@ -450,10 +444,10 @@ public class CredentialTest { cred.getSimCredential().setImsi("dummy"); // For R1 validation - assertFalse(cred.validate(true)); + assertFalse(cred.validate()); // For R2 validation - assertFalse(cred.validate(false)); + assertFalse(cred.validate()); } /** @@ -467,14 +461,14 @@ public class CredentialTest { cred.getSimCredential().setEapType(EAPConstants.EAP_TLS); // For R1 validation - assertFalse(cred.validate(true)); + assertFalse(cred.validate()); // For R2 validation - assertFalse(cred.validate(false)); + assertFalse(cred.validate()); } /** - * Verify that a credential contained both an user and a SIM credential is invalid. + * Verify that a credential contained both a user and a SIM credential is invalid. * * @throws Exception */ @@ -488,10 +482,10 @@ public class CredentialTest { cred.setSimCredential(simCredential); // For R1 validation - assertFalse(cred.validate(true)); + assertFalse(cred.validate()); // For R2 validation - assertFalse(cred.validate(false)); + assertFalse(cred.validate()); } /** -- cgit v1.2.3 From 117cacc93f477feb6bbd56651bc6de5aece29ba9 Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Thu, 27 Feb 2020 17:42:23 -0800 Subject: Fix KeyMgmt.OSEN and Eap.UNAUTH_TLS handling Fix KeyMgmt.OSEN case in WifiConfiguration#getSsidAndSecurityTypeString and return the correct key when key management type os OSEN. Fix WifiEnterpriseconfig#saveToSupplicant when checking the prerequisite conditions to save the network, Eap.UNAUTH_TLS does not have a phase2 method. Bug: 150418439 Test: atest WifiConfigurationTest WifiEnterpriseConfigTest Change-Id: Iafb181c89530f67982541b07d0ac7a4e1eb3378a --- wifi/java/android/net/wifi/WifiConfiguration.java | 2 ++ wifi/java/android/net/wifi/WifiEnterpriseConfig.java | 2 +- .../android/net/wifi/WifiEnterpriseConfigTest.java | 19 +++++++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index c48e89526ae0..a2da895092f5 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -2550,6 +2550,8 @@ public class WifiConfiguration implements Parcelable { key = SSID + KeyMgmt.strings[KeyMgmt.WAPI_PSK]; } else if (allowedKeyManagement.get(KeyMgmt.WAPI_CERT)) { key = SSID + KeyMgmt.strings[KeyMgmt.WAPI_CERT]; + } else if (allowedKeyManagement.get(KeyMgmt.OSEN)) { + key = SSID + KeyMgmt.strings[KeyMgmt.OSEN]; } else { key = SSID + KeyMgmt.strings[KeyMgmt.NONE]; } diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java index fb6e9ed532a7..2e4e7f541ac2 100644 --- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java +++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java @@ -482,7 +482,7 @@ public class WifiEnterpriseConfig implements Parcelable { return false; } - if (mEapMethod != Eap.TLS && mPhase2Method != Phase2.NONE) { + if (mEapMethod != Eap.TLS && mEapMethod != Eap.UNAUTH_TLS && mPhase2Method != Phase2.NONE) { boolean is_autheap = mEapMethod == Eap.TTLS && mPhase2Method == Phase2.GTC; String prefix = is_autheap ? Phase2.AUTHEAP_PREFIX : Phase2.AUTH_PREFIX; String value = convertToQuotedString(prefix + Phase2.strings[mPhase2Method]); diff --git a/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java b/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java index d8db4ceb6e9c..320c187bbc2d 100644 --- a/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java +++ b/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java @@ -521,4 +521,23 @@ public class WifiEnterpriseConfigTest { // expected exception. } } + + /** Verifies that the EAP inner method is reset when we switch to Unauth-TLS */ + @Test + public void eapPhase2MethodForUnauthTls() { + // Initially select an EAP method that supports an phase2. + mEnterpriseConfig.setEapMethod(Eap.PEAP); + mEnterpriseConfig.setPhase2Method(Phase2.MSCHAPV2); + assertEquals("PEAP", getSupplicantEapMethod()); + assertEquals("\"auth=MSCHAPV2\"", getSupplicantPhase2Method()); + + // Change the EAP method to another type which supports a phase2. + mEnterpriseConfig.setEapMethod(Eap.TTLS); + assertEquals("TTLS", getSupplicantEapMethod()); + assertEquals("\"auth=MSCHAPV2\"", getSupplicantPhase2Method()); + + // Change the EAP method to Unauth-TLS which does not support a phase2. + mEnterpriseConfig.setEapMethod(Eap.UNAUTH_TLS); + assertEquals(null, getSupplicantPhase2Method()); + } } -- cgit v1.2.3 From aa06e85a29b84ee6445cc72c7a261c5dcf0d1f5e Mon Sep 17 00:00:00 2001 From: Quang Luong Date: Thu, 27 Feb 2020 18:00:06 -0800 Subject: Rename setMeteredOverridePasspoint to setPasspointMeteredOverride Renaming as per Android API Council request. Bug: 150204647 Test: build Change-Id: Id6c40eef43ce765fe379af68144d342413d3daa4 --- wifi/java/android/net/wifi/IWifiManager.aidl | 2 +- wifi/java/android/net/wifi/WifiManager.java | 4 ++-- wifi/tests/src/android/net/wifi/WifiManagerTest.java | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 3025caf74000..30a76e463f67 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -97,7 +97,7 @@ interface IWifiManager void setMacRandomizationSettingPasspointEnabled(String fqdn, boolean enable); - void setMeteredOverridePasspoint(String fqdn, int meteredOverride); + void setPasspointMeteredOverride(String fqdn, int meteredOverride); boolean startScan(String packageName, String featureId); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index b1a4cac5864a..b9dc349870ea 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -4429,9 +4429,9 @@ public class WifiManager { */ @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - public void setMeteredOverridePasspoint(@NonNull String fqdn, int meteredOverride) { + public void setPasspointMeteredOverride(@NonNull String fqdn, int meteredOverride) { try { - mService.setMeteredOverridePasspoint(fqdn, meteredOverride); + mService.setPasspointMeteredOverride(fqdn, meteredOverride); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 234d929fc05a..76ac8373374a 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -1803,10 +1803,10 @@ public class WifiManagerTest { * {@link WifiManager#setMacRandomizationSettingPasspointEnabled(String, boolean)} */ @Test - public void testSetMeteredOverridePasspoint() throws Exception { + public void testSetPasspointMeteredOverride() throws Exception { final String fqdn = "FullyQualifiedDomainName"; - mWifiManager.setMeteredOverridePasspoint(fqdn, METERED_OVERRIDE_METERED); - verify(mWifiService).setMeteredOverridePasspoint(fqdn, METERED_OVERRIDE_METERED); + mWifiManager.setPasspointMeteredOverride(fqdn, METERED_OVERRIDE_METERED); + verify(mWifiService).setPasspointMeteredOverride(fqdn, METERED_OVERRIDE_METERED); } /** -- cgit v1.2.3 From 87ca1ac633fa09095cfdb9d9afec68cbfa091184 Mon Sep 17 00:00:00 2001 From: Quang Luong Date: Mon, 2 Mar 2020 15:16:38 -0800 Subject: Add @MeteredOverride annotation to setPasspointMeteredOverride() Bug: 150204647 Test: build Change-Id: Ibd2b3f55bd4340d2fe3e3455d85d2aeb9f4bb085 --- wifi/java/android/net/wifi/WifiManager.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 6487e8390374..a262c92b8b29 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -4430,7 +4430,8 @@ public class WifiManager { */ @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - public void setPasspointMeteredOverride(@NonNull String fqdn, int meteredOverride) { + public void setPasspointMeteredOverride(@NonNull String fqdn, + @WifiConfiguration.MeteredOverride int meteredOverride) { try { mService.setPasspointMeteredOverride(fqdn, meteredOverride); } catch (RemoteException e) { -- cgit v1.2.3 From 758606219f1cd0f90fc9e589d685d6401974df95 Mon Sep 17 00:00:00 2001 From: "Nate(Qiang) Jiang" Date: Mon, 2 Mar 2020 15:34:12 -0800 Subject: Create different KeyId for saved and suggestion network Bug: 150500247 Test: atest android.net.wifi Change-Id: I31ee6f3a3295aca0bd7fcb83ce74327922977797 --- wifi/java/android/net/wifi/WifiConfiguration.java | 13 +++-- .../android/net/wifi/WifiConfigurationTest.java | 61 ++++++++++++++++++++++ 2 files changed, 71 insertions(+), 3 deletions(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 4c4a96277d12..5a7bf4b15f1a 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -2442,16 +2442,23 @@ public class WifiConfiguration implements Parcelable { if (TextUtils.isEmpty(keyMgmt)) { throw new IllegalStateException("Not an EAP network"); } + String keyId = trimStringForKeyId(SSID) + "_" + keyMgmt + "_" + + trimStringForKeyId(enterpriseConfig.getKeyId(current != null + ? current.enterpriseConfig : null)); - return trimStringForKeyId(SSID) + "_" + keyMgmt + "_" + - trimStringForKeyId(enterpriseConfig.getKeyId(current != null ? - current.enterpriseConfig : null)); + if (!fromWifiNetworkSuggestion) { + return keyId; + } + return keyId + "_" + trimStringForKeyId(BSSID) + "_" + trimStringForKeyId(creatorName); } catch (NullPointerException e) { throw new IllegalStateException("Invalid config details"); } } private String trimStringForKeyId(String string) { + if (string == null) { + return ""; + } // Remove quotes and spaces return string.replace("\"", "").replace(" ", ""); } diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java index 00790d5a2d60..047a64b25733 100644 --- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java @@ -252,6 +252,67 @@ public class WifiConfigurationTest { assertTrue(exceptionThrown); } + /** + * Verifies that getKeyIdForCredentials returns the expected string for Suggestion Enterprise + * networks + * @throws Exception + */ + @Test + public void testGetKeyIdForCredentialsForSuggestion() throws Exception { + WifiConfiguration config = new WifiConfiguration(); + final String mSsid = "TestAP"; + final String packageName = "TestApp"; + final String bSsid = MacAddressUtils.createRandomUnicastAddress().toString(); + String suggestionSuffix = "_" + bSsid + "_" + packageName; + config.SSID = mSsid; + config.fromWifiNetworkSuggestion = true; + config.creatorName = packageName; + config.BSSID = bSsid; + + // Test various combinations + // EAP with TLS + config.allowedKeyManagement.set(KeyMgmt.WPA_EAP); + config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); + config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE); + String keyId = config.getKeyIdForCredentials(config); + assertEquals(keyId, mSsid + "_WPA_EAP_TLS_NULL" + suggestionSuffix); + + // EAP with TTLS & MSCHAPv2 + config.allowedKeyManagement.set(KeyMgmt.WPA_EAP); + config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS); + config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.MSCHAPV2); + keyId = config.getKeyIdForCredentials(config); + assertEquals(keyId, mSsid + "_WPA_EAP_TTLS_MSCHAPV2" + suggestionSuffix); + + // Suite-B 192 with PWD & GTC + config.allowedKeyManagement.clear(); + config.allowedKeyManagement.set(KeyMgmt.SUITE_B_192); + config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.PWD); + config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC); + keyId = config.getKeyIdForCredentials(config); + assertEquals(keyId, mSsid + "_SUITE_B_192_PWD_GTC" + suggestionSuffix); + + // IEEE8021X with SIM + config.allowedKeyManagement.clear(); + config.allowedKeyManagement.set(KeyMgmt.IEEE8021X); + config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.SIM); + config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE); + keyId = config.getKeyIdForCredentials(config); + assertEquals(keyId, mSsid + "_IEEE8021X_SIM_NULL" + suggestionSuffix); + + // Try calling this method with non-Enterprise network, expect an exception + boolean exceptionThrown = false; + try { + config.allowedKeyManagement.clear(); + config.allowedKeyManagement.set(KeyMgmt.WPA2_PSK); + config.preSharedKey = "TestPsk"; + keyId = config.getKeyIdForCredentials(config); + } catch (IllegalStateException e) { + exceptionThrown = true; + } + assertTrue(exceptionThrown); + } + /** * Verifies that getSsidAndSecurityTypeString returns the correct String for networks of * various different security types -- cgit v1.2.3 From 229e2881942a791a99721dda56ceb549519f9f08 Mon Sep 17 00:00:00 2001 From: David Su Date: Tue, 3 Mar 2020 15:25:23 -0800 Subject: WifiManager#getCountryCode: clarify doc on return format Bug: 150236894 Test: compiles Change-Id: I21244da2620ddc55579c31c92465359c22d4927b --- wifi/java/android/net/wifi/WifiManager.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index a262c92b8b29..c46cd11f7aae 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -2820,7 +2820,8 @@ public class WifiManager { /** * Get the country code. - * @return the country code in ISO 3166 format, or null if there is no country code configured. + * @return the country code in ISO 3166 alpha-2 (2-letter) uppercase format, or null if + * there is no country code configured. * @hide */ @Nullable -- cgit v1.2.3 From 426ddac2fc31c4973082c06324eda2338289192d Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Thu, 5 Mar 2020 11:34:55 -0800 Subject: [DPP] Update javadoc for onFailure callback Following up on API council feedback, update the javadoc for the onFailure callback to explain the format of the channelListArray sparse array. Bug: 150685275 Test: No code changes. Change-Id: I68e1cce89fa9dc50b79b41e2ca4e6d42a36d8aa2 --- wifi/java/android/net/wifi/EasyConnectStatusCallback.java | 2 ++ 1 file changed, 2 insertions(+) (limited to 'wifi') diff --git a/wifi/java/android/net/wifi/EasyConnectStatusCallback.java b/wifi/java/android/net/wifi/EasyConnectStatusCallback.java index 8ccf0076f0b0..de2f5d9a3fe4 100644 --- a/wifi/java/android/net/wifi/EasyConnectStatusCallback.java +++ b/wifi/java/android/net/wifi/EasyConnectStatusCallback.java @@ -242,6 +242,8 @@ public abstract class EasyConnectStatusCallback { * 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. + * The sparse array key is the Global Operating class, and the value + * is an integer array of Wi-Fi channels. * @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. -- cgit v1.2.3 From 6df01e928d0ed87f0aef771c2557e8e9c0315cbb Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 5 Mar 2020 13:12:39 -0800 Subject: MTS: only run FrameworksWifiApiTest if Wifi module is installed Bug: 150650681 Test: m mts && mts-tradefed run mts-wifi Change-Id: I3a3baeccfb6b9a385e01553b7eb483aedb55b958 --- wifi/tests/AndroidTest.xml | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'wifi') diff --git a/wifi/tests/AndroidTest.xml b/wifi/tests/AndroidTest.xml index 987fee79fefd..34e2e3af9cda 100644 --- a/wifi/tests/AndroidTest.xml +++ b/wifi/tests/AndroidTest.xml @@ -25,4 +25,10 @@