1 /* 2 * Copyright (C) 2023 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 17 package com.android.server.am; 18 19 import static org.mockito.ArgumentMatchers.any; 20 import static org.mockito.ArgumentMatchers.anyInt; 21 import static org.mockito.ArgumentMatchers.anyLong; 22 import static org.mockito.ArgumentMatchers.eq; 23 import static org.mockito.Mockito.doAnswer; 24 import static org.mockito.Mockito.doNothing; 25 import static org.mockito.Mockito.doReturn; 26 import static org.mockito.Mockito.spy; 27 28 import android.annotation.NonNull; 29 import android.app.usage.UsageStatsManagerInternal; 30 import android.content.ComponentName; 31 import android.content.Context; 32 import android.content.IntentFilter; 33 import android.content.pm.ActivityInfo; 34 import android.content.pm.ApplicationInfo; 35 import android.content.pm.PackageManagerInternal; 36 import android.content.pm.ResolveInfo; 37 import android.os.Handler; 38 import android.os.HandlerThread; 39 import android.os.TestLooperManager; 40 import android.os.UserHandle; 41 import android.platform.test.flag.junit.CheckFlagsRule; 42 import android.platform.test.flag.junit.DeviceFlagsValueProvider; 43 import android.provider.Settings; 44 import android.util.SparseArray; 45 46 import androidx.test.platform.app.InstrumentationRegistry; 47 48 import com.android.dx.mockito.inline.extended.ExtendedMockito; 49 import com.android.internal.util.FrameworkStatsLog; 50 import com.android.modules.utils.testing.ExtendedMockitoRule; 51 import com.android.server.AlarmManagerInternal; 52 import com.android.server.DropBoxManagerInternal; 53 import com.android.server.LocalServices; 54 import com.android.server.appop.AppOpsService; 55 import com.android.server.wm.ActivityTaskManagerService; 56 57 import org.junit.Rule; 58 import org.mockito.Mock; 59 import org.mockito.Mockito; 60 import org.mockito.MockitoAnnotations; 61 62 import java.io.File; 63 import java.util.Objects; 64 import java.util.concurrent.atomic.AtomicInteger; 65 66 public abstract class BaseBroadcastQueueTest { 67 68 static final int USER_GUEST = 11; 69 70 static final String PACKAGE_ANDROID = "android"; 71 static final String PACKAGE_PHONE = "com.android.phone"; 72 static final String PACKAGE_RED = "com.example.red"; 73 static final String PACKAGE_GREEN = "com.example.green"; 74 static final String PACKAGE_BLUE = "com.example.blue"; 75 static final String PACKAGE_YELLOW = "com.example.yellow"; 76 static final String PACKAGE_ORANGE = "com.example.orange"; 77 78 static final String PROCESS_SYSTEM = "system"; 79 80 static final String CLASS_RED = "com.example.red.Red"; 81 static final String CLASS_GREEN = "com.example.green.Green"; 82 static final String CLASS_BLUE = "com.example.blue.Blue"; 83 static final String CLASS_YELLOW = "com.example.yellow.Yellow"; 84 static final String CLASS_ORANGE = "com.example.orange.Orange"; 85 86 static final BroadcastProcessQueue.BroadcastPredicate BROADCAST_PREDICATE_ANY = 87 (r, i) -> true; 88 89 @Rule 90 public final ApplicationExitInfoTest.ServiceThreadRule 91 mServiceThreadRule = new ApplicationExitInfoTest.ServiceThreadRule(); 92 93 @Rule 94 public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this) 95 .spyStatic(FrameworkStatsLog.class) 96 .spyStatic(ProcessList.class) 97 .build(); 98 99 @Rule 100 public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); 101 102 @Mock 103 AppOpsService mAppOpsService; 104 @Mock 105 PackageManagerInternal mPackageManagerInt; 106 @Mock 107 UsageStatsManagerInternal mUsageStatsManagerInt; 108 @Mock 109 DropBoxManagerInternal mDropBoxManagerInt; 110 @Mock 111 AlarmManagerInternal mAlarmManagerInt; 112 @Mock 113 ProcessList mProcessList; 114 115 @Mock 116 AppStartInfoTracker mAppStartInfoTracker; 117 118 Context mContext; 119 ActivityManagerService mAms; 120 BroadcastConstants mConstants; 121 BroadcastSkipPolicy mSkipPolicy; 122 HandlerThread mHandlerThread; 123 TestLooperManager mLooper; 124 AtomicInteger mNextPid; 125 BroadcastHistory mEmptyHistory; 126 127 /** 128 * Map from PID to registered registered runtime receivers. 129 */ 130 SparseArray<ReceiverList> mRegisteredReceivers = new SparseArray<>(); 131 setUp()132 public void setUp() throws Exception { 133 MockitoAnnotations.initMocks(this); 134 135 mContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 136 mHandlerThread = new HandlerThread(getTag()); 137 mHandlerThread.start(); 138 // Pause all event processing until a test chooses to resume 139 mLooper = Objects.requireNonNull(InstrumentationRegistry.getInstrumentation() 140 .acquireLooperManager(mHandlerThread.getLooper())); 141 mNextPid = new AtomicInteger(100); 142 143 mConstants = new BroadcastConstants(Settings.Global.BROADCAST_FG_CONSTANTS); 144 mEmptyHistory = new BroadcastHistory(mConstants) { 145 public void addBroadcastToHistoryLocked(BroadcastRecord original) { 146 // Ignored 147 } 148 }; 149 150 LocalServices.removeServiceForTest(DropBoxManagerInternal.class); 151 LocalServices.addService(DropBoxManagerInternal.class, mDropBoxManagerInt); 152 LocalServices.removeServiceForTest(PackageManagerInternal.class); 153 LocalServices.addService(PackageManagerInternal.class, mPackageManagerInt); 154 LocalServices.removeServiceForTest(AlarmManagerInternal.class); 155 LocalServices.addService(AlarmManagerInternal.class, mAlarmManagerInt); 156 doReturn(new ComponentName("", "")).when(mPackageManagerInt).getSystemUiServiceComponent(); 157 doNothing().when(mPackageManagerInt).notifyComponentUsed(any(), anyInt(), any(), any()); 158 doAnswer((invocation) -> { 159 return getUidForPackage(invocation.getArgument(0)); 160 }).when(mPackageManagerInt).getPackageUid(any(), anyLong(), eq(UserHandle.USER_SYSTEM)); 161 162 final ActivityManagerService realAms = new ActivityManagerService( 163 new TestInjector(mContext), mServiceThreadRule.getThread()); 164 realAms.mActivityTaskManager = new ActivityTaskManagerService(mContext); 165 realAms.mActivityTaskManager.initialize(null, null, mContext.getMainLooper()); 166 realAms.mAtmInternal = spy(realAms.mActivityTaskManager.getAtmInternal()); 167 realAms.mOomAdjuster.mCachedAppOptimizer = Mockito.mock(CachedAppOptimizer.class); 168 realAms.mOomAdjuster = spy(realAms.mOomAdjuster); 169 ExtendedMockito.doNothing().when(() -> ProcessList.setOomAdj(anyInt(), anyInt(), anyInt())); 170 realAms.mPackageManagerInt = mPackageManagerInt; 171 realAms.mUsageStatsService = mUsageStatsManagerInt; 172 realAms.mProcessesReady = true; 173 mAms = spy(realAms); 174 175 mSkipPolicy = spy(new BroadcastSkipPolicy(mAms)); 176 doReturn(null).when(mSkipPolicy).shouldSkipMessage(any(), any()); 177 doReturn(false).when(mSkipPolicy).disallowBackgroundStart(any()); 178 179 doReturn(mAppStartInfoTracker).when(mProcessList).getAppStartInfoTracker(); 180 } 181 tearDown()182 public void tearDown() throws Exception { 183 if (mHandlerThread != null) { 184 mHandlerThread.quit(); 185 } 186 } 187 getUidForPackage(@onNull String packageName)188 static int getUidForPackage(@NonNull String packageName) { 189 switch (packageName) { 190 case PACKAGE_ANDROID: return android.os.Process.SYSTEM_UID; 191 case PACKAGE_PHONE: return android.os.Process.PHONE_UID; 192 case PACKAGE_RED: return android.os.Process.FIRST_APPLICATION_UID + 1; 193 case PACKAGE_GREEN: return android.os.Process.FIRST_APPLICATION_UID + 2; 194 case PACKAGE_BLUE: return android.os.Process.FIRST_APPLICATION_UID + 3; 195 case PACKAGE_YELLOW: return android.os.Process.FIRST_APPLICATION_UID + 4; 196 case PACKAGE_ORANGE: return android.os.Process.FIRST_APPLICATION_UID + 5; 197 default: throw new IllegalArgumentException(); 198 } 199 } 200 getUidForPackage(@onNull String packageName, int userId)201 static int getUidForPackage(@NonNull String packageName, int userId) { 202 return UserHandle.getUid(userId, getUidForPackage(packageName)); 203 } 204 205 private class TestInjector extends ActivityManagerService.Injector { TestInjector(Context context)206 TestInjector(Context context) { 207 super(context); 208 } 209 210 @Override getAppOpsService(File recentAccessesFile, File storageFile, Handler handler)211 public AppOpsService getAppOpsService(File recentAccessesFile, File storageFile, 212 Handler handler) { 213 return mAppOpsService; 214 } 215 216 @Override getUiHandler(ActivityManagerService service)217 public Handler getUiHandler(ActivityManagerService service) { 218 return mHandlerThread.getThreadHandler(); 219 } 220 221 @Override getProcessList(ActivityManagerService service)222 public ProcessList getProcessList(ActivityManagerService service) { 223 return mProcessList; 224 } 225 226 @Override getBroadcastQueue(ActivityManagerService service)227 public BroadcastQueue getBroadcastQueue(ActivityManagerService service) { 228 return null; 229 } 230 } 231 getTag()232 abstract String getTag(); 233 makeApplicationInfo(String packageName)234 static ApplicationInfo makeApplicationInfo(String packageName) { 235 return makeApplicationInfo(packageName, packageName, UserHandle.USER_SYSTEM); 236 } 237 makeApplicationInfo(String packageName, String processName, int userId)238 static ApplicationInfo makeApplicationInfo(String packageName, String processName, int userId) { 239 final ApplicationInfo ai = new ApplicationInfo(); 240 ai.packageName = packageName; 241 ai.processName = processName; 242 ai.uid = getUidForPackage(packageName, userId); 243 return ai; 244 } 245 withPriority(ResolveInfo info, int priority)246 static ResolveInfo withPriority(ResolveInfo info, int priority) { 247 info.priority = priority; 248 return info; 249 } 250 withPriority(BroadcastFilter filter, int priority)251 static BroadcastFilter withPriority(BroadcastFilter filter, int priority) { 252 filter.setPriority(priority); 253 return filter; 254 } 255 makeManifestReceiver(String packageName, String name)256 static ResolveInfo makeManifestReceiver(String packageName, String name) { 257 return makeManifestReceiver(packageName, name, UserHandle.USER_SYSTEM); 258 } 259 makeManifestReceiver(String packageName, String name, int userId)260 static ResolveInfo makeManifestReceiver(String packageName, String name, int userId) { 261 return makeManifestReceiver(packageName, packageName, name, userId); 262 } 263 makeManifestReceiver(String packageName, String processName, String name, int userId)264 static ResolveInfo makeManifestReceiver(String packageName, String processName, 265 String name, int userId) { 266 final ResolveInfo ri = new ResolveInfo(); 267 ri.activityInfo = new ActivityInfo(); 268 ri.activityInfo.packageName = packageName; 269 ri.activityInfo.processName = processName; 270 ri.activityInfo.name = name; 271 ri.activityInfo.applicationInfo = makeApplicationInfo(packageName, processName, userId); 272 return ri; 273 } 274 makeRegisteredReceiver(ProcessRecord app)275 BroadcastFilter makeRegisteredReceiver(ProcessRecord app) { 276 return makeRegisteredReceiver(app, 0); 277 } 278 makeRegisteredReceiver(ProcessRecord app, int priority)279 BroadcastFilter makeRegisteredReceiver(ProcessRecord app, int priority) { 280 final ReceiverList receiverList = mRegisteredReceivers.get(app.getPid()); 281 return makeRegisteredReceiver(receiverList, priority); 282 } 283 makeRegisteredReceiver(ReceiverList receiverList, int priority)284 static BroadcastFilter makeRegisteredReceiver(ReceiverList receiverList, int priority) { 285 final IntentFilter filter = new IntentFilter(); 286 filter.setPriority(priority); 287 final BroadcastFilter res = new BroadcastFilter(filter, receiverList, 288 receiverList.app.info.packageName, null, null, null, receiverList.uid, 289 receiverList.userId, false, false, true); 290 receiverList.add(res); 291 return res; 292 } 293 setProcessFreezable(ProcessRecord app, boolean pendingFreeze, boolean frozen)294 void setProcessFreezable(ProcessRecord app, boolean pendingFreeze, boolean frozen) { 295 app.mOptRecord.setPendingFreeze(pendingFreeze); 296 app.mOptRecord.setFrozen(frozen); 297 } 298 } 299