Merge "Add DO app bypass for start/stopTethering" into main
This commit is contained in:
commit
038fd312fe
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.Manifest.permission.TETHER_PRIVILEGED;
|
||||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||||
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
|
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_ACCESS_TETHERING_PERMISSION;
|
||||||
import static android.net.TetheringManager.TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION;
|
import static android.net.TetheringManager.TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION;
|
||||||
import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
|
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.internal.annotations.VisibleForTesting;
|
||||||
import com.android.networkstack.apishim.SettingsShimImpl;
|
import com.android.networkstack.apishim.SettingsShimImpl;
|
||||||
import com.android.networkstack.apishim.common.SettingsShim;
|
import com.android.networkstack.apishim.common.SettingsShim;
|
||||||
|
import com.android.networkstack.tethering.util.TetheringPermissionsUtils;
|
||||||
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
|
@ -72,6 +74,7 @@ public class TetheringService extends Service {
|
||||||
|
|
||||||
private TetheringConnector mConnector;
|
private TetheringConnector mConnector;
|
||||||
private SettingsShim mSettingsShim;
|
private SettingsShim mSettingsShim;
|
||||||
|
private TetheringPermissionsUtils mTetheringPermissionsUtils;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
|
|
@ -81,6 +84,7 @@ public class TetheringService extends Service {
|
||||||
mConnector = new TetheringConnector(makeTethering(deps), TetheringService.this);
|
mConnector = new TetheringConnector(makeTethering(deps), TetheringService.this);
|
||||||
|
|
||||||
mSettingsShim = SettingsShimImpl.newInstance();
|
mSettingsShim = SettingsShimImpl.newInstance();
|
||||||
|
mTetheringPermissionsUtils = new TetheringPermissionsUtils(deps.getContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -109,7 +113,11 @@ public class TetheringService extends Service {
|
||||||
@Override
|
@Override
|
||||||
public void tether(String iface, String callerPkg, String callingAttributionTag,
|
public void tether(String iface, String callerPkg, String callingAttributionTag,
|
||||||
IIntResultListener listener) {
|
IIntResultListener listener) {
|
||||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return;
|
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag,
|
||||||
|
false /* onlyAllowPrivileged */, false /* isDeviceOwnerAppAllowed */,
|
||||||
|
listener)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
mTethering.legacyTether(iface, listener);
|
mTethering.legacyTether(iface, listener);
|
||||||
}
|
}
|
||||||
|
|
@ -117,7 +125,11 @@ public class TetheringService extends Service {
|
||||||
@Override
|
@Override
|
||||||
public void untether(String iface, String callerPkg, String callingAttributionTag,
|
public void untether(String iface, String callerPkg, String callingAttributionTag,
|
||||||
IIntResultListener listener) {
|
IIntResultListener listener) {
|
||||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return;
|
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag,
|
||||||
|
false /* onlyAllowPrivileged */, false /* isDeviceOwnerAppAllowed */,
|
||||||
|
listener)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
mTethering.legacyUntether(iface, listener);
|
mTethering.legacyUntether(iface, listener);
|
||||||
}
|
}
|
||||||
|
|
@ -125,32 +137,45 @@ public class TetheringService extends Service {
|
||||||
@Override
|
@Override
|
||||||
public void setUsbTethering(boolean enable, String callerPkg, String callingAttributionTag,
|
public void setUsbTethering(boolean enable, String callerPkg, String callingAttributionTag,
|
||||||
IIntResultListener listener) {
|
IIntResultListener listener) {
|
||||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return;
|
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag,
|
||||||
|
false /* onlyAllowPrivileged */, false /* isDeviceOwnerAppAllowed */,
|
||||||
|
listener)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
mTethering.setUsbTethering(enable, listener);
|
mTethering.setUsbTethering(enable, listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isRequestAllowedForDeviceOwner(@NonNull TetheringRequest request) {
|
||||||
|
return request.getTetheringType() == TETHERING_WIFI
|
||||||
|
&& request.getSoftApConfiguration() != null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startTethering(TetheringRequestParcel request, String callerPkg,
|
public void startTethering(TetheringRequestParcel requestParcel, String callerPkg,
|
||||||
String callingAttributionTag, IIntResultListener listener) {
|
String callingAttributionTag, IIntResultListener listener) {
|
||||||
boolean onlyAllowPrivileged = request.exemptFromEntitlementCheck
|
TetheringRequest request = new TetheringRequest(requestParcel);
|
||||||
|| request.interfaceName != null;
|
request.setUid(getBinderCallingUid());
|
||||||
if (checkAndNotifyCommonError(callerPkg,
|
request.setPackageName(callerPkg);
|
||||||
callingAttributionTag,
|
boolean onlyAllowPrivileged = request.isExemptFromEntitlementCheck()
|
||||||
onlyAllowPrivileged,
|
|| request.getInterfaceName() != null;
|
||||||
listener)) {
|
boolean isDeviceOwnerAllowed = mTethering.isTetheringWithSoftApConfigEnabled()
|
||||||
|
&& isRequestAllowedForDeviceOwner(request);
|
||||||
|
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, onlyAllowPrivileged,
|
||||||
|
isDeviceOwnerAllowed, listener)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
TetheringRequest external = new TetheringRequest(request);
|
mTethering.startTethering(request, callerPkg, listener);
|
||||||
external.setUid(getBinderCallingUid());
|
|
||||||
external.setPackageName(callerPkg);
|
|
||||||
mTethering.startTethering(external, callerPkg, listener);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stopTethering(int type, String callerPkg, String callingAttributionTag,
|
public void stopTethering(int type, String callerPkg, String callingAttributionTag,
|
||||||
IIntResultListener listener) {
|
IIntResultListener listener) {
|
||||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return;
|
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag,
|
||||||
|
false /* onlyAllowPrivileged */, false /* isDeviceOwnerAppAllowed */,
|
||||||
|
listener)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mTethering.stopTethering(type);
|
mTethering.stopTethering(type);
|
||||||
|
|
@ -164,9 +189,16 @@ public class TetheringService extends Service {
|
||||||
IIntResultListener listener) {
|
IIntResultListener listener) {
|
||||||
if (request == null) return;
|
if (request == null) return;
|
||||||
if (listener == null) return;
|
if (listener == null) return;
|
||||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return;
|
|
||||||
request.setUid(getBinderCallingUid());
|
request.setUid(getBinderCallingUid());
|
||||||
request.setPackageName(callerPkg);
|
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);
|
mTethering.stopTetheringRequest(request, listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -187,7 +219,11 @@ public class TetheringService extends Service {
|
||||||
+ " internal-only listener");
|
+ " internal-only listener");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return;
|
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag,
|
||||||
|
false /* onlyAllowPrivileged */, false /* isDeviceOwnerAppAllowed */,
|
||||||
|
listener)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
mTethering.requestLatestTetheringEntitlementResult(type, receiver, showEntitlementUi);
|
mTethering.requestLatestTetheringEntitlementResult(type, receiver, showEntitlementUi);
|
||||||
}
|
}
|
||||||
|
|
@ -223,7 +259,11 @@ public class TetheringService extends Service {
|
||||||
@Override
|
@Override
|
||||||
public void stopAllTethering(String callerPkg, String callingAttributionTag,
|
public void stopAllTethering(String callerPkg, String callingAttributionTag,
|
||||||
IIntResultListener listener) {
|
IIntResultListener listener) {
|
||||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return;
|
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag,
|
||||||
|
false /* onlyAllowPrivileged */, false /* isDeviceOwnerAppAllowed */,
|
||||||
|
listener)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mTethering.stopAllTethering();
|
mTethering.stopAllTethering();
|
||||||
|
|
@ -234,8 +274,11 @@ public class TetheringService extends Service {
|
||||||
@Override
|
@Override
|
||||||
public void isTetheringSupported(String callerPkg, String callingAttributionTag,
|
public void isTetheringSupported(String callerPkg, String callingAttributionTag,
|
||||||
IIntResultListener listener) {
|
IIntResultListener listener) {
|
||||||
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag, listener)) return;
|
boolean isDeviceOwnerAppAllowed = mTethering.isTetheringWithSoftApConfigEnabled();
|
||||||
|
if (checkAndNotifyCommonError(callerPkg, callingAttributionTag,
|
||||||
|
false /* onlyAllowPrivileged */, isDeviceOwnerAppAllowed, listener)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
listener.onResult(TETHER_ERROR_NO_ERROR);
|
listener.onResult(TETHER_ERROR_NO_ERROR);
|
||||||
} catch (RemoteException e) { }
|
} catch (RemoteException e) { }
|
||||||
|
|
@ -259,24 +302,18 @@ public class TetheringService extends Service {
|
||||||
mTethering.dump(fd, writer, args);
|
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,
|
private boolean checkAndNotifyCommonError(final String callerPkg,
|
||||||
final String callingAttributionTag, final boolean onlyAllowPrivileged,
|
final String callingAttributionTag, final boolean onlyAllowPrivileged,
|
||||||
final IIntResultListener listener) {
|
final boolean isDeviceOwnerAppAllowed, final IIntResultListener listener) {
|
||||||
try {
|
try {
|
||||||
if (!checkPackageNameMatchesUid(getBinderCallingUid(), callerPkg)) {
|
final int uid = getBinderCallingUid();
|
||||||
Log.e(TAG, "Package name " + callerPkg + " does not match UID "
|
if (!checkPackageNameMatchesUid(uid, callerPkg)) {
|
||||||
+ getBinderCallingUid());
|
Log.e(TAG, "Package name " + callerPkg + " does not match UID " + uid);
|
||||||
listener.onResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
listener.onResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!hasTetherChangePermission(callerPkg, callingAttributionTag,
|
if (!hasTetherChangePermission(uid, callerPkg, callingAttributionTag,
|
||||||
onlyAllowPrivileged)) {
|
onlyAllowPrivileged, isDeviceOwnerAppAllowed)) {
|
||||||
listener.onResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
listener.onResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -308,21 +345,25 @@ public class TetheringService extends Service {
|
||||||
return mService.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED;
|
return mService.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasTetherChangePermission(final String callerPkg,
|
private boolean hasTetherChangePermission(final int uid, final String callerPkg,
|
||||||
final String callingAttributionTag, final boolean onlyAllowPrivileged) {
|
final String callingAttributionTag, final boolean onlyAllowPrivileged,
|
||||||
|
final boolean isDeviceOwnerAppAllowed) {
|
||||||
if (onlyAllowPrivileged && !hasNetworkStackPermission()
|
if (onlyAllowPrivileged && !hasNetworkStackPermission()
|
||||||
&& !hasNetworkSettingsPermission()) return false;
|
&& !hasNetworkSettingsPermission()) return false;
|
||||||
|
|
||||||
if (hasTetherPrivilegedPermission()) return true;
|
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
|
// After TetheringManager moves to public API, prevent third-party apps from being able
|
||||||
// to change tethering with only WRITE_SETTINGS permission.
|
// to change tethering with only WRITE_SETTINGS permission.
|
||||||
if (mTethering.isTetheringWithSoftApConfigEnabled()) return false;
|
if (mTethering.isTetheringWithSoftApConfigEnabled()) return false;
|
||||||
|
|
||||||
if (mTethering.isTetherProvisioningRequired()) return false;
|
if (mTethering.isTetherProvisioningRequired()) return false;
|
||||||
|
|
||||||
int uid = getBinderCallingUid();
|
|
||||||
|
|
||||||
// If callerPkg's uid is not same as getBinderCallingUid(),
|
// If callerPkg's uid is not same as getBinderCallingUid(),
|
||||||
// checkAndNoteWriteSettingsOperation will return false and the operation will be
|
// checkAndNoteWriteSettingsOperation will return false and the operation will be
|
||||||
// denied.
|
// denied.
|
||||||
|
|
@ -386,6 +427,14 @@ public class TetheringService extends Service {
|
||||||
return Binder.getCallingUid();
|
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.
|
* 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.Binder;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
|
import android.util.ArraySet;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class MockTetheringService extends TetheringService {
|
public class MockTetheringService extends TetheringService {
|
||||||
private final Tethering mTethering = mock(Tethering.class);
|
private final Tethering mTethering = mock(Tethering.class);
|
||||||
private final ArrayMap<String, Integer> mMockedPermissions = new ArrayMap<>();
|
private final ArrayMap<String, Integer> mMockedPermissions = new ArrayMap<>();
|
||||||
private final ArrayMap<String, Integer> mMockedPackageUids = new ArrayMap<>();
|
private final ArrayMap<String, Integer> mMockedPackageUids = new ArrayMap<>();
|
||||||
|
private final Set<String> mMockedDeviceOwnerPackages = new ArraySet<>();
|
||||||
private int mMockCallingUid;
|
private int mMockCallingUid;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -74,6 +78,11 @@ public class MockTetheringService extends TetheringService {
|
||||||
return mMockCallingUid;
|
return mMockCallingUid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean isDeviceOwner(final int uid, final String callerPkg) {
|
||||||
|
return mMockedDeviceOwnerPackages.contains(callerPkg);
|
||||||
|
}
|
||||||
|
|
||||||
public Tethering getTethering() {
|
public Tethering getTethering() {
|
||||||
return mTethering;
|
return mTethering;
|
||||||
}
|
}
|
||||||
|
|
@ -118,5 +127,19 @@ public class MockTetheringService extends TetheringService {
|
||||||
public void setCallingUid(int uid) {
|
public void setCallingUid(int uid) {
|
||||||
mMockCallingUid = 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.TETHER_PRIVILEGED;
|
||||||
import static android.Manifest.permission.WRITE_SETTINGS;
|
import static android.Manifest.permission.WRITE_SETTINGS;
|
||||||
import static android.content.pm.PackageManager.PERMISSION_DENIED;
|
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_VIRTUAL;
|
||||||
import static android.net.TetheringManager.TETHERING_WIFI;
|
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_ACCESS_TETHERING_PERMISSION;
|
||||||
|
|
@ -36,6 +37,7 @@ import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.anyInt;
|
import static org.mockito.Mockito.anyInt;
|
||||||
|
import static org.mockito.Mockito.atLeastOnce;
|
||||||
import static org.mockito.Mockito.doAnswer;
|
import static org.mockito.Mockito.doAnswer;
|
||||||
import static org.mockito.Mockito.doThrow;
|
import static org.mockito.Mockito.doThrow;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
|
|
@ -53,6 +55,7 @@ import android.net.ITetheringEventCallback;
|
||||||
import android.net.TetheringManager;
|
import android.net.TetheringManager;
|
||||||
import android.net.TetheringManager.TetheringRequest;
|
import android.net.TetheringManager.TetheringRequest;
|
||||||
import android.net.TetheringRequestParcel;
|
import android.net.TetheringRequestParcel;
|
||||||
|
import android.net.wifi.SoftApConfiguration;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.ConditionVariable;
|
import android.os.ConditionVariable;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
|
@ -153,43 +156,58 @@ public final class TetheringServiceTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runAsNoPermission(final TestTetheringCall test) throws Exception {
|
private void runAsNoPermission(final TestTetheringCall test) throws Exception {
|
||||||
runTetheringCall(test, true /* isTetheringAllowed */, false /* isWriteSettingsAllowed */,
|
runTetheringCall(test, true /* isTetheringAllowed */,
|
||||||
new String[0]);
|
true /* isTetheringWithSoftApConfigEnabled */, new String[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runAsTetherPrivileged(final TestTetheringCall test) throws Exception {
|
private void runAsTetherPrivileged(final TestTetheringCall test) throws Exception {
|
||||||
runTetheringCall(test, true /* isTetheringAllowed */, false /* isWriteSettingsAllowed */,
|
runTetheringCall(test, true /* isTetheringAllowed */,
|
||||||
TETHER_PRIVILEGED);
|
true /* isTetheringWithSoftApConfigEnabled */, TETHER_PRIVILEGED);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runAsAccessNetworkState(final TestTetheringCall test) throws Exception {
|
private void runAsAccessNetworkState(final TestTetheringCall test) throws Exception {
|
||||||
runTetheringCall(test, true /* isTetheringAllowed */, false /* isWriteSettingsAllowed */,
|
runTetheringCall(test, true /* isTetheringAllowed */,
|
||||||
ACCESS_NETWORK_STATE);
|
true /* isTetheringWithSoftApConfigEnabled */, ACCESS_NETWORK_STATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runAsWriteSettings(final TestTetheringCall test) throws Exception {
|
private void runAsWriteSettings(final TestTetheringCall test) throws Exception {
|
||||||
runTetheringCall(test, true /* isTetheringAllowed */, false /* isWriteSettingsAllowed */,
|
runTetheringCall(test, true /* isTetheringAllowed */,
|
||||||
WRITE_SETTINGS);
|
true /* isTetheringWithSoftApConfigEnabled */, WRITE_SETTINGS);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runAsWriteSettingsWhenWriteSettingsAllowed(
|
private void runAsWriteSettingsWhenWriteSettingsAllowed(
|
||||||
final TestTetheringCall test) throws Exception {
|
final TestTetheringCall test) throws Exception {
|
||||||
runTetheringCall(test, true /* isTetheringAllowed */, true /* isWriteSettingsAllowed */,
|
runTetheringCall(test, true /* isTetheringAllowed */,
|
||||||
WRITE_SETTINGS);
|
false /* isTetheringWithSoftApConfigEnabled */, WRITE_SETTINGS);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runAsTetheringDisallowed(final TestTetheringCall test) throws Exception {
|
private void runAsTetheringDisallowed(final TestTetheringCall test) throws Exception {
|
||||||
runTetheringCall(test, false /* isTetheringAllowed */, false /* isWriteSettingsAllowed */,
|
runTetheringCall(test, false /* isTetheringAllowed */,
|
||||||
TETHER_PRIVILEGED);
|
true /* isTetheringWithSoftApConfigEnabled */, TETHER_PRIVILEGED);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runAsNetworkSettings(final TestTetheringCall test) throws Exception {
|
private void runAsNetworkSettings(final TestTetheringCall test) throws Exception {
|
||||||
runTetheringCall(test, true /* isTetheringAllowed */, false /* isWriteSettingsAllowed */,
|
runTetheringCall(test, true /* isTetheringAllowed */,
|
||||||
NETWORK_SETTINGS, TETHER_PRIVILEGED);
|
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,
|
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
|
// Allow the test to run even if ACCESS_NETWORK_STATE was granted at the APK level
|
||||||
if (!CollectionUtils.contains(permissions, ACCESS_NETWORK_STATE)) {
|
if (!CollectionUtils.contains(permissions, ACCESS_NETWORK_STATE)) {
|
||||||
mMockConnector.setPermission(ACCESS_NETWORK_STATE, PERMISSION_DENIED);
|
mMockConnector.setPermission(ACCESS_NETWORK_STATE, PERMISSION_DENIED);
|
||||||
|
|
@ -200,7 +218,7 @@ public final class TetheringServiceTest {
|
||||||
when(mTethering.isTetheringSupported()).thenReturn(true);
|
when(mTethering.isTetheringSupported()).thenReturn(true);
|
||||||
when(mTethering.isTetheringAllowed()).thenReturn(isTetheringAllowed);
|
when(mTethering.isTetheringAllowed()).thenReturn(isTetheringAllowed);
|
||||||
when(mTethering.isTetheringWithSoftApConfigEnabled())
|
when(mTethering.isTetheringWithSoftApConfigEnabled())
|
||||||
.thenReturn(!isWriteSettingsAllowed);
|
.thenReturn(isTetheringWithSoftApConfigEnabled);
|
||||||
test.runTetheringCall(new TestTetheringResult());
|
test.runTetheringCall(new TestTetheringResult());
|
||||||
} finally {
|
} finally {
|
||||||
mUiAutomation.dropShellPermissionIdentity();
|
mUiAutomation.dropShellPermissionIdentity();
|
||||||
|
|
@ -226,7 +244,7 @@ public final class TetheringServiceTest {
|
||||||
runAsNoPermission((result) -> {
|
runAsNoPermission((result) -> {
|
||||||
mTetheringConnector.tether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
mTetheringConnector.tether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||||
result);
|
result);
|
||||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
verifyNoMoreInteractionsForTethering();
|
verifyNoMoreInteractionsForTethering();
|
||||||
});
|
});
|
||||||
|
|
@ -239,14 +257,14 @@ public final class TetheringServiceTest {
|
||||||
runAsWriteSettings((result) -> {
|
runAsWriteSettings((result) -> {
|
||||||
mTetheringConnector.tether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
mTetheringConnector.tether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||||
result);
|
result);
|
||||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
verifyNoMoreInteractionsForTethering();
|
verifyNoMoreInteractionsForTethering();
|
||||||
});
|
});
|
||||||
|
|
||||||
runAsWriteSettingsWhenWriteSettingsAllowed((result) -> {
|
runAsWriteSettingsWhenWriteSettingsAllowed((result) -> {
|
||||||
runTether(result);
|
runTether(result);
|
||||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||||
verify(mTethering).isTetherProvisioningRequired();
|
verify(mTethering).isTetherProvisioningRequired();
|
||||||
verifyNoMoreInteractionsForTethering();
|
verifyNoMoreInteractionsForTethering();
|
||||||
});
|
});
|
||||||
|
|
@ -274,7 +292,7 @@ public final class TetheringServiceTest {
|
||||||
runAsNoPermission((result) -> {
|
runAsNoPermission((result) -> {
|
||||||
mTetheringConnector.untether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
mTetheringConnector.untether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||||
result);
|
result);
|
||||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
verifyNoMoreInteractionsForTethering();
|
verifyNoMoreInteractionsForTethering();
|
||||||
});
|
});
|
||||||
|
|
@ -287,14 +305,14 @@ public final class TetheringServiceTest {
|
||||||
runAsWriteSettings((result) -> {
|
runAsWriteSettings((result) -> {
|
||||||
mTetheringConnector.untether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
mTetheringConnector.untether(TEST_IFACE_NAME, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||||
result);
|
result);
|
||||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
verifyNoMoreInteractionsForTethering();
|
verifyNoMoreInteractionsForTethering();
|
||||||
});
|
});
|
||||||
|
|
||||||
runAsWriteSettingsWhenWriteSettingsAllowed((result) -> {
|
runAsWriteSettingsWhenWriteSettingsAllowed((result) -> {
|
||||||
runUnTether(result);
|
runUnTether(result);
|
||||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||||
verify(mTethering).isTetherProvisioningRequired();
|
verify(mTethering).isTetherProvisioningRequired();
|
||||||
verifyNoMoreInteractionsForTethering();
|
verifyNoMoreInteractionsForTethering();
|
||||||
});
|
});
|
||||||
|
|
@ -328,7 +346,7 @@ public final class TetheringServiceTest {
|
||||||
runAsNoPermission((result) -> {
|
runAsNoPermission((result) -> {
|
||||||
mTetheringConnector.setUsbTethering(true /* enable */, TEST_CALLER_PKG,
|
mTetheringConnector.setUsbTethering(true /* enable */, TEST_CALLER_PKG,
|
||||||
TEST_ATTRIBUTION_TAG, result);
|
TEST_ATTRIBUTION_TAG, result);
|
||||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
verifyNoMoreInteractionsForTethering();
|
verifyNoMoreInteractionsForTethering();
|
||||||
});
|
});
|
||||||
|
|
@ -341,14 +359,14 @@ public final class TetheringServiceTest {
|
||||||
runAsWriteSettings((result) -> {
|
runAsWriteSettings((result) -> {
|
||||||
mTetheringConnector.setUsbTethering(true /* enable */, TEST_CALLER_PKG,
|
mTetheringConnector.setUsbTethering(true /* enable */, TEST_CALLER_PKG,
|
||||||
TEST_ATTRIBUTION_TAG, result);
|
TEST_ATTRIBUTION_TAG, result);
|
||||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
verifyNoMoreInteractionsForTethering();
|
verifyNoMoreInteractionsForTethering();
|
||||||
});
|
});
|
||||||
|
|
||||||
runAsWriteSettingsWhenWriteSettingsAllowed((result) -> {
|
runAsWriteSettingsWhenWriteSettingsAllowed((result) -> {
|
||||||
runSetUsbTethering(result);
|
runSetUsbTethering(result);
|
||||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||||
verify(mTethering).isTetherProvisioningRequired();
|
verify(mTethering).isTetherProvisioningRequired();
|
||||||
verifyNoMoreInteractionsForTethering();
|
verifyNoMoreInteractionsForTethering();
|
||||||
});
|
});
|
||||||
|
|
@ -367,6 +385,7 @@ public final class TetheringServiceTest {
|
||||||
final TetheringRequestParcel request) throws Exception {
|
final TetheringRequestParcel request) throws Exception {
|
||||||
mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||||
result);
|
result);
|
||||||
|
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||||
verify(mTethering).isTetheringSupported();
|
verify(mTethering).isTetheringSupported();
|
||||||
verify(mTethering).isTetheringAllowed();
|
verify(mTethering).isTetheringAllowed();
|
||||||
verify(mTethering).startTethering(
|
verify(mTethering).startTethering(
|
||||||
|
|
@ -381,14 +400,61 @@ public final class TetheringServiceTest {
|
||||||
runAsNoPermission((result) -> {
|
runAsNoPermission((result) -> {
|
||||||
mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||||
result);
|
result);
|
||||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
verifyNoMoreInteractionsForTethering();
|
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) -> {
|
runAsTetherPrivileged((result) -> {
|
||||||
mTetheringConnector.startTethering(request, TEST_WRONG_PACKAGE,
|
mTetheringConnector.startTethering(request, TEST_WRONG_PACKAGE,
|
||||||
TEST_ATTRIBUTION_TAG, result);
|
TEST_ATTRIBUTION_TAG, result);
|
||||||
|
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||||
verify(mTethering, never()).startTethering(
|
verify(mTethering, never()).startTethering(
|
||||||
eq(new TetheringRequest(request)), eq(TEST_WRONG_PACKAGE), eq(result));
|
eq(new TetheringRequest(request)), eq(TEST_WRONG_PACKAGE), eq(result));
|
||||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
|
|
@ -403,14 +469,14 @@ public final class TetheringServiceTest {
|
||||||
runAsWriteSettings((result) -> {
|
runAsWriteSettings((result) -> {
|
||||||
mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||||
result);
|
result);
|
||||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
verifyNoMoreInteractionsForTethering();
|
verifyNoMoreInteractionsForTethering();
|
||||||
});
|
});
|
||||||
|
|
||||||
runAsWriteSettingsWhenWriteSettingsAllowed((result) -> {
|
runAsWriteSettingsWhenWriteSettingsAllowed((result) -> {
|
||||||
runStartTethering(result, request);
|
runStartTethering(result, request);
|
||||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||||
verify(mTethering).isTetherProvisioningRequired();
|
verify(mTethering).isTetherProvisioningRequired();
|
||||||
verifyNoMoreInteractionsForTethering();
|
verifyNoMoreInteractionsForTethering();
|
||||||
});
|
});
|
||||||
|
|
@ -418,6 +484,7 @@ public final class TetheringServiceTest {
|
||||||
runAsTetheringDisallowed((result) -> {
|
runAsTetheringDisallowed((result) -> {
|
||||||
mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||||
result);
|
result);
|
||||||
|
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||||
verify(mTethering).isTetheringSupported();
|
verify(mTethering).isTetheringSupported();
|
||||||
verify(mTethering).isTetheringAllowed();
|
verify(mTethering).isTetheringAllowed();
|
||||||
result.assertResult(TETHER_ERROR_UNSUPPORTED);
|
result.assertResult(TETHER_ERROR_UNSUPPORTED);
|
||||||
|
|
@ -447,6 +514,7 @@ public final class TetheringServiceTest {
|
||||||
mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||||
result);
|
result);
|
||||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
|
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||||
verifyNoMoreInteractionsForTethering();
|
verifyNoMoreInteractionsForTethering();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -459,6 +527,7 @@ public final class TetheringServiceTest {
|
||||||
mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
mTetheringConnector.startTethering(request, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||||
result);
|
result);
|
||||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
|
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||||
verifyNoMoreInteractionsForTethering();
|
verifyNoMoreInteractionsForTethering();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -495,7 +564,7 @@ public final class TetheringServiceTest {
|
||||||
runAsNoPermission((result) -> {
|
runAsNoPermission((result) -> {
|
||||||
mTetheringConnector.stopTethering(TETHERING_WIFI, TEST_CALLER_PKG,
|
mTetheringConnector.stopTethering(TETHERING_WIFI, TEST_CALLER_PKG,
|
||||||
TEST_ATTRIBUTION_TAG, result);
|
TEST_ATTRIBUTION_TAG, result);
|
||||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
verifyNoMoreInteractionsForTethering();
|
verifyNoMoreInteractionsForTethering();
|
||||||
});
|
});
|
||||||
|
|
@ -508,14 +577,14 @@ public final class TetheringServiceTest {
|
||||||
runAsWriteSettings((result) -> {
|
runAsWriteSettings((result) -> {
|
||||||
mTetheringConnector.stopTethering(TETHERING_WIFI, TEST_CALLER_PKG,
|
mTetheringConnector.stopTethering(TETHERING_WIFI, TEST_CALLER_PKG,
|
||||||
TEST_ATTRIBUTION_TAG, result);
|
TEST_ATTRIBUTION_TAG, result);
|
||||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
verifyNoMoreInteractionsForTethering();
|
verifyNoMoreInteractionsForTethering();
|
||||||
});
|
});
|
||||||
|
|
||||||
runAsWriteSettingsWhenWriteSettingsAllowed((result) -> {
|
runAsWriteSettingsWhenWriteSettingsAllowed((result) -> {
|
||||||
runStopTethering(result);
|
runStopTethering(result);
|
||||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||||
verify(mTethering).isTetherProvisioningRequired();
|
verify(mTethering).isTetherProvisioningRequired();
|
||||||
verifyNoMoreInteractionsForTethering();
|
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 {
|
private void runRequestLatestTetheringEntitlementResult() throws Exception {
|
||||||
final MyResultReceiver result = new MyResultReceiver(null);
|
final MyResultReceiver result = new MyResultReceiver(null);
|
||||||
mTetheringConnector.requestLatestTetheringEntitlementResult(TETHERING_WIFI, result,
|
mTetheringConnector.requestLatestTetheringEntitlementResult(TETHERING_WIFI, result,
|
||||||
|
|
@ -547,7 +697,7 @@ public final class TetheringServiceTest {
|
||||||
runAsNoPermission((none) -> {
|
runAsNoPermission((none) -> {
|
||||||
mTetheringConnector.requestLatestTetheringEntitlementResult(TETHERING_WIFI, result,
|
mTetheringConnector.requestLatestTetheringEntitlementResult(TETHERING_WIFI, result,
|
||||||
true /* showEntitlementUi */, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG);
|
true /* showEntitlementUi */, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG);
|
||||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
verifyNoMoreInteractionsForTethering();
|
verifyNoMoreInteractionsForTethering();
|
||||||
});
|
});
|
||||||
|
|
@ -567,14 +717,14 @@ public final class TetheringServiceTest {
|
||||||
runAsWriteSettings((none) -> {
|
runAsWriteSettings((none) -> {
|
||||||
mTetheringConnector.requestLatestTetheringEntitlementResult(TETHERING_WIFI, result,
|
mTetheringConnector.requestLatestTetheringEntitlementResult(TETHERING_WIFI, result,
|
||||||
true /* showEntitlementUi */, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG);
|
true /* showEntitlementUi */, TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG);
|
||||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
verifyNoMoreInteractionsForTethering();
|
verifyNoMoreInteractionsForTethering();
|
||||||
});
|
});
|
||||||
|
|
||||||
runAsWriteSettingsWhenWriteSettingsAllowed((none) -> {
|
runAsWriteSettingsWhenWriteSettingsAllowed((none) -> {
|
||||||
runRequestLatestTetheringEntitlementResult();
|
runRequestLatestTetheringEntitlementResult();
|
||||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||||
verify(mTethering).isTetherProvisioningRequired();
|
verify(mTethering).isTetherProvisioningRequired();
|
||||||
verifyNoMoreInteractionsForTethering();
|
verifyNoMoreInteractionsForTethering();
|
||||||
});
|
});
|
||||||
|
|
@ -668,7 +818,7 @@ public final class TetheringServiceTest {
|
||||||
public void testStopAllTethering() throws Exception {
|
public void testStopAllTethering() throws Exception {
|
||||||
runAsNoPermission((result) -> {
|
runAsNoPermission((result) -> {
|
||||||
mTetheringConnector.stopAllTethering(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, 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);
|
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
verifyNoMoreInteractionsForTethering();
|
verifyNoMoreInteractionsForTethering();
|
||||||
});
|
});
|
||||||
|
|
@ -680,14 +830,14 @@ public final class TetheringServiceTest {
|
||||||
|
|
||||||
runAsWriteSettings((result) -> {
|
runAsWriteSettings((result) -> {
|
||||||
mTetheringConnector.stopAllTethering(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, 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);
|
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
verifyNoMoreInteractionsForTethering();
|
verifyNoMoreInteractionsForTethering();
|
||||||
});
|
});
|
||||||
|
|
||||||
runAsWriteSettingsWhenWriteSettingsAllowed((result) -> {
|
runAsWriteSettingsWhenWriteSettingsAllowed((result) -> {
|
||||||
runStopAllTethering(result);
|
runStopAllTethering(result);
|
||||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||||
verify(mTethering).isTetherProvisioningRequired();
|
verify(mTethering).isTetherProvisioningRequired();
|
||||||
verifyNoMoreInteractionsForTethering();
|
verifyNoMoreInteractionsForTethering();
|
||||||
});
|
});
|
||||||
|
|
@ -703,6 +853,7 @@ public final class TetheringServiceTest {
|
||||||
|
|
||||||
private void runIsTetheringSupported(final TestTetheringResult result) throws Exception {
|
private void runIsTetheringSupported(final TestTetheringResult result) throws Exception {
|
||||||
mTetheringConnector.isTetheringSupported(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result);
|
mTetheringConnector.isTetheringSupported(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG, result);
|
||||||
|
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||||
verify(mTethering).isTetheringSupported();
|
verify(mTethering).isTetheringSupported();
|
||||||
verify(mTethering).isTetheringAllowed();
|
verify(mTethering).isTetheringAllowed();
|
||||||
result.assertResult(TETHER_ERROR_NO_ERROR);
|
result.assertResult(TETHER_ERROR_NO_ERROR);
|
||||||
|
|
@ -713,7 +864,7 @@ public final class TetheringServiceTest {
|
||||||
runAsNoPermission((result) -> {
|
runAsNoPermission((result) -> {
|
||||||
mTetheringConnector.isTetheringSupported(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
mTetheringConnector.isTetheringSupported(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||||
result);
|
result);
|
||||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
verifyNoMoreInteractionsForTethering();
|
verifyNoMoreInteractionsForTethering();
|
||||||
});
|
});
|
||||||
|
|
@ -726,14 +877,13 @@ public final class TetheringServiceTest {
|
||||||
runAsWriteSettings((result) -> {
|
runAsWriteSettings((result) -> {
|
||||||
mTetheringConnector.isTetheringSupported(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
mTetheringConnector.isTetheringSupported(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||||
result);
|
result);
|
||||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||||
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
result.assertResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
|
||||||
verifyNoMoreInteractionsForTethering();
|
verifyNoMoreInteractionsForTethering();
|
||||||
});
|
});
|
||||||
|
|
||||||
runAsWriteSettingsWhenWriteSettingsAllowed((result) -> {
|
runAsWriteSettingsWhenWriteSettingsAllowed((result) -> {
|
||||||
runIsTetheringSupported(result);
|
runIsTetheringSupported(result);
|
||||||
verify(mTethering).isTetheringWithSoftApConfigEnabled();
|
|
||||||
verify(mTethering).isTetherProvisioningRequired();
|
verify(mTethering).isTetherProvisioningRequired();
|
||||||
verifyNoMoreInteractionsForTethering();
|
verifyNoMoreInteractionsForTethering();
|
||||||
});
|
});
|
||||||
|
|
@ -741,6 +891,7 @@ public final class TetheringServiceTest {
|
||||||
runAsTetheringDisallowed((result) -> {
|
runAsTetheringDisallowed((result) -> {
|
||||||
mTetheringConnector.isTetheringSupported(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
mTetheringConnector.isTetheringSupported(TEST_CALLER_PKG, TEST_ATTRIBUTION_TAG,
|
||||||
result);
|
result);
|
||||||
|
verify(mTethering, atLeastOnce()).isTetheringWithSoftApConfigEnabled();
|
||||||
verify(mTethering).isTetheringSupported();
|
verify(mTethering).isTetheringSupported();
|
||||||
verify(mTethering).isTetheringAllowed();
|
verify(mTethering).isTetheringAllowed();
|
||||||
result.assertResult(TETHER_ERROR_UNSUPPORTED);
|
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