1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.networkstack.tethering; 17 18 import static android.Manifest.permission.WRITE_SETTINGS; 19 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20 21 import static org.mockito.Mockito.mock; 22 23 import android.content.Context; 24 import android.content.Intent; 25 import android.os.Binder; 26 import android.os.IBinder; 27 import android.util.ArrayMap; 28 import android.util.ArraySet; 29 30 import androidx.annotation.NonNull; 31 import androidx.annotation.Nullable; 32 33 import java.util.Set; 34 35 public class MockTetheringService extends TetheringService { 36 private final Tethering mTethering = mock(Tethering.class); 37 private final ArrayMap<String, Integer> mMockedPermissions = new ArrayMap<>(); 38 private final ArrayMap<String, Integer> mMockedPackageUids = new ArrayMap<>(); 39 private final Set<String> mMockedDeviceOwnerPackages = new ArraySet<>(); 40 private final Set<String> mMockedCarrierPrivilegedPackages = new ArraySet<>(); 41 private int mMockCallingUid; 42 43 @Override onBind(Intent intent)44 public IBinder onBind(Intent intent) { 45 return new MockTetheringConnector(super.onBind(intent)); 46 } 47 48 @Override makeTethering(TetheringDependencies deps)49 public Tethering makeTethering(TetheringDependencies deps) { 50 return mTethering; 51 } 52 53 @Override checkAndNoteWriteSettingsOperation(@onNull Context context, int uid, @NonNull String callingPackage, @Nullable String callingAttributionTag, boolean throwException)54 boolean checkAndNoteWriteSettingsOperation(@NonNull Context context, int uid, 55 @NonNull String callingPackage, @Nullable String callingAttributionTag, 56 boolean throwException) { 57 // Test this does not verify the calling package / UID, as calling package could be shell 58 // and not match the UID. 59 return context.checkCallingOrSelfPermission(WRITE_SETTINGS) == PERMISSION_GRANTED; 60 } 61 62 @Override checkCallingOrSelfPermission(String permission)63 public int checkCallingOrSelfPermission(String permission) { 64 final Integer mocked = mMockedPermissions.getOrDefault(permission, null); 65 if (mocked != null) { 66 return mocked; 67 } 68 return super.checkCallingOrSelfPermission(permission); 69 } 70 71 @Override checkPackageNameMatchesUid(@onNull Context context, int uid, @NonNull String callingPackage)72 boolean checkPackageNameMatchesUid(@NonNull Context context, int uid, 73 @NonNull String callingPackage) { 74 return mMockedPackageUids.getOrDefault(callingPackage, 0) == uid; 75 } 76 77 @Override getBinderCallingUid()78 int getBinderCallingUid() { 79 return mMockCallingUid; 80 } 81 82 @Override isDeviceOwner(final int uid, final String callerPkg)83 boolean isDeviceOwner(final int uid, final String callerPkg) { 84 return mMockedDeviceOwnerPackages.contains(callerPkg); 85 } 86 87 @Override isCarrierPrivileged(final String callerPkg)88 boolean isCarrierPrivileged(final String callerPkg) { 89 return mMockedCarrierPrivilegedPackages.contains(callerPkg); 90 } 91 getTethering()92 public Tethering getTethering() { 93 return mTethering; 94 } 95 96 public class MockTetheringConnector extends Binder { 97 final IBinder mBase; MockTetheringConnector(IBinder base)98 MockTetheringConnector(IBinder base) { 99 mBase = base; 100 } 101 getIBinder()102 public IBinder getIBinder() { 103 return mBase; 104 } 105 getService()106 public MockTetheringService getService() { 107 return MockTetheringService.this; 108 } 109 110 /** 111 * Mock a permission 112 * @param permission Permission to mock 113 * @param granted One of PackageManager.PERMISSION_*, or null to reset to default behavior 114 */ setPermission(String permission, Integer granted)115 public void setPermission(String permission, Integer granted) { 116 if (granted == null) { 117 mMockedPermissions.remove(permission); 118 } else { 119 mMockedPermissions.put(permission, granted); 120 } 121 } 122 123 /** 124 * Mock a package name matching a uid. 125 */ setPackageNameUid(String packageName, int uid)126 public void setPackageNameUid(String packageName, int uid) { 127 mMockedPackageUids.put(packageName, uid); 128 } 129 130 /** 131 * Mock a package name matching a uid. 132 */ setCallingUid(int uid)133 public void setCallingUid(int uid) { 134 mMockCallingUid = uid; 135 } 136 137 /** 138 * Add a mocked carrier privileges package 139 */ addDeviceOwnerPackage(final String packageName)140 public void addDeviceOwnerPackage(final String packageName) { 141 mMockedDeviceOwnerPackages.add(packageName); 142 } 143 144 /** 145 * Remove a mocked carrier privileges package 146 */ removeDeviceOwnerPackage(final String packageName)147 public void removeDeviceOwnerPackage(final String packageName) { 148 mMockedDeviceOwnerPackages.remove(packageName); 149 } 150 151 /** 152 * Add a mocked carrier privileges package 153 */ addCarrierPrivilegedPackage(final String packageName)154 public void addCarrierPrivilegedPackage(final String packageName) { 155 mMockedCarrierPrivilegedPackages.add(packageName); 156 } 157 158 /** 159 * Remove a mocked carrier privileges package 160 */ removeCarrierPrivilegedPackage(final String packageName)161 public void removeCarrierPrivilegedPackage(final String packageName) { 162 mMockedCarrierPrivilegedPackages.remove(packageName); 163 } 164 } 165 } 166