Add hostside CTS tests for SoftApConfig redaction
Add hostside CTS tests to test for SoftApConfiguration being redacted from TetheringInterface for apps that don't own that config. Bug: 216524590 Test: atest CtsHostsideNetworkTests Change-Id: I823c8e94cc6fe10c6118e7a694da368e585bbd69
This commit is contained in:
parent
a66b78ab87
commit
b5b82cc424
7 changed files with 325 additions and 2 deletions
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -42,6 +42,8 @@
|
|||
android:debuggable="true">
|
||||
<service android:name=".RemoteSocketFactoryService"
|
||||
android:exported="true"/>
|
||||
<service android:name=".TetheringHelperService"
|
||||
android:exported="true"/>
|
||||
</application>
|
||||
|
||||
<!--
|
||||
|
|
|
|||
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* 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.app2;
|
||||
|
||||
|
||||
import static android.net.TetheringManager.TETHERING_WIFI;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.net.TetheringInterface;
|
||||
import android.net.TetheringManager;
|
||||
import android.os.IBinder;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.cts.net.hostside.ITetheringHelper;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class TetheringHelperService extends Service {
|
||||
private static final String TAG = TetheringHelperService.class.getSimpleName();
|
||||
|
||||
private ITetheringHelper.Stub mBinder = new ITetheringHelper.Stub() {
|
||||
public TetheringInterface getTetheredWifiInterface() {
|
||||
ArrayBlockingQueue<TetheringInterface> queue = new ArrayBlockingQueue<>(1);
|
||||
TetheringManager.TetheringEventCallback callback =
|
||||
new TetheringManager.TetheringEventCallback() {
|
||||
@Override
|
||||
public void onTetheredInterfacesChanged(
|
||||
@NonNull Set<TetheringInterface> interfaces) {
|
||||
for (TetheringInterface iface : interfaces) {
|
||||
if (iface.getType() == TETHERING_WIFI) {
|
||||
queue.offer(iface);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
TetheringManager tm =
|
||||
TetheringHelperService.this.getSystemService(TetheringManager.class);
|
||||
tm.registerTetheringEventCallback(Runnable::run, callback);
|
||||
TetheringInterface iface;
|
||||
try {
|
||||
iface = queue.poll(5, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
throw new IllegalStateException("Wait for wifi TetheredInterface interrupted");
|
||||
} finally {
|
||||
tm.unregisterTetheringEventCallback(callback);
|
||||
}
|
||||
if (iface == null) {
|
||||
throw new IllegalStateException(
|
||||
"No wifi TetheredInterface received after 5 seconds");
|
||||
}
|
||||
return iface;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return mBinder;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import com.android.tradefed.device.DeviceNotAvailableException;
|
||||
import com.android.tradefed.invoker.TestInformation;
|
||||
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
|
||||
import com.android.tradefed.testtype.junit4.AfterClassWithInfo;
|
||||
import com.android.tradefed.testtype.junit4.BeforeClassWithInfo;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(DeviceJUnit4ClassRunner.class)
|
||||
public class HostsideTetheringTests extends HostsideNetworkTestCase {
|
||||
/**
|
||||
* Set up the test once before running all the tests.
|
||||
*/
|
||||
@BeforeClassWithInfo
|
||||
public static void setUpOnce(TestInformation testInfo) throws Exception {
|
||||
uninstallPackage(testInfo, TEST_APP2_PKG, false);
|
||||
installPackage(testInfo, TEST_APP2_APK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tear down the test once after running all the tests.
|
||||
*/
|
||||
@AfterClassWithInfo
|
||||
public static void tearDownOnce(TestInformation testInfo)
|
||||
throws DeviceNotAvailableException {
|
||||
uninstallPackage(testInfo, TEST_APP2_PKG, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSoftApConfigurationRedactedForOtherApps() throws Exception {
|
||||
runDeviceTests(TEST_PKG, TEST_PKG + ".TetheringTest",
|
||||
"testSoftApConfigurationRedactedForOtherUids");
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue