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 17 package com.android.systemui.controls.management 18 19 import android.app.ActivityManager 20 import android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND 21 import android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE 22 import android.content.ComponentName 23 import android.content.Context 24 import android.content.ContextWrapper 25 import android.content.Intent 26 import android.content.pm.PackageManager 27 import android.os.UserHandle 28 import android.service.controls.Control 29 import android.service.controls.ControlsProviderService 30 import android.testing.AndroidTestingRunner 31 import androidx.test.filters.SmallTest 32 import com.android.systemui.SysuiTestCase 33 import org.junit.Assert.assertEquals 34 import org.junit.Assert.assertFalse 35 import org.junit.Assert.assertNull 36 import org.junit.Assert.assertTrue 37 import org.junit.Assert.fail 38 import org.junit.Before 39 import org.junit.Test 40 import org.junit.runner.RunWith 41 import org.mockito.ArgumentMatchers.anyInt 42 import org.mockito.ArgumentMatchers.anyString 43 import org.mockito.ArgumentMatchers.eq 44 import org.mockito.Mock 45 import org.mockito.Mockito.`when` 46 import org.mockito.MockitoAnnotations 47 48 @SmallTest 49 @RunWith(AndroidTestingRunner::class) 50 class ControlsRequestReceiverTest : SysuiTestCase() { 51 52 @Mock 53 private lateinit var packageManager: PackageManager 54 @Mock 55 private lateinit var activityManager: ActivityManager 56 @Mock 57 private lateinit var control: Control 58 59 private val componentName = ComponentName("test_pkg", "test_cls") 60 private lateinit var receiver: ControlsRequestReceiver 61 private lateinit var wrapper: MyWrapper 62 private lateinit var intent: Intent 63 64 @Before 65 fun setUp() { 66 MockitoAnnotations.initMocks(this) 67 68 mContext.setMockPackageManager(packageManager) 69 `when`(packageManager.hasSystemFeature(PackageManager.FEATURE_CONTROLS)).thenReturn(true) 70 mContext.addMockSystemService(ActivityManager::class.java, activityManager) 71 72 receiver = ControlsRequestReceiver() 73 74 wrapper = MyWrapper(context) 75 76 intent = Intent(ControlsProviderService.ACTION_ADD_CONTROL).apply { 77 putExtra(Intent.EXTRA_COMPONENT_NAME, componentName) 78 putExtra(ControlsProviderService.EXTRA_CONTROL, control) 79 } 80 } 81 82 @Test 83 fun testPackageVerification_nonExistentPackage() { 84 `when`(packageManager.getPackageUid(anyString(), anyInt())) 85 .thenThrow(PackageManager.NameNotFoundException::class.java) 86 87 assertFalse(ControlsRequestReceiver.isPackageInForeground(mContext, "TEST")) 88 } 89 90 @Test 91 fun testPackageVerification_uidNotInForeground() { 92 `when`(packageManager.getPackageUid(anyString(), anyInt())).thenReturn(12345) 93 94 `when`(activityManager.getUidImportance(anyInt())).thenReturn(IMPORTANCE_GONE) 95 96 assertFalse(ControlsRequestReceiver.isPackageInForeground(mContext, "TEST")) 97 } 98 99 @Test 100 fun testPackageVerification_OK() { 101 `when`(packageManager.getPackageUid(anyString(), anyInt())).thenReturn(12345) 102 103 `when`(activityManager.getUidImportance(anyInt())).thenReturn(IMPORTANCE_GONE) 104 `when`(activityManager.getUidImportance(12345)).thenReturn(IMPORTANCE_FOREGROUND) 105 106 assertTrue(ControlsRequestReceiver.isPackageInForeground(mContext, "TEST")) 107 } 108 109 @Test 110 fun testOnReceive_packageNotVerified_nameNotFound() { 111 `when`(packageManager.getPackageUid(eq(componentName.packageName), anyInt())) 112 .thenThrow(PackageManager.NameNotFoundException::class.java) 113 114 receiver.onReceive(wrapper, intent) 115 116 assertNull(wrapper.intent) 117 } 118 119 @Test 120 fun testOnReceive_packageNotVerified_notForeground() { 121 `when`(packageManager.getPackageUid(eq(componentName.packageName), anyInt())) 122 .thenReturn(12345) 123 124 `when`(activityManager.getUidImportance(anyInt())).thenReturn(IMPORTANCE_GONE) 125 126 receiver.onReceive(wrapper, intent) 127 128 assertNull(wrapper.intent) 129 } 130 131 @Test 132 fun testOnReceive_OK() { 133 `when`(packageManager.getPackageUid(eq(componentName.packageName), anyInt())) 134 .thenReturn(12345) 135 136 `when`(activityManager.getUidImportance(eq(12345))).thenReturn(IMPORTANCE_FOREGROUND) 137 138 receiver.onReceive(wrapper, intent) 139 140 wrapper.intent?.let { 141 assertEquals(ComponentName(wrapper, ControlsRequestDialog::class.java), it.component) 142 143 assertEquals(control, it.getParcelableExtra(ControlsProviderService.EXTRA_CONTROL)) 144 145 assertEquals(componentName, it.getParcelableExtra(Intent.EXTRA_COMPONENT_NAME)) 146 } ?: run { fail("Null start intent") } 147 } 148 149 @Test 150 fun testFeatureDisabled_activityNotStarted() { 151 `when`(packageManager.hasSystemFeature(PackageManager.FEATURE_CONTROLS)).thenReturn(false) 152 receiver.onReceive(wrapper, intent) 153 154 assertNull(wrapper.intent) 155 } 156 157 @Test 158 fun testClassCastExceptionComponentName_noCrash() { 159 val badIntent = Intent(ControlsProviderService.ACTION_ADD_CONTROL).apply { 160 putExtra(Intent.EXTRA_COMPONENT_NAME, Intent()) 161 putExtra(ControlsProviderService.EXTRA_CONTROL, control) 162 } 163 receiver.onReceive(wrapper, badIntent) 164 165 assertNull(wrapper.intent) 166 } 167 168 @Test 169 fun testClassCastExceptionControl_noCrash() { 170 val badIntent = Intent(ControlsProviderService.ACTION_ADD_CONTROL).apply { 171 putExtra(Intent.EXTRA_COMPONENT_NAME, componentName) 172 putExtra(ControlsProviderService.EXTRA_CONTROL, Intent()) 173 } 174 receiver.onReceive(wrapper, badIntent) 175 176 assertNull(wrapper.intent) 177 } 178 179 class MyWrapper(context: Context) : ContextWrapper(context) { 180 var intent: Intent? = null 181 182 override fun startActivityAsUser(intent: Intent, user: UserHandle) { 183 // Always launch activity as system 184 assertTrue(user == UserHandle.SYSTEM) 185 this.intent = intent 186 } 187 188 override fun startActivity(intent: Intent) { 189 this.intent = intent 190 } 191 } 192 }