diff --git a/tests/cts/hostside/aidl/Android.bp b/tests/cts/hostside/aidl/Android.bp index 31924f08e5..ca3e77f128 100644 --- a/tests/cts/hostside/aidl/Android.bp +++ b/tests/cts/hostside/aidl/Android.bp @@ -19,8 +19,7 @@ package { java_test_helper_library { name: "CtsHostsideNetworkTestsAidl", - sdk_version: "current", - min_sdk_version: "30", + sdk_version: "system_current", srcs: [ "com/android/cts/net/hostside/*.aidl", "com/android/cts/net/hostside/*.java", diff --git a/tests/cts/hostside/aidl/com/android/cts/net/hostside/ITetheringHelper.aidl b/tests/cts/hostside/aidl/com/android/cts/net/hostside/ITetheringHelper.aidl new file mode 100644 index 0000000000..a9f5ed4b46 --- /dev/null +++ b/tests/cts/hostside/aidl/com/android/cts/net/hostside/ITetheringHelper.aidl @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2024 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 com.android.cts.net.hostside; + +import android.net.TetheringInterface; + +interface ITetheringHelper { + TetheringInterface getTetheredWifiInterface(); +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/TetheringHelperClient.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/TetheringHelperClient.java new file mode 100644 index 0000000000..5f5ebb093f --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/TetheringHelperClient.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2024 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 com.android.cts.net.hostside; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.net.TetheringInterface; +import android.os.ConditionVariable; +import android.os.IBinder; +import android.os.RemoteException; + +public class TetheringHelperClient { + private static final int TIMEOUT_MS = 5000; + private static final String PACKAGE = TetheringHelperClient.class.getPackage().getName(); + private static final String APP2_PACKAGE = PACKAGE + ".app2"; + private static final String SERVICE_NAME = APP2_PACKAGE + ".TetheringHelperService"; + + private Context mContext; + private ServiceConnection mServiceConnection; + private ITetheringHelper mService; + + public TetheringHelperClient(Context context) { + mContext = context; + } + + /** + * Binds to TetheringHelperService. + */ + public void bind() { + if (mService != null) { + throw new IllegalStateException("Already bound"); + } + + final ConditionVariable cv = new ConditionVariable(); + mServiceConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + mService = ITetheringHelper.Stub.asInterface(service); + cv.open(); + } + @Override + public void onServiceDisconnected(ComponentName name) { + mService = null; + } + }; + + final Intent intent = new Intent(); + intent.setComponent(new ComponentName(APP2_PACKAGE, SERVICE_NAME)); + mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE); + cv.block(TIMEOUT_MS); + if (mService == null) { + throw new IllegalStateException( + "Could not bind to TetheringHelperService after " + TIMEOUT_MS + "ms"); + } + } + + /** + * Unbinds from TetheringHelperService. + */ + public void unbind() { + if (mService != null) { + mContext.unbindService(mServiceConnection); + } + } + + /** + * Returns the tethered Wifi interface as seen from TetheringHelperService. + */ + public TetheringInterface getTetheredWifiInterface() throws RemoteException { + return mService.getTetheredWifiInterface(); + } +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/TetheringTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/TetheringTest.java new file mode 100644 index 0000000000..ad98a29938 --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/TetheringTest.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2024 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 com.android.cts.net.hostside; + +import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import android.content.Context; +import android.net.TetheringInterface; +import android.net.cts.util.CtsTetheringUtils; +import android.net.wifi.SoftApConfiguration; +import android.net.wifi.WifiSsid; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.nio.charset.StandardCharsets; + +public class TetheringTest { + private CtsTetheringUtils mCtsTetheringUtils; + private TetheringHelperClient mTetheringHelperClient; + + @Before + public void setUp() throws Exception { + Context targetContext = getInstrumentation().getTargetContext(); + mCtsTetheringUtils = new CtsTetheringUtils(targetContext); + mTetheringHelperClient = new TetheringHelperClient(targetContext); + mTetheringHelperClient.bind(); + } + + @After + public void tearDown() throws Exception { + mTetheringHelperClient.unbind(); + } + + /** + * Starts Wifi tethering and tests that the SoftApConfiguration is redacted from + * TetheringEventCallback for other apps. + */ + @Test + public void testSoftApConfigurationRedactedForOtherUids() throws Exception { + final CtsTetheringUtils.TestTetheringEventCallback tetherEventCallback = + mCtsTetheringUtils.registerTetheringEventCallback(); + SoftApConfiguration softApConfig = new SoftApConfiguration.Builder() + .setWifiSsid(WifiSsid.fromBytes("This is an SSID!" + .getBytes(StandardCharsets.UTF_8))).build(); + final TetheringInterface tetheringInterface = + mCtsTetheringUtils.startWifiTethering(tetherEventCallback, softApConfig); + assertNotNull(tetheringInterface); + assertEquals(softApConfig, tetheringInterface.getSoftApConfiguration()); + try { + TetheringInterface tetheringInterfaceForApp2 = + mTetheringHelperClient.getTetheredWifiInterface(); + assertNotNull(tetheringInterfaceForApp2); + assertNull(tetheringInterfaceForApp2.getSoftApConfiguration()); + assertEquals( + tetheringInterface.getInterface(), tetheringInterfaceForApp2.getInterface()); + } finally { + mCtsTetheringUtils.stopWifiTethering(tetherEventCallback); + } + } +} diff --git a/tests/cts/hostside/app2/AndroidManifest.xml b/tests/cts/hostside/app2/AndroidManifest.xml index 412b307511..6ccaf4f2e6 100644 --- a/tests/cts/hostside/app2/AndroidManifest.xml +++ b/tests/cts/hostside/app2/AndroidManifest.xml @@ -42,6 +42,8 @@ android:debuggable="true"> +