1 /* 2 * Copyright (C) 2019 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 com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; 20 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; 21 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; 22 23 import static org.junit.Assert.assertEquals; 24 import static org.mockito.ArgumentMatchers.anyInt; 25 import static org.mockito.ArgumentMatchers.anyLong; 26 import static org.mockito.ArgumentMatchers.eq; 27 import static org.mockito.Mockito.mock; 28 import static org.mockito.Mockito.when; 29 30 import android.app.ActivityManager; 31 import android.app.ActivityManagerInternal; 32 import android.app.AppGlobals; 33 import android.app.PendingIntent; 34 import android.content.Intent; 35 import android.content.pm.IPackageManager; 36 import android.os.Looper; 37 38 import androidx.test.runner.AndroidJUnit4; 39 40 import com.android.server.AlarmManagerInternal; 41 import com.android.server.LocalServices; 42 43 import org.junit.After; 44 import org.junit.Before; 45 import org.junit.Test; 46 import org.junit.runner.RunWith; 47 import org.mockito.ArgumentCaptor; 48 import org.mockito.Mock; 49 import org.mockito.MockitoSession; 50 import org.mockito.quality.Strictness; 51 52 @RunWith(AndroidJUnit4.class) 53 public class PendingIntentControllerTest { 54 private static final String TEST_PACKAGE_NAME = "test-package-1"; 55 private static final String TEST_FEATURE_ID = "test-feature-1"; 56 private static final int TEST_CALLING_UID = android.os.Process.myUid(); 57 private static final Intent[] TEST_INTENTS = new Intent[]{new Intent("com.test.intent")}; 58 59 @Mock 60 private UserController mUserController; 61 @Mock 62 private AlarmManagerInternal mAlarmManagerInternal; 63 @Mock 64 private ActivityManagerInternal mActivityManagerInternal; 65 @Mock 66 private IPackageManager mIPackageManager; 67 68 private MockitoSession mMockingSession; 69 private PendingIntentController mPendingIntentController; 70 71 @Before setUp()72 public void setUp() throws Exception { 73 mMockingSession = mockitoSession() 74 .initMocks(this) 75 .mockStatic(LocalServices.class) 76 .mockStatic(AppGlobals.class) 77 .strictness(Strictness.LENIENT) // Needed to stub LocalServices.getService twice 78 .startMocking(); 79 doReturn(mAlarmManagerInternal).when( 80 () -> LocalServices.getService(AlarmManagerInternal.class)); 81 doReturn(mActivityManagerInternal).when( 82 () -> LocalServices.getService(ActivityManagerInternal.class)); 83 doReturn(mIPackageManager).when(() -> AppGlobals.getPackageManager()); 84 when(mIPackageManager.getPackageUid(eq(TEST_PACKAGE_NAME), anyLong(), anyInt())).thenReturn( 85 TEST_CALLING_UID); 86 ActivityManagerConstants constants = mock(ActivityManagerConstants.class); 87 constants.PENDINGINTENT_WARNING_THRESHOLD = 2000; 88 mPendingIntentController = new PendingIntentController(Looper.getMainLooper(), 89 mUserController, constants); 90 mPendingIntentController.onActivityManagerInternalAdded(); 91 } 92 createPendingIntentRecord(int flags)93 private PendingIntentRecord createPendingIntentRecord(int flags) { 94 return mPendingIntentController.getIntentSender(ActivityManager.INTENT_SENDER_BROADCAST, 95 TEST_PACKAGE_NAME, TEST_FEATURE_ID, TEST_CALLING_UID, 0, null, null, 0, 96 TEST_INTENTS, null, flags, null); 97 } 98 99 @Test alarmsRemovedOnCancel()100 public void alarmsRemovedOnCancel() { 101 final PendingIntentRecord pir = createPendingIntentRecord(0); 102 mPendingIntentController.cancelIntentSender(pir); 103 final ArgumentCaptor<PendingIntent> piCaptor = ArgumentCaptor.forClass(PendingIntent.class); 104 verify(mAlarmManagerInternal).remove(piCaptor.capture()); 105 assertEquals("Wrong target for pending intent passed to alarm manager", pir, 106 piCaptor.getValue().getTarget()); 107 } 108 109 @Test alarmsRemovedOnRecreateWithCancelCurrent()110 public void alarmsRemovedOnRecreateWithCancelCurrent() { 111 final PendingIntentRecord pir = createPendingIntentRecord(0); 112 createPendingIntentRecord(PendingIntent.FLAG_CANCEL_CURRENT); 113 final ArgumentCaptor<PendingIntent> piCaptor = ArgumentCaptor.forClass(PendingIntent.class); 114 verify(mAlarmManagerInternal).remove(piCaptor.capture()); 115 assertEquals("Wrong target for pending intent passed to alarm manager", pir, 116 piCaptor.getValue().getTarget()); 117 } 118 119 @Test alarmsRemovedOnSendingOneShot()120 public void alarmsRemovedOnSendingOneShot() { 121 final PendingIntentRecord pir = createPendingIntentRecord(PendingIntent.FLAG_ONE_SHOT); 122 pir.send(0, null, null, null, null, null, null); 123 final ArgumentCaptor<PendingIntent> piCaptor = ArgumentCaptor.forClass(PendingIntent.class); 124 verify(mAlarmManagerInternal).remove(piCaptor.capture()); 125 assertEquals("Wrong target for pending intent passed to alarm manager", pir, 126 piCaptor.getValue().getTarget()); 127 } 128 129 @After tearDown()130 public void tearDown() { 131 if (mMockingSession != null) { 132 mMockingSession.finishMocking(); 133 } 134 } 135 } 136