Add DO app bypass for start/stopTethering
Allow DO apps to call startTethering and stopTethering for wifi tethering with a non-null SoftApConfiguration. Bug: 295979433 Test: atest TetheringTests CtsTetheringTests Change-Id: Ie5836e9e30afb2df1de0640645d696e185aa2191
This commit is contained in:
parent
0613620f40
commit
3f22173b75
5 changed files with 440 additions and 76 deletions
|
|
@ -22,6 +22,7 @@ import static android.Manifest.permission.NETWORK_STACK;
|
|||
import static android.Manifest.permission.TETHER_PRIVILEGED;
|
||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
|
||||
import static android.net.TetheringManager.TETHERING_WIFI;
|
||||
import static android.net.TetheringManager.TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION;
|
||||
import static android.net.TetheringManager.TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION;
|
||||
import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
|
||||
|
|
@ -58,6 +59,7 @@ import androidx.annotation.Nullable;
|
|||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.networkstack.apishim.SettingsShimImpl;
|
||||
import com.android.networkstack.apishim.common.SettingsShim;
|
||||
import com.android.networkstack.tethering.util.TetheringPermissionsUtils;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
|
|
@ -72,6 +74,7 @@ public class TetheringService extends Service {
|
|||
|
||||
private TetheringConnector mConnector;
|
||||
private SettingsShim mSettingsShim;
|
||||
private TetheringPermissionsUtils mTetheringPermissionsUtils;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
|
|
@ -81,6 +84,7 @@ public class TetheringService extends Service {
|
|||
mConnector = new TetheringConnector(makeTethering(deps), TetheringService.this);
|
||||
|
||||
mSettingsShim = SettingsShimImpl.newInstance();
|
||||
mTetheringPermissionsUtils = new TetheringPermissionsUtils(deps.getContext());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -109,7 +113,11 @@ public class TetheringService extends Service {
|
|||
@Override
|
||||
public void tether(String iface, String callerPkg, String callingAttributionTag,
|
||||
IIntResultListener listener) {
|
||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return;
|
||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag,
|
||||
false /* onlyAllowPrivileged */, false /* isDeviceOwnerAppAllowed */,
|
||||
listener)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mTethering.legacyTether(iface, listener);
|
||||
}
|
||||
|
|
@ -117,7 +125,11 @@ public class TetheringService extends Service {
|
|||
@Override
|
||||
public void untether(String iface, String callerPkg, String callingAttributionTag,
|
||||
IIntResultListener listener) {
|
||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return;
|
||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag,
|
||||
false /* onlyAllowPrivileged */, false /* isDeviceOwnerAppAllowed */,
|
||||
listener)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mTethering.legacyUntether(iface, listener);
|
||||
}
|
||||
|
|
@ -125,32 +137,45 @@ public class TetheringService extends Service {
|
|||
@Override
|
||||
public void setUsbTethering(boolean enable, String callerPkg, String callingAttributionTag,
|
||||
IIntResultListener listener) {
|
||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return;
|
||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag,
|
||||
false /* onlyAllowPrivileged */, false /* isDeviceOwnerAppAllowed */,
|
||||
listener)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mTethering.setUsbTethering(enable, listener);
|
||||
}
|
||||
|
||||
private boolean isRequestAllowedForDeviceOwner(@NonNull TetheringRequest request) {
|
||||
return request.getTetheringType() == TETHERING_WIFI
|
||||
&& request.getSoftApConfiguration() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startTethering(TetheringRequestParcel request, String callerPkg,
|
||||
public void startTethering(TetheringRequestParcel requestParcel, String callerPkg,
|
||||
String callingAttributionTag, IIntResultListener listener) {
|
||||
boolean onlyAllowPrivileged = request.exemptFromEntitlementCheck
|
||||
|| request.interfaceName != null;
|
||||
if (checkAndNotifyCommonError(callerPkg,
|
||||
callingAttributionTag,
|
||||
onlyAllowPrivileged,
|
||||
listener)) {
|
||||
TetheringRequest request = new TetheringRequest(requestParcel);
|
||||
request.setUid(getBinderCallingUid());
|
||||
request.setPackageName(callerPkg);
|
||||
boolean onlyAllowPrivileged = request.isExemptFromEntitlementCheck()
|
||||
|| request.getInterfaceName() != null;
|
||||
boolean isDeviceOwnerAllowed = mTethering.isTetheringWithSoftApConfigEnabled()
|
||||
&& isRequestAllowedForDeviceOwner(request);
|
||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, onlyAllowPrivileged,
|
||||
isDeviceOwnerAllowed, listener)) {
|
||||
return;
|
||||
}
|
||||
TetheringRequest external = new TetheringRequest(request);
|
||||
external.setUid(getBinderCallingUid());
|
||||
external.setPackageName(callerPkg);
|
||||
mTethering.startTethering(external, callerPkg, listener);
|
||||
mTethering.startTethering(request, callerPkg, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopTethering(int type, String callerPkg, String callingAttributionTag,
|
||||
IIntResultListener listener) {
|
||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return;
|
||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag,
|
||||
false /* onlyAllowPrivileged */, false /* isDeviceOwnerAppAllowed */,
|
||||
listener)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
mTethering.stopTethering(type);
|
||||
|
|
@ -164,9 +189,16 @@ public class TetheringService extends Service {
|
|||
IIntResultListener listener) {
|
||||
if (request == null) return;
|
||||
if (listener == null) return;
|
||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return;
|
||||
request.setUid(getBinderCallingUid());
|
||||
request.setPackageName(callerPkg);
|
||||
boolean isDeviceOwnerAllowed = mTethering.isTetheringWithSoftApConfigEnabled()
|
||||
&& isRequestAllowedForDeviceOwner(request);
|
||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag,
|
||||
false /* onlyAllowPrivileged */, isDeviceOwnerAllowed, listener)) {
|
||||
return;
|
||||
}
|
||||
// Note: Whether tethering is actually stopped or not will depend on whether the request
|
||||
// matches an active one with the same UID (see RequestTracker#findFuzzyMatchedRequest).
|
||||
mTethering.stopTetheringRequest(request, listener);
|
||||
}
|
||||
|
||||
|
|
@ -187,7 +219,11 @@ public class TetheringService extends Service {
|
|||
+ " internal-only listener");
|
||||
}
|
||||
};
|
||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return;
|
||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag,
|
||||
false /* onlyAllowPrivileged */, false /* isDeviceOwnerAppAllowed */,
|
||||
listener)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mTethering.requestLatestTetheringEntitlementResult(type, receiver, showEntitlementUi);
|
||||
}
|
||||
|
|
@ -223,7 +259,11 @@ public class TetheringService extends Service {
|
|||
@Override
|
||||
public void stopAllTethering(String callerPkg, String callingAttributionTag,
|
||||
IIntResultListener listener) {
|
||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return;
|
||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag,
|
||||
false /* onlyAllowPrivileged */, false /* isDeviceOwnerAppAllowed */,
|
||||
listener)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
mTethering.stopAllTethering();
|
||||
|
|
@ -234,8 +274,11 @@ public class TetheringService extends Service {
|
|||
@Override
|
||||
public void isTetheringSupported(String callerPkg, String callingAttributionTag,
|
||||
IIntResultListener listener) {
|
||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return;
|
||||
|
||||
boolean isDeviceOwnerAppAllowed = mTethering.isTetheringWithSoftApConfigEnabled();
|
||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag,
|
||||
false /* onlyAllowPrivileged */, isDeviceOwnerAppAllowed, listener)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
listener.onResult(TETHER_ERROR_NO_ERROR);
|
||||
} catch (RemoteException e) { }
|
||||
|
|
@ -259,24 +302,18 @@ public class TetheringService extends Service {
|
|||
mTethering.dump(fd, writer, args);
|
||||
}
|
||||
|
||||
private boolean checkAndNotifyCommonError(final String callerPkg,
|
||||
final String callingAttributionTag, final IIntResultListener listener) {
|
||||
return checkAndNotifyCommonError(callerPkg, callingAttributionTag,
|
||||
false /* onlyAllowPrivileged */, listener);
|
||||
}
|
||||
|
||||
private boolean checkAndNotifyCommonError(final String callerPkg,
|
||||
final String callingAttributionTag, final boolean onlyAllowPrivileged,
|
||||
final IIntResultListener listener) {
|
||||
final boolean isDeviceOwnerAppAllowed, final IIntResultListener listener) {
|
||||
try {
|
||||
if (!checkPackageNameMatchesUid(getBinderCallingUid(), callerPkg)) {
|
||||
Log.e(TAG, "Package name " + callerPkg + " does not match UID "
|
||||
+ getBinderCallingUid());
|
||||
final int uid = getBinderCallingUid();
|
||||
if (!checkPackageNameMatchesUid(uid, callerPkg)) {
|
||||
Log.e(TAG, "Package name " + callerPkg + " does not match UID " + uid);
|
||||
listener.onResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||
return true;
|
||||
}
|
||||
if (!hasTetherChangePermission(callerPkg, callingAttributionTag,
|
||||
onlyAllowPrivileged)) {
|
||||
if (!hasTetherChangePermission(uid, callerPkg, callingAttributionTag,
|
||||
onlyAllowPrivileged, isDeviceOwnerAppAllowed)) {
|
||||
listener.onResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -308,21 +345,25 @@ public class TetheringService extends Service {
|
|||
return mService.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED;
|
||||
}
|
||||
|
||||
private boolean hasTetherChangePermission(final String callerPkg,
|
||||
final String callingAttributionTag, final boolean onlyAllowPrivileged) {
|
||||
private boolean hasTetherChangePermission(final int uid, final String callerPkg,
|
||||
final String callingAttributionTag, final boolean onlyAllowPrivileged,
|
||||
final boolean isDeviceOwnerAppAllowed) {
|
||||
if (onlyAllowPrivileged && !hasNetworkStackPermission()
|
||||
&& !hasNetworkSettingsPermission()) return false;
|
||||
|
||||
if (hasTetherPrivilegedPermission()) return true;
|
||||
|
||||
// Allow DO apps to change tethering even if they don't have TETHER_PRIVILEGED.
|
||||
if (isDeviceOwnerAppAllowed && mService.isDeviceOwner(uid, callerPkg)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// After TetheringManager moves to public API, prevent third-party apps from being able
|
||||
// to change tethering with only WRITE_SETTINGS permission.
|
||||
if (mTethering.isTetheringWithSoftApConfigEnabled()) return false;
|
||||
|
||||
if (mTethering.isTetherProvisioningRequired()) return false;
|
||||
|
||||
int uid = getBinderCallingUid();
|
||||
|
||||
// If callerPkg's uid is not same as getBinderCallingUid(),
|
||||
// checkAndNoteWriteSettingsOperation will return false and the operation will be
|
||||
// denied.
|
||||
|
|
@ -386,6 +427,14 @@ public class TetheringService extends Service {
|
|||
return Binder.getCallingUid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for {@link TetheringPermissionsUtils#isDeviceOwner(int, String)}, used for mocks.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
boolean isDeviceOwner(final int uid, final String callerPkg) {
|
||||
return mTetheringPermissionsUtils.isDeviceOwner(uid, callerPkg);
|
||||
}
|
||||
|
||||
/**
|
||||
* An injection method for testing.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (C) 2025 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.networkstack.tethering.util;
|
||||
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
/**
|
||||
* Utils class for checking permissions related to Tethering APIs.
|
||||
*/
|
||||
public class TetheringPermissionsUtils {
|
||||
private static final String TAG = "TetherPermUtils";
|
||||
|
||||
@NonNull private final Context mContext;
|
||||
|
||||
public TetheringPermissionsUtils(@NonNull Context context) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the package name is a Device Owner.
|
||||
*/
|
||||
public boolean isDeviceOwner(final int uid, @NonNull final String packageName) {
|
||||
Context userContext;
|
||||
try {
|
||||
// There is no safe way to invoke this method since tethering package might not be
|
||||
// installed for a certain user on the OEM devices, refer to b/382628161.
|
||||
userContext = mContext.createContextAsUser(UserHandle.getUserHandleForUid(uid),
|
||||
0 /* flags */);
|
||||
} catch (IllegalStateException e) {
|
||||
// TODO: Add a terrible error metric for this case.
|
||||
Log.e(TAG, "createContextAsUser failed, skipping Device Owner check", e);
|
||||
return false;
|
||||
}
|
||||
DevicePolicyManager devicePolicyManager =
|
||||
retrieveDevicePolicyManagerFromContext(userContext);
|
||||
if (devicePolicyManager == null) return false;
|
||||
return devicePolicyManager.isDeviceOwnerApp(packageName);
|
||||
}
|
||||
|
||||
private DevicePolicyManager retrieveDevicePolicyManagerFromContext(
|
||||
@NonNull final Context context) {
|
||||
DevicePolicyManager devicePolicyManager =
|
||||
context.getSystemService(DevicePolicyManager.class);
|
||||
if (devicePolicyManager == null
|
||||
&& context.getPackageManager().hasSystemFeature(
|
||||
PackageManager.FEATURE_DEVICE_ADMIN)) {
|
||||
Log.w(TAG, "Error retrieving DPM service");
|
||||
}
|
||||
return devicePolicyManager;
|
||||
}
|
||||
}
|
||||
|
|
@ -25,14 +25,18 @@ import android.content.Intent;
|
|||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class MockTetheringService extends TetheringService {
|
||||
private final Tethering mTethering = mock(Tethering.class);
|
||||
private final ArrayMap<String, Integer> mMockedPermissions = new ArrayMap<>();
|
||||
private final ArrayMap<String, Integer> mMockedPackageUids = new ArrayMap<>();
|
||||
private final Set<String> mMockedDeviceOwnerPackages = new ArraySet<>();
|
||||
private int mMockCallingUid;
|
||||
|
||||
@Override
|
||||
|
|
@ -74,6 +78,11 @@ public class MockTetheringService extends TetheringService {
|
|||
return mMockCallingUid;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isDeviceOwner(final int uid, final String callerPkg) {
|
||||
return mMockedDeviceOwnerPackages.contains(callerPkg);
|
||||
}
|
||||
|
||||
public Tethering getTethering() {
|
||||
return mTethering;
|
||||
}
|
||||
|
|
@ -118,5 +127,19 @@ public class MockTetheringService extends TetheringService {
|
|||
public void setCallingUid(int uid) {
|
||||
mMockCallingUid = uid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a mocked carrier privileges package
|
||||
*/
|
||||
public void addDeviceOwnerPackage(final String packageName) {
|
||||
mMockedDeviceOwnerPackages.add(packageName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a mocked carrier privileges package
|
||||
*/
|
||||
public void removeDeviceOwnerPackage(final String packageName) {
|
||||
mMockedDeviceOwnerPackages.remove(packageName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import static android.Manifest.permission.NETWORK_SETTINGS;
|
|||
import static android.Manifest.permission.TETHER_PRIVILEGED;
|
||||
import static android.Manifest.permission.WRITE_SETTINGS;
|
||||
import static android.content.pm.PackageManager.PERMISSION_DENIED;
|
||||
import static android.net.TetheringManager.TETHERING_USB;
|
||||
import static android.net.TetheringManager.TETHERING_VIRTUAL;
|
||||
import static android.net.TetheringManager.TETHERING_WIFI;
|
||||
import static android.net.TetheringManager.TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION;
|
||||
|
|
@ -36,6 +37,7 @@ import static org.mockito.ArgumentMatchers.any;
|
|||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.anyInt;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.never;
|
||||
|
|
@ -53,6 +55,7 @@ import android.net.ITetheringEventCallback;
|
|||
import android.net.TetheringManager;
|
||||
import android.net.TetheringManager.TetheringRequest;
|
||||
import android.net.TetheringRequestParcel;
|
||||
import android.net.wifi.SoftApConfiguration;
|
||||
import android.os.Bundle;
|
||||
import android.os.ConditionVariable;
|
||||
import android.os.Handler;
|
||||
|
|
@ -153,43 +156,58 @@ public final class TetheringServiceTest {
|
|||
}
|
||||
|
||||
private void runAsNoPermission(final TestTetheringCall test) throws Exception {
|
||||
runTetheringCall(test, true /* isTetheringAllowed */, false /* isWriteSettingsAllowed */,
|
||||
new String[0]);
|
||||
runTetheringCall(test, true /* isTetheringAllowed */,
|
||||
true /* isTetheringWithSoftApConfigEnabled */, new String[0]);
|
||||
}
|
||||
|
||||
private void runAsTetherPrivileged(final TestTetheringCall test) throws Exception {
|
||||
runTetheringCall(test, true /* isTetheringAllowed */, false /* isWriteSettingsAllowed */,
|
||||
TETHER_PRIVILEGED);
|
||||
runTetheringCall(test, true /* isTetheringAllowed */,
|
||||
true /* isTetheringWithSoftApConfigEnabled */, TETHER_PRIVILEGED);
|
||||
}
|
||||
|
||||
private void runAsAccessNetworkState(final TestTetheringCall test) throws Exception {
|
||||
runTetheringCall(test, true /* isTetheringAllowed */, false /* isWriteSettingsAllowed */,
|
||||
ACCESS_NETWORK_STATE);
|
||||
runTetheringCall(test, true /* isTetheringAllowed */,
|
||||
true /* isTetheringWithSoftApConfigEnabled */, ACCESS_NETWORK_STATE);
|
||||
}
|
||||
|
||||
private void runAsWriteSettings(final TestTetheringCall test) throws Exception {
|
||||
runTetheringCall(test, true /* isTetheringAllowed */, false /* isWriteSettingsAllowed */,
|
||||
WRITE_SETTINGS);
|
||||
runTetheringCall(test, true /* isTetheringAllowed */,
|
||||
true /* isTetheringWithSoftApConfigEnabled */, WRITE_SETTINGS);
|
||||
}
|
||||
|
||||
private void runAsWriteSettingsWhenWriteSettingsAllowed(
|
||||
final TestTetheringCall test) throws Exception {
|
||||
runTetheringCall(test, true /* isTetheringAllowed */, true /* isWriteSettingsAllowed */,
|
||||
WRITE_SETTINGS);
|
||||
runTetheringCall(test, true /* isTetheringAllowed */,
|
||||
false /* isTetheringWithSoftApConfigEnabled */, WRITE_SETTINGS);
|
||||
}
|
||||
|
||||
private void runAsTetheringDisallowed(final TestTetheringCall test) throws Exception {
|
||||
runTetheringCall(test, false /* isTetheringAllowed */, false /* isWriteSettingsAllowed */,
|
||||
TETHER_PRIVILEGED);
|
||||
runTetheringCall(test, false /* isTetheringAllowed */,
|
||||
true /* isTetheringWithSoftApConfigEnabled */, TETHER_PRIVILEGED);
|
||||
}
|
||||
|
||||
private void runAsNetworkSettings(final TestTetheringCall test) throws Exception {
|
||||
runTetheringCall(test, true /* isTetheringAllowed */, false /* isWriteSettingsAllowed */,
|
||||
NETWORK_SETTINGS, TETHER_PRIVILEGED);
|
||||
runTetheringCall(test, true /* isTetheringAllowed */,
|
||||
true /* isTetheringWithSoftApConfigEnabled */, NETWORK_SETTINGS, TETHER_PRIVILEGED);
|
||||
}
|
||||
|
||||
private void runAsDeviceOwner(final TestTetheringCall test) throws Exception {
|
||||
mMockConnector.addDeviceOwnerPackage(TEST_CALLER_PKG);
|
||||
runTetheringCall(test, true /* isTetheringAllowed */,
|
||||
true /* isTetheringWithSoftApConfigEnabled */, new String[0]);
|
||||
mMockConnector.removeDeviceOwnerPackage(TEST_CALLER_PKG);
|
||||
}
|
||||
|
||||
private void runAsDeviceOwnerWhenDeviceOwnerBypassNotEnabled(final TestTetheringCall test)
|
||||
throws Exception {
|
||||
mMockConnector.addDeviceOwnerPackage(TEST_CALLER_PKG);
|
||||
runTetheringCall(test, true /* isTetheringAllowed */,
|
||||
false /* isTetheringWithSoftApConfigEnabled */, new String[0]);
|
||||
mMockConnector.removeDeviceOwnerPackage(TEST_CALLER_PKG);
|
||||
}
|
||||
|
||||
private void runTetheringCall(final TestTetheringCall test, boolean isTetheringAllowed,
|
||||
boolean isWriteSettingsAllowed, String... permissions) throws Exception {
|
||||
boolean isTetheringWithSoftApConfigEnabled, String... permissions) throws Exception {
|
||||
// Allow the test to run even if ACCESS_NETWORK_STATE was granted at the APK level
|
||||
if (!CollectionUtils.contains(permissions, ACCESS_NETWORK_STATE)) {
|
||||
mMockConnector.setPermission(ACCESS_NETWORK_STATE, PERMISSION_DENIED);
|
||||
|
|
@ -200,7 +218,7 @@ public final class TetheringServiceTest {
|
|||
when(mTethering.isTetheringSupported()).thenReturn(true);
|
||||
when(mTethering.isTetheringAllowed()).thenReturn(isTetheringAllowed);
|
||||
when(mTethering.isTetheringWithSoftApConfigEnabled())
|
||||
.thenReturn(!isWriteSettingsAllowed);
|
||||
.thenReturn(isTetheringWithSoftApConfigEnabled);
|
||||
test.runTetheringCall(new TestTetheringResult());
|
||||
} finally {
|
||||
mUiAutomation.dropShellPermissionIdentity();
|
||||
|
|
@ -226,7 +244,7 @@ public final class TetheringServiceTest {
|
|||
runAsNoPermission((result) -> {
|
||||
mTetheringConnector.tether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||
result);
|
||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
});
|
||||
|
|
@ -239,14 +257,14 @@ public final class TetheringServiceTest {
|
|||
runAsWriteSettings((result) -> {
|
||||
mTetheringConnector.tether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||
result);
|
||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
});
|
||||
|
||||
runAsWriteSettingsWhenWriteSettingsAllowed((result) -> {
|
||||
runTether(result);
|
||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering).isTetherProvisioningRequired();
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
});
|
||||
|
|
@ -274,7 +292,7 @@ public final class TetheringServiceTest {
|
|||
runAsNoPermission((result) -> {
|
||||
mTetheringConnector.untether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||
result);
|
||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
});
|
||||
|
|
@ -287,14 +305,14 @@ public final class TetheringServiceTest {
|
|||
runAsWriteSettings((result) -> {
|
||||
mTetheringConnector.untether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||
result);
|
||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
});
|
||||
|
||||
runAsWriteSettingsWhenWriteSettingsAllowed((result) -> {
|
||||
runUnTether(result);
|
||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering).isTetherProvisioningRequired();
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
});
|
||||
|
|
@ -328,7 +346,7 @@ public final class TetheringServiceTest {
|
|||
runAsNoPermission((result) -> {
|
||||
mTetheringConnector.setUsbTethering(true /* enable */, TEST_CALLER_PKG,
|
||||
TEST_ATTRIBUTION_TAG, result);
|
||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
});
|
||||
|
|
@ -341,14 +359,14 @@ public final class TetheringServiceTest {
|
|||
runAsWriteSettings((result) -> {
|
||||
mTetheringConnector.setUsbTethering(true /* enable */, TEST_CALLER_PKG,
|
||||
TEST_ATTRIBUTION_TAG, result);
|
||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
});
|
||||
|
||||
runAsWriteSettingsWhenWriteSettingsAllowed((result) -> {
|
||||
runSetUsbTethering(result);
|
||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering).isTetherProvisioningRequired();
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
});
|
||||
|
|
@ -367,6 +385,7 @@ public final class TetheringServiceTest {
|
|||
final TetheringRequestParcel request) throws Exception {
|
||||
mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||
result);
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering).isTetheringSupported();
|
||||
verify(mTethering).isTetheringAllowed();
|
||||
verify(mTethering).startTethering(
|
||||
|
|
@ -381,14 +400,61 @@ public final class TetheringServiceTest {
|
|||
runAsNoPermission((result) -> {
|
||||
mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||
result);
|
||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
});
|
||||
|
||||
// Not a Wifi request - Fail
|
||||
runAsDeviceOwner((result) -> {
|
||||
final TetheringRequestParcel notWifi = new TetheringRequestParcel();
|
||||
notWifi.tetheringType = TETHERING_USB;
|
||||
mTetheringConnector.startTethering(notWifi, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||
result);
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
});
|
||||
|
||||
// Request has no SoftApConfiguration - Fail
|
||||
runAsDeviceOwner((result) -> {
|
||||
final TetheringRequestParcel noConfig = new TetheringRequestParcel();
|
||||
noConfig.tetheringType = TETHERING_WIFI;
|
||||
mTetheringConnector.startTethering(noConfig, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||
result);
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
});
|
||||
|
||||
// Wifi request with SoftApConfiguration - Succeed
|
||||
runAsDeviceOwner((result) -> {
|
||||
final TetheringRequestParcel withConfig = new TetheringRequestParcel();
|
||||
withConfig.tetheringType = TETHERING_WIFI;
|
||||
withConfig.softApConfig = new SoftApConfiguration.Builder().build();
|
||||
mTetheringConnector.startTethering(withConfig, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||
result);
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering).isTetheringSupported();
|
||||
verify(mTethering).isTetheringAllowed();
|
||||
verify(mTethering).startTethering(any(), any(), any());
|
||||
result.assertResult(-1); // No result
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
});
|
||||
|
||||
runAsDeviceOwnerWhenDeviceOwnerBypassNotEnabled((result) -> {
|
||||
mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||
result);
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||
verify(mTethering).isTetherProvisioningRequired();
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
});
|
||||
|
||||
runAsTetherPrivileged((result) -> {
|
||||
mTetheringConnector.startTethering(request, TEST_WRONG_PACKAGE,
|
||||
TEST_ATTRIBUTION_TAG, result);
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering, never()).startTethering(
|
||||
eq(new TetheringRequest(request)), eq(TEST_WRONG_PACKAGE), eq(result));
|
||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||
|
|
@ -403,14 +469,14 @@ public final class TetheringServiceTest {
|
|||
runAsWriteSettings((result) -> {
|
||||
mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||
result);
|
||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
});
|
||||
|
||||
runAsWriteSettingsWhenWriteSettingsAllowed((result) -> {
|
||||
runStartTethering(result, request);
|
||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering).isTetherProvisioningRequired();
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
});
|
||||
|
|
@ -418,6 +484,7 @@ public final class TetheringServiceTest {
|
|||
runAsTetheringDisallowed((result) -> {
|
||||
mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||
result);
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering).isTetheringSupported();
|
||||
verify(mTethering).isTetheringAllowed();
|
||||
result.assertResult(TETHER_ERROR_UNSUPPORTED);
|
||||
|
|
@ -447,6 +514,7 @@ public final class TetheringServiceTest {
|
|||
mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||
result);
|
||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
});
|
||||
}
|
||||
|
|
@ -459,6 +527,7 @@ public final class TetheringServiceTest {
|
|||
mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||
result);
|
||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
}
|
||||
|
||||
|
|
@ -495,7 +564,7 @@ public final class TetheringServiceTest {
|
|||
runAsNoPermission((result) -> {
|
||||
mTetheringConnector.stopTethering(TETHERING_WIFI, TEST_CALLER_PKG,
|
||||
TEST_ATTRIBUTION_TAG, result);
|
||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
});
|
||||
|
|
@ -508,14 +577,14 @@ public final class TetheringServiceTest {
|
|||
runAsWriteSettings((result) -> {
|
||||
mTetheringConnector.stopTethering(TETHERING_WIFI, TEST_CALLER_PKG,
|
||||
TEST_ATTRIBUTION_TAG, result);
|
||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
});
|
||||
|
||||
runAsWriteSettingsWhenWriteSettingsAllowed((result) -> {
|
||||
runStopTethering(result);
|
||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering).isTetherProvisioningRequired();
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
});
|
||||
|
|
@ -530,6 +599,87 @@ public final class TetheringServiceTest {
|
|||
});
|
||||
}
|
||||
|
||||
private void verifyHasPermissionForStopTetheringRequest(TetheringRequest request,
|
||||
final TestTetheringResult result) throws Exception {
|
||||
mTetheringConnector.stopTetheringRequest(request, TEST_CALLER_PKG,
|
||||
TEST_ATTRIBUTION_TAG, result);
|
||||
verify(mTethering).stopTetheringRequest(any(), any());
|
||||
verify(mTethering).isTetheringSupported();
|
||||
verify(mTethering).isTetheringAllowed();
|
||||
reset(mTethering);
|
||||
}
|
||||
|
||||
private void verifyDoesNotHavePermissionForStopTetheringRequest(TetheringRequest request,
|
||||
final TestTetheringResult result) throws Exception {
|
||||
mTetheringConnector.stopTetheringRequest(request, TEST_CALLER_PKG,
|
||||
TEST_ATTRIBUTION_TAG, result);
|
||||
verify(mTethering, never()).stopTetheringRequest(any(), any());
|
||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||
reset(mTethering);
|
||||
}
|
||||
|
||||
private void verifyStopTetheringRequestWithTetheringDisallowed(TetheringRequest request,
|
||||
final TestTetheringResult result) throws Exception {
|
||||
mTetheringConnector.stopTetheringRequest(request, TEST_CALLER_PKG,
|
||||
TEST_ATTRIBUTION_TAG, result);
|
||||
verify(mTethering, never()).stopTetheringRequest(any(), any());
|
||||
result.assertResult(TETHER_ERROR_UNSUPPORTED);
|
||||
reset(mTethering);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStopTetheringRequest() throws Exception {
|
||||
TetheringRequest request = new TetheringRequest.Builder(TETHERING_WIFI).build();
|
||||
|
||||
runAsNoPermission((result) -> {
|
||||
verifyDoesNotHavePermissionForStopTetheringRequest(request, result);
|
||||
});
|
||||
|
||||
runAsTetherPrivileged((result) -> {
|
||||
verifyHasPermissionForStopTetheringRequest(request, result);
|
||||
});
|
||||
|
||||
runAsWriteSettings((result) -> {
|
||||
verifyDoesNotHavePermissionForStopTetheringRequest(request, result);
|
||||
});
|
||||
|
||||
runAsWriteSettingsWhenWriteSettingsAllowed((result) -> {
|
||||
verifyHasPermissionForStopTetheringRequest(request, result);
|
||||
});
|
||||
|
||||
runAsTetheringDisallowed((result) -> {
|
||||
verifyStopTetheringRequestWithTetheringDisallowed(request, result);
|
||||
});
|
||||
|
||||
runAsNetworkSettings((result) -> {
|
||||
verifyHasPermissionForStopTetheringRequest(request, result);
|
||||
});
|
||||
|
||||
// Not wifi -> fail
|
||||
runAsDeviceOwner((result) -> {
|
||||
TetheringRequest notWifi = new TetheringRequest.Builder(TETHERING_USB).build();
|
||||
verifyDoesNotHavePermissionForStopTetheringRequest(notWifi, result);
|
||||
});
|
||||
|
||||
// No config -> fail
|
||||
runAsDeviceOwner((result) -> {
|
||||
TetheringRequest noConfig = new TetheringRequest.Builder(TETHERING_WIFI).build();
|
||||
verifyDoesNotHavePermissionForStopTetheringRequest(noConfig, result);
|
||||
});
|
||||
|
||||
// With config -> success
|
||||
TetheringRequest withConfig = new TetheringRequest.Builder(TETHERING_WIFI)
|
||||
.setSoftApConfiguration(new SoftApConfiguration.Builder().build())
|
||||
.build();
|
||||
runAsDeviceOwner((result) -> {
|
||||
verifyHasPermissionForStopTetheringRequest(withConfig, result);
|
||||
});
|
||||
|
||||
runAsDeviceOwnerWhenDeviceOwnerBypassNotEnabled((result) -> {
|
||||
verifyDoesNotHavePermissionForStopTetheringRequest(withConfig, result);
|
||||
});
|
||||
}
|
||||
|
||||
private void runRequestLatestTetheringEntitlementResult() throws Exception {
|
||||
final MyResultReceiver result = new MyResultReceiver(null);
|
||||
mTetheringConnector.requestLatestTetheringEntitlementResult(TETHERING_WIFI, result,
|
||||
|
|
@ -547,7 +697,7 @@ public final class TetheringServiceTest {
|
|||
runAsNoPermission((none) -> {
|
||||
mTetheringConnector.requestLatestTetheringEntitlementResult(TETHERING_WIFI, result,
|
||||
true /* showEntitlementUi */, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG);
|
||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
});
|
||||
|
|
@ -567,14 +717,14 @@ public final class TetheringServiceTest {
|
|||
runAsWriteSettings((none) -> {
|
||||
mTetheringConnector.requestLatestTetheringEntitlementResult(TETHERING_WIFI, result,
|
||||
true /* showEntitlementUi */, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG);
|
||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
});
|
||||
|
||||
runAsWriteSettingsWhenWriteSettingsAllowed((none) -> {
|
||||
runRequestLatestTetheringEntitlementResult();
|
||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering).isTetherProvisioningRequired();
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
});
|
||||
|
|
@ -668,7 +818,7 @@ public final class TetheringServiceTest {
|
|||
public void testStopAllTethering() throws Exception {
|
||||
runAsNoPermission((result) -> {
|
||||
mTetheringConnector.stopAllTethering(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result);
|
||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
});
|
||||
|
|
@ -680,14 +830,14 @@ public final class TetheringServiceTest {
|
|||
|
||||
runAsWriteSettings((result) -> {
|
||||
mTetheringConnector.stopAllTethering(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result);
|
||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
});
|
||||
|
||||
runAsWriteSettingsWhenWriteSettingsAllowed((result) -> {
|
||||
runStopAllTethering(result);
|
||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering).isTetherProvisioningRequired();
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
});
|
||||
|
|
@ -703,6 +853,7 @@ public final class TetheringServiceTest {
|
|||
|
||||
private void runIsTetheringSupported(final TestTetheringResult result) throws Exception {
|
||||
mTetheringConnector.isTetheringSupported(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result);
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering).isTetheringSupported();
|
||||
verify(mTethering).isTetheringAllowed();
|
||||
result.assertResult(TETHER_ERROR_NO_ERROR);
|
||||
|
|
@ -713,7 +864,7 @@ public final class TetheringServiceTest {
|
|||
runAsNoPermission((result) -> {
|
||||
mTetheringConnector.isTetheringSupported(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||
result);
|
||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
});
|
||||
|
|
@ -726,14 +877,13 @@ public final class TetheringServiceTest {
|
|||
runAsWriteSettings((result) -> {
|
||||
mTetheringConnector.isTetheringSupported(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||
result);
|
||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
});
|
||||
|
||||
runAsWriteSettingsWhenWriteSettingsAllowed((result) -> {
|
||||
runIsTetheringSupported(result);
|
||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering).isTetherProvisioningRequired();
|
||||
verifyNoMoreInteractionsForTethering();
|
||||
});
|
||||
|
|
@ -741,6 +891,7 @@ public final class TetheringServiceTest {
|
|||
runAsTetheringDisallowed((result) -> {
|
||||
mTetheringConnector.isTetheringSupported(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||
result);
|
||||
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||
verify(mTethering).isTetheringSupported();
|
||||
verify(mTethering).isTetheringAllowed();
|
||||
result.assertResult(TETHER_ERROR_UNSUPPORTED);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* 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.networkstack.tethering.util;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.Context;
|
||||
import android.os.UserHandle;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
public class TetheringPermissionsUtilsTest {
|
||||
private static final int TEST_UID = 12345;
|
||||
private static final String TEST_PACKAGE = "test.package";
|
||||
|
||||
@Mock Context mContext;
|
||||
@Mock Context mUserContext;
|
||||
@Mock DevicePolicyManager mDevicePolicyManager;
|
||||
@Mock TelephonyManager mTelephonyManager;
|
||||
|
||||
TetheringPermissionsUtils mTetheringPermissionsUtils;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
when(mContext.createContextAsUser(UserHandle.getUserHandleForUid(TEST_UID), 0))
|
||||
.thenReturn(mUserContext);
|
||||
when(mUserContext.getSystemService(DevicePolicyManager.class))
|
||||
.thenReturn(mDevicePolicyManager);
|
||||
when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
|
||||
mTetheringPermissionsUtils = new TetheringPermissionsUtils(mContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsDeviceOwner() {
|
||||
when(mDevicePolicyManager.isDeviceOwnerApp(TEST_PACKAGE)).thenReturn(false);
|
||||
assertThat(mTetheringPermissionsUtils.isDeviceOwner(TEST_UID, TEST_PACKAGE)).isFalse();
|
||||
|
||||
when(mDevicePolicyManager.isDeviceOwnerApp(TEST_PACKAGE)).thenReturn(true);
|
||||
assertThat(mTetheringPermissionsUtils.isDeviceOwner(TEST_UID, TEST_PACKAGE)).isTrue();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue