1 /* <lambda>null2 * Copyright (C) 2021 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 android.permission5.cts 17 18 import android.Manifest 19 import android.app.AppOpsManager 20 import android.app.Instrumentation 21 import android.content.AttributionSource 22 import android.content.ComponentName 23 import android.content.ContentValues 24 import android.content.Context 25 import android.content.ContextParams 26 import android.content.Intent 27 import android.content.pm.PackageManager.FEATURE_LEANBACK 28 import android.net.Uri 29 import android.os.Bundle 30 import android.os.Process 31 import android.os.RemoteCallback 32 import android.os.SystemClock 33 import android.os.UserHandle 34 import android.permission.PermissionManager 35 import android.platform.test.annotations.AppModeFull 36 import android.provider.CalendarContract 37 import android.provider.CallLog 38 import android.provider.ContactsContract 39 import android.provider.Telephony 40 import android.speech.RecognitionListener 41 import android.speech.SpeechRecognizer 42 import androidx.test.platform.app.InstrumentationRegistry 43 import com.android.compatibility.common.util.SystemUtil 44 import com.google.common.truth.Truth.assertThat 45 import org.junit.After 46 import org.junit.Assume.assumeFalse 47 import org.junit.Before 48 import org.junit.Test 49 import org.mockito.ArgumentMatcher 50 import org.mockito.Mockito.eq 51 import org.mockito.Mockito.inOrder 52 import org.mockito.Mockito.intThat 53 import org.mockito.Mockito.isNull 54 import org.mockito.Mockito.mock 55 import java.util.concurrent.CountDownLatch 56 import java.util.concurrent.TimeUnit 57 import java.util.concurrent.atomic.AtomicReference 58 import java.util.concurrent.locks.ReentrantLock 59 import java.util.function.Consumer 60 61 @AppModeFull(reason = "Instant apps cannot hold READ_CONTACTS/READ_CALENDAR/READ_SMS/READ_CALL_LOG") 62 class RuntimePermissionsAppOpTrackingTest { 63 64 @Before 65 fun setUpTest() { 66 val appOpsManager = context.getSystemService(AppOpsManager::class.java)!! 67 SystemUtil.runWithShellPermissionIdentity { 68 appOpsManager.clearHistory() 69 appOpsManager.setHistoryParameters( 70 AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE, 71 SNAPSHOT_INTERVAL_MILLIS, 72 INTERVAL_COMPRESSION_MULTIPLIER) 73 74 appOpsManager.resetPackageOpsNoHistory(context.packageName) 75 appOpsManager.resetPackageOpsNoHistory(SHELL_PACKAGE_NAME) 76 appOpsManager.resetPackageOpsNoHistory(RECEIVER_PACKAGE_NAME) 77 appOpsManager.resetPackageOpsNoHistory(RECEIVER2_PACKAGE_NAME) 78 } 79 } 80 81 @After 82 fun tearDownTest() { 83 val appOpsManager = context.getSystemService(AppOpsManager::class.java)!! 84 SystemUtil.runWithShellPermissionIdentity { 85 appOpsManager.clearHistory() 86 appOpsManager.resetHistoryParameters() 87 } 88 } 89 90 @Test 91 @Throws(Exception::class) 92 fun testSelfContactsAccess() { 93 testSelfAccess(ContactsContract.Contacts.CONTENT_URI, 94 Manifest.permission.READ_CONTACTS) 95 } 96 97 @Test 98 @Throws(Exception::class) 99 fun testSelfCalendarAccess() { 100 testSelfAccess(CalendarContract.Calendars.CONTENT_URI, 101 Manifest.permission.READ_CALENDAR) 102 } 103 104 @Test 105 @Throws(Exception::class) 106 fun testSelfSmsAccess() { 107 assumeNotTv() 108 testSelfAccess(Telephony.Sms.CONTENT_URI, 109 Manifest.permission.READ_SMS) 110 } 111 112 @Test 113 @Throws(Exception::class) 114 fun testSelfCallLogAccess() { 115 testSelfAccess(CallLog.Calls.CONTENT_URI, 116 Manifest.permission.READ_CALL_LOG) 117 } 118 119 @Throws(Exception::class) 120 private fun testSelfAccess(uri: Uri, permission: String) { 121 val context = createAttributionContext(ACCESSOR_ATTRIBUTION_TAG, null, null) 122 val beginEndMillis = System.currentTimeMillis() 123 context.contentResolver.query(uri, null, null, null)!!.close() 124 val endTimeMillis = System.currentTimeMillis() 125 126 assertNotRunningOpAccess(AppOpsManager.permissionToOp(permission)!!, 127 beginEndMillis, endTimeMillis, context.attributionSource, 128 /*accessorForeground*/ true, /*receiverForeground*/ false, 129 /*accessorTrusted*/ true, /*accessorAccessCount*/ 1, 130 /*receiverAccessCount*/ 0, /*checkAccessor*/ true, 131 /*fromDatasource*/ false) 132 } 133 134 @Test 135 @Throws(Exception::class) 136 fun testSelfCalendarWrite() { 137 testSelfWrite(CalendarContract.Calendars.CONTENT_URI, 138 Manifest.permission.WRITE_CALENDAR) 139 } 140 141 @Test 142 @Throws(Exception::class) 143 fun testSelfCallLogWrite() { 144 testSelfWrite(CallLog.Calls.CONTENT_URI, 145 Manifest.permission.WRITE_CALL_LOG) 146 } 147 148 @Throws(Exception::class) 149 private fun testSelfWrite(uri: Uri, permission: String) { 150 val context = createAttributionContext(ACCESSOR_ATTRIBUTION_TAG, null, null) 151 val beginEndMillis = System.currentTimeMillis() 152 context.contentResolver.insert(uri, ContentValues()) 153 val endTimeMillis = System.currentTimeMillis() 154 155 assertNotRunningOpAccess(AppOpsManager.permissionToOp(permission)!!, 156 beginEndMillis, endTimeMillis, context.attributionSource, 157 /*accessorForeground*/ true, /*receiverForeground*/ false, 158 /*accessorTrusted*/ true, /*accessorAccessCount*/ 1, 159 /*receiverAccessCount*/ 0, /*checkAccessor*/ true, 160 /*fromDatasource*/ false) 161 } 162 163 @Test 164 @Throws(Exception::class) 165 fun testUntrustedContactsAccessAttributeToAnother() { 166 testUntrustedAccessAttributeToAnother(ContactsContract.Contacts.CONTENT_URI, 167 Manifest.permission.READ_CONTACTS) 168 } 169 170 @Test 171 @Throws(Exception::class) 172 fun testUntrustedCalendarAccessAttributeToAnother() { 173 testUntrustedAccessAttributeToAnother(CalendarContract.Calendars.CONTENT_URI, 174 Manifest.permission.READ_CALENDAR) 175 } 176 177 @Test 178 @Throws(Exception::class) 179 fun testUntrustedSmsAccessAttributeToAnother() { 180 assumeNotTv() 181 testUntrustedAccessAttributeToAnother(Telephony.Sms.CONTENT_URI, 182 Manifest.permission.READ_SMS) 183 } 184 185 @Test 186 @Throws(Exception::class) 187 fun testUntrustedCallLogAccessAttributeToAnother() { 188 testUntrustedAccessAttributeToAnother(CallLog.Calls.CONTENT_URI, 189 Manifest.permission.READ_CALL_LOG) 190 } 191 192 @Throws(Exception::class) 193 private fun testUntrustedAccessAttributeToAnother(uri: Uri, permission: String) { 194 val context = createAttributionContext(ACCESSOR_ATTRIBUTION_TAG, 195 RECEIVER_PACKAGE_NAME, RECEIVER_ATTRIBUTION_TAG) 196 val beginEndMillis = System.currentTimeMillis() 197 context.contentResolver.query(uri, null, null, null)!!.close() 198 val endTimeMillis = System.currentTimeMillis() 199 200 assertNotRunningOpAccess(AppOpsManager.permissionToOp(permission)!!, 201 beginEndMillis, endTimeMillis, context.attributionSource, 202 /*accessorForeground*/ true, /*receiverForeground*/ false, 203 /*accessorTrusted*/ false, /*accessorAccessCount*/ 1, 204 /*receiverAccessCount*/ 1, /*checkAccessor*/ false, 205 /*fromDatasource*/ false) 206 } 207 208 @Test 209 @Throws(Exception::class) 210 fun testUntrustedContactsAccessAttributeToAnotherThroughIntermediary() { 211 testUntrustedAccessAttributeToAnotherThroughIntermediary( 212 ContactsContract.Contacts.CONTENT_URI, 213 Manifest.permission.READ_CONTACTS) 214 } 215 216 @Test 217 @Throws(Exception::class) 218 fun testUntrustedCalendarAccessAttributeToAnotherThroughIntermediary() { 219 testUntrustedAccessAttributeToAnotherThroughIntermediary( 220 CalendarContract.Calendars.CONTENT_URI, 221 Manifest.permission.READ_CALENDAR) 222 } 223 224 @Test 225 @Throws(Exception::class) 226 fun testUntrustedSmsAccessAttributeToAnotherThroughIntermediary() { 227 assumeNotTv() 228 testUntrustedAccessAttributeToAnotherThroughIntermediary( 229 Telephony.Sms.CONTENT_URI, 230 Manifest.permission.READ_SMS) 231 } 232 233 @Test 234 @Throws(Exception::class) 235 fun testUntrustedCallLogAccessAttributeToAnotherThroughIntermediary() { 236 testUntrustedAccessAttributeToAnotherThroughIntermediary( 237 CallLog.Calls.CONTENT_URI, 238 Manifest.permission.READ_CALL_LOG) 239 } 240 241 @Throws(Exception::class) 242 private fun testUntrustedAccessAttributeToAnotherThroughIntermediary( 243 uri: Uri, 244 permission: String 245 ) { 246 runWithAuxiliaryApps { 247 val nextAttributionSource = startBlamedAppActivity() 248 249 val intermediaryContext = context.createContext(ContextParams.Builder() 250 .setNextAttributionSource(nextAttributionSource) 251 .setAttributionTag(ACCESSOR_ATTRIBUTION_TAG) 252 .build()) 253 254 val beginEndMillis = System.currentTimeMillis() 255 intermediaryContext.contentResolver.query(uri, null, null, null)!!.close() 256 val endTimeMillis = System.currentTimeMillis() 257 258 // Assert first stage access 259 assertNotRunningOpAccess(AppOpsManager.permissionToOp(permission)!!, 260 beginEndMillis, endTimeMillis, intermediaryContext.attributionSource, 261 /*accessorForeground*/ true, /*receiverForeground*/ true, 262 /*accessorTrusted*/ false, /*accessorAccessCount*/ 1, 263 /*receiverAccessCount*/ 1, /*checkAccessor*/ false, 264 /*fromDatasource*/ false) 265 266 // Assert second stage access 267 assertNotRunningOpAccess(AppOpsManager.permissionToOp(permission)!!, 268 beginEndMillis, endTimeMillis, nextAttributionSource, 269 /*accessorForeground*/ true, /*receiverForeground*/ false, 270 /*accessorTrusted*/ false, /*accessorAccessCount*/ 1, 271 /*receiverAccessCount*/ 1, /*checkAccessor*/ false, 272 /*fromDatasource*/ false) 273 } 274 } 275 276 @Test(expected = SecurityException::class) 277 fun testCannotForgeAttributionSource() { 278 val receiverSource = AttributionSource(context 279 .packageManager.getPackageUid(RECEIVER2_PACKAGE_NAME, 0), 280 RECEIVER2_PACKAGE_NAME, RECEIVER2_ATTRIBUTION_TAG, null, AttributionSource( 281 context.packageManager.getPackageUid(RECEIVER_PACKAGE_NAME, 0), 282 RECEIVER_PACKAGE_NAME, RECEIVER_ATTRIBUTION_TAG)) 283 val intermediaryContext = context.createContext(ContextParams.Builder() 284 .setNextAttributionSource(receiverSource) 285 .setAttributionTag(ACCESSOR_ATTRIBUTION_TAG) 286 .build()) 287 intermediaryContext.contentResolver.query(CallLog.Calls.CONTENT_URI, null, 288 null, null)!!.close() 289 } 290 291 @Test(expected = SecurityException::class) 292 fun testCannotAppendToForgeAttributionSource() { 293 runWithAuxiliaryApps { 294 val nextAttributionSource = startBlamedAppActivity() 295 val untrustedAttributionSource = AttributionSource(context 296 .packageManager.getPackageUid(RECEIVER2_PACKAGE_NAME, 0), 297 RECEIVER2_PACKAGE_NAME, RECEIVER2_ATTRIBUTION_TAG, null, 298 nextAttributionSource) 299 val intermediaryContext = context.createContext(ContextParams.Builder() 300 .setNextAttributionSource(untrustedAttributionSource) 301 .setAttributionTag(ACCESSOR_ATTRIBUTION_TAG) 302 .build()) 303 intermediaryContext.contentResolver.query(CallLog.Calls.CONTENT_URI, null, 304 null, null)!!.close() 305 } 306 } 307 308 @Test 309 @Throws(Exception::class) 310 fun testTrustedAccessContactsAttributeToAnother() { 311 testTrustedAccessAttributeToAnother(ContactsContract.Contacts.CONTENT_URI, 312 Manifest.permission.READ_CONTACTS) 313 } 314 315 @Test 316 @Throws(Exception::class) 317 fun testTrustedAccessCalendarAttributeToAnother() { 318 testTrustedAccessAttributeToAnother(CalendarContract.Calendars.CONTENT_URI, 319 Manifest.permission.READ_CALENDAR) 320 } 321 322 @Test 323 @Throws(Exception::class) 324 fun testTrustedAccessSmsAttributeToAnother() { 325 assumeNotTv() 326 testTrustedAccessAttributeToAnother(Telephony.Sms.CONTENT_URI, 327 Manifest.permission.READ_SMS) 328 } 329 330 @Test 331 @Throws(Exception::class) 332 fun testTrustedAccessCallLogAttributeToAnother() { 333 testTrustedAccessAttributeToAnother(CallLog.Calls.CONTENT_URI, 334 Manifest.permission.READ_CALL_LOG) 335 } 336 337 @Throws(Exception::class) 338 private fun testTrustedAccessAttributeToAnother(uri: Uri, permission: String) { 339 val context = createAttributionContext(ACCESSOR_ATTRIBUTION_TAG, 340 RECEIVER_PACKAGE_NAME, RECEIVER_ATTRIBUTION_TAG) 341 val beginEndMillis = System.currentTimeMillis() 342 SystemUtil.runWithShellPermissionIdentity { 343 context.contentResolver.query(uri, null, null, null)!!.close() 344 } 345 val endTimeMillis = System.currentTimeMillis() 346 347 // Calculate the shellUid to account for running this from a secondary user. 348 val shellUid = UserHandle.getUid(Process.myUserHandle().identifier, 349 UserHandle.getAppId(Process.SHELL_UID)) 350 // Since we use adopt the shell permission identity we need to adjust 351 // the permission identity to have the shell as the accessor. 352 assertNotRunningOpAccess(AppOpsManager.permissionToOp(permission)!!, 353 beginEndMillis, endTimeMillis, AttributionSource(shellUid, 354 SHELL_PACKAGE_NAME, context.attributionTag, null, 355 context.attributionSource.next), 356 /*accessorForeground*/ false, /*receiverForeground*/ false, 357 /*accessorTrusted*/ true, /*accessorAccessCount*/ 1, 358 /*receiverAccessCount*/ 1, /*checkAccessor*/ false, 359 /*fromDatasource*/ false) 360 } 361 362 @Test 363 @Throws(Exception::class) 364 fun testMicRecognitionInjectRecoWithoutAttribution() { 365 runWithAuxiliaryApps { 366 startBlamedAppActivity() 367 368 val context = createAttributionContext(ACCESSOR_ATTRIBUTION_TAG, 369 RECEIVER_PACKAGE_NAME, RECEIVER_ATTRIBUTION_TAG) 370 371 val listener = mock(AppOpsManager.OnOpActiveChangedListener::class.java) 372 val appopsManager = context.getSystemService(AppOpsManager::class.java) 373 SystemUtil.runWithShellPermissionIdentity<Unit> { 374 appopsManager!!.startWatchingActive(arrayOf(AppOpsManager.OPSTR_RECORD_AUDIO), 375 context.mainExecutor, listener) 376 } 377 378 val speechStartTime = System.currentTimeMillis() 379 val recognizerRef = AtomicReference<SpeechRecognizer>() 380 var currentOperationComplete = CountDownLatch(1) 381 382 instrumentation.runOnMainSync { 383 val recognizer = SpeechRecognizer.createSpeechRecognizer(context, 384 ComponentName(RECEIVER2_PACKAGE_NAME, RECOGNITION_SERVICE)) 385 386 recognizer.setRecognitionListener(object : RecognitionListener { 387 override fun onReadyForSpeech(params: Bundle?) {} 388 override fun onRmsChanged(rmsdB: Float) {} 389 override fun onBufferReceived(buffer: ByteArray?) { 390 currentOperationComplete.countDown() 391 } 392 override fun onPartialResults(partialResults: Bundle?) {} 393 override fun onEvent(eventType: Int, params: Bundle?) {} 394 override fun onError(error: Int) {} 395 override fun onResults(results: Bundle?) {} 396 override fun onBeginningOfSpeech() {} 397 override fun onEndOfSpeech() {} 398 }) 399 400 val recoIntent = Intent() 401 recoIntent.putExtra(OPERATION, OPERATION_INJECT_RECO_WITHOUT_ATTRIBUTION) 402 recognizer.startListening(recoIntent) 403 404 recognizerRef.set(recognizer) 405 } 406 407 try { 408 currentOperationComplete.await(ASYNC_OPERATION_TIMEOUT_MILLIS, 409 TimeUnit.MILLISECONDS) 410 411 val op = AppOpsManager.permissionToOp(Manifest.permission.RECORD_AUDIO)!! 412 413 assertRunningOpAccess(op, speechStartTime, System.currentTimeMillis(), 414 AttributionSource(context.packageManager.getPackageUid( 415 RECEIVER2_PACKAGE_NAME, 0), RECEIVER2_PACKAGE_NAME, 416 /*attributionTag*/ null, null, context.attributionSource), 417 /*accessorForeground*/ true, /*receiverForeground*/ true, 418 /*accessorTrusted*/ false, /*accessorAccessCount*/ 1, 419 /*receiverAccessCount*/ 1, /*checkAccessor*/ true, 420 /*fromDatasource*/ false) 421 422 assertRunningOpAccess(op, speechStartTime, System.currentTimeMillis(), 423 context.attributionSource, /*accessorForeground*/ true, 424 /*receiverForeground*/ true, /*accessorTrusted*/ false, 425 /*accessorAccessCount*/ 0, /*receiverAccessCount*/ 1, 426 /*checkAccessor*/ false, /*fromDatasource*/ false) 427 428 // Finish recon and check if all ops are finished 429 currentOperationComplete = CountDownLatch(1) 430 instrumentation.runOnMainSync { recognizerRef.get().cancel() } 431 currentOperationComplete.await(ASYNC_OPERATION_TIMEOUT_MILLIS, 432 TimeUnit.MILLISECONDS) 433 434 val recognizerUid = context.packageManager.getPackageUid( 435 RECEIVER2_PACKAGE_NAME, 0) 436 437 assertNotRunningOpAccess(op, speechStartTime, System.currentTimeMillis(), 438 AttributionSource(recognizerUid, RECEIVER2_PACKAGE_NAME, 439 /*attributionTag*/ null, null, context.attributionSource), 440 /*accessorForeground*/ true, /*receiverForeground*/ true, 441 /*accessorTrusted*/ false, /*accessorAccessCount*/ 1, 442 /*receiverAccessCount*/ 1, /*checkAccessor*/ true, 443 /*fromDatasource*/ false) 444 445 assertNotRunningOpAccess(op, speechStartTime, System.currentTimeMillis(), 446 context.attributionSource, /*accessorForeground*/ true, 447 /*receiverForeground*/ true, /*accessorTrusted*/ false, 448 /*accessorAccessCount*/ 0, /*receiverAccessCount*/ 1, 449 /*checkAccessor*/ false, /*fromDatasource*/ false) 450 451 var attributionChainId: Int? = null 452 val inOrder = inOrder(listener) 453 val attributionChainIdMatcher = ArgumentMatcher<Int> { 454 if (attributionChainId == null) { 455 attributionChainId = it 456 return@ArgumentMatcher true 457 } else { 458 return@ArgumentMatcher (attributionChainId == it) 459 } 460 } 461 val receiverUid = context.packageManager.getPackageUid( 462 RECEIVER_PACKAGE_NAME, 0) 463 464 inOrder.verify(listener).onOpActiveChanged(eq(AppOpsManager.OPSTR_RECORD_AUDIO), 465 eq(recognizerUid), eq(RECEIVER2_PACKAGE_NAME), isNull(), eq(true), 466 eq(AppOpsManager.ATTRIBUTION_FLAG_ACCESSOR), 467 intThat(attributionChainIdMatcher)) 468 inOrder.verify(listener).onOpActiveChanged(eq(AppOpsManager.OPSTR_RECORD_AUDIO), 469 eq(Process.myUid()), eq(context.packageName), eq(ACCESSOR_ATTRIBUTION_TAG), 470 eq(true), eq(AppOpsManager.ATTRIBUTION_FLAG_INTERMEDIARY), 471 intThat(attributionChainIdMatcher)) 472 inOrder.verify(listener).onOpActiveChanged(eq(AppOpsManager.OPSTR_RECORD_AUDIO), 473 eq(receiverUid), eq(RECEIVER_PACKAGE_NAME), eq(RECEIVER_ATTRIBUTION_TAG), 474 eq(true), eq(AppOpsManager.ATTRIBUTION_FLAG_RECEIVER), 475 intThat(attributionChainIdMatcher)) 476 477 inOrder.verify(listener).onOpActiveChanged(eq(AppOpsManager.OPSTR_RECORD_AUDIO), 478 eq(recognizerUid), eq(RECEIVER2_PACKAGE_NAME), isNull(), eq(false), 479 eq(AppOpsManager.ATTRIBUTION_FLAG_ACCESSOR), 480 intThat(attributionChainIdMatcher)) 481 inOrder.verify(listener).onOpActiveChanged(eq(AppOpsManager.OPSTR_RECORD_AUDIO), 482 eq(Process.myUid()), eq(context.packageName), eq(ACCESSOR_ATTRIBUTION_TAG), 483 eq(false), eq(AppOpsManager.ATTRIBUTION_FLAG_INTERMEDIARY), 484 intThat(attributionChainIdMatcher)) 485 inOrder.verify(listener).onOpActiveChanged(eq(AppOpsManager.OPSTR_RECORD_AUDIO), 486 eq(receiverUid), eq(RECEIVER_PACKAGE_NAME), eq(RECEIVER_ATTRIBUTION_TAG), 487 eq(false), eq(AppOpsManager.ATTRIBUTION_FLAG_RECEIVER), 488 intThat(attributionChainIdMatcher)) 489 } finally { 490 // Take down the recognition service 491 instrumentation.runOnMainSync { recognizerRef.get().destroy() } 492 } 493 } 494 } 495 496 @Test 497 @Throws(Exception::class) 498 fun testMicRecognitionMicRecoWithAttribution() { 499 runWithAuxiliaryApps { 500 startBlamedAppActivity() 501 502 val context = createAttributionContext(ACCESSOR_ATTRIBUTION_TAG, 503 RECEIVER_PACKAGE_NAME, RECEIVER_ATTRIBUTION_TAG) 504 505 val listener = mock(AppOpsManager.OnOpActiveChangedListener::class.java) 506 val appopsManager = context.getSystemService(AppOpsManager::class.java) 507 SystemUtil.runWithShellPermissionIdentity<Unit> { 508 appopsManager!!.startWatchingActive(arrayOf(AppOpsManager.OPSTR_RECORD_AUDIO), 509 context.mainExecutor, listener) 510 } 511 512 val speechStartTime = System.currentTimeMillis() 513 val recognizerRef = AtomicReference<SpeechRecognizer>() 514 var currentOperationComplete = CountDownLatch(1) 515 516 instrumentation.runOnMainSync { 517 val recognizer = SpeechRecognizer.createSpeechRecognizer(context, 518 ComponentName(RECEIVER2_PACKAGE_NAME, RECOGNITION_SERVICE)) 519 520 recognizer.setRecognitionListener(object : RecognitionListener { 521 override fun onReadyForSpeech(params: Bundle?) {} 522 override fun onRmsChanged(rmsdB: Float) {} 523 override fun onBufferReceived(buffer: ByteArray?) { 524 currentOperationComplete.countDown() 525 } 526 override fun onPartialResults(partialResults: Bundle?) {} 527 override fun onEvent(eventType: Int, params: Bundle?) {} 528 override fun onError(error: Int) {} 529 override fun onResults(results: Bundle?) {} 530 override fun onBeginningOfSpeech() {} 531 override fun onEndOfSpeech() {} 532 }) 533 534 val recoIntent = Intent() 535 recoIntent.putExtra(OPERATION, OPERATION_MIC_RECO_WITH_ATTRIBUTION) 536 recognizer.startListening(recoIntent) 537 538 recognizerRef.set(recognizer) 539 } 540 541 try { 542 currentOperationComplete.await(ASYNC_OPERATION_TIMEOUT_MILLIS, 543 TimeUnit.MILLISECONDS) 544 545 val op = AppOpsManager.permissionToOp(Manifest.permission.RECORD_AUDIO)!! 546 547 assertRunningOpAccess(op, speechStartTime, System.currentTimeMillis(), 548 AttributionSource(context.packageManager.getPackageUid( 549 RECEIVER2_PACKAGE_NAME, 0), RECEIVER2_PACKAGE_NAME, 550 /*attributionTag*/ null, null, context.attributionSource), 551 /*accessorForeground*/ true, /*receiverForeground*/ true, 552 /*accessorTrusted*/ true, /*accessorAccessCount*/ 1, 553 /*receiverAccessCount*/ 1, /*checkAccessor*/ true, 554 /*fromDatasource*/ true) 555 556 assertRunningOpAccess(op, speechStartTime, System.currentTimeMillis(), 557 context.attributionSource, /*accessorForeground*/ true, 558 /*receiverForeground*/ true, /*accessorTrusted*/ true, 559 /*accessorAccessCount*/ 0, /*receiverAccessCount*/ 1, 560 /*checkAccessor*/ false, /*fromDatasource*/ true) 561 562 // Finish recon and check if all ops are finished 563 currentOperationComplete = CountDownLatch(1) 564 instrumentation.runOnMainSync { recognizerRef.get().cancel() } 565 currentOperationComplete.await(ASYNC_OPERATION_TIMEOUT_MILLIS, 566 TimeUnit.MILLISECONDS) 567 568 val recognizerUid = context.packageManager.getPackageUid( 569 RECEIVER2_PACKAGE_NAME, 0) 570 571 assertNotRunningOpAccess(op, speechStartTime, System.currentTimeMillis(), 572 AttributionSource(recognizerUid, RECEIVER2_PACKAGE_NAME, 573 /*attributionTag*/ null, null, context.attributionSource), 574 /*accessorForeground*/ true, /*receiverForeground*/ true, 575 /*accessorTrusted*/ true, /*accessorAccessCount*/ 1, 576 /*receiverAccessCount*/ 1, /*checkAccessor*/ true, 577 /*fromDatasource*/ true) 578 579 assertNotRunningOpAccess(op, speechStartTime, System.currentTimeMillis(), 580 context.attributionSource, /*accessorForeground*/ true, 581 /*receiverForeground*/ true, /*accessorTrusted*/ true, 582 /*accessorAccessCount*/ 0, /*receiverAccessCount*/ 1, 583 /*checkAccessor*/ false, /*fromDatasource*/ true) 584 585 var attributionChainId: Int? = null 586 val inOrder = inOrder(listener) 587 val attributionChainIdMatcher = ArgumentMatcher<Int> { 588 if (attributionChainId == null) { 589 attributionChainId = it 590 return@ArgumentMatcher true 591 } else { 592 return@ArgumentMatcher (attributionChainId == it) 593 } 594 } 595 val receiverUid = context.packageManager.getPackageUid( 596 RECEIVER_PACKAGE_NAME, 0) 597 598 inOrder.verify(listener).onOpActiveChanged(eq(AppOpsManager.OPSTR_RECORD_AUDIO), 599 eq(recognizerUid), eq(RECEIVER2_PACKAGE_NAME), isNull(), eq(true), 600 eq(AppOpsManager.ATTRIBUTION_FLAG_ACCESSOR or ATTRIBUTION_FLAG_TRUSTED), 601 intThat(attributionChainIdMatcher)) 602 inOrder.verify(listener).onOpActiveChanged(eq(AppOpsManager.OPSTR_RECORD_AUDIO), 603 eq(Process.myUid()), eq(context.packageName), eq(ACCESSOR_ATTRIBUTION_TAG), 604 eq(true), eq(AppOpsManager.ATTRIBUTION_FLAG_INTERMEDIARY or 605 ATTRIBUTION_FLAG_TRUSTED), intThat(attributionChainIdMatcher)) 606 inOrder.verify(listener).onOpActiveChanged(eq(AppOpsManager.OPSTR_RECORD_AUDIO), 607 eq(receiverUid), eq(RECEIVER_PACKAGE_NAME), eq(RECEIVER_ATTRIBUTION_TAG), 608 eq(true), eq(AppOpsManager.ATTRIBUTION_FLAG_RECEIVER or 609 ATTRIBUTION_FLAG_TRUSTED), intThat(attributionChainIdMatcher)) 610 611 inOrder.verify(listener).onOpActiveChanged(eq(AppOpsManager.OPSTR_RECORD_AUDIO), 612 eq(recognizerUid), eq(RECEIVER2_PACKAGE_NAME), isNull(), eq(false), 613 eq(AppOpsManager.ATTRIBUTION_FLAG_ACCESSOR or ATTRIBUTION_FLAG_TRUSTED), 614 intThat(attributionChainIdMatcher)) 615 inOrder.verify(listener).onOpActiveChanged(eq(AppOpsManager.OPSTR_RECORD_AUDIO), 616 eq(Process.myUid()), eq(context.packageName), eq(ACCESSOR_ATTRIBUTION_TAG), 617 eq(false), eq(AppOpsManager.ATTRIBUTION_FLAG_INTERMEDIARY or 618 ATTRIBUTION_FLAG_TRUSTED), intThat(attributionChainIdMatcher)) 619 inOrder.verify(listener).onOpActiveChanged(eq(AppOpsManager.OPSTR_RECORD_AUDIO), 620 eq(receiverUid), eq(RECEIVER_PACKAGE_NAME), eq(RECEIVER_ATTRIBUTION_TAG), 621 eq(false), eq(AppOpsManager.ATTRIBUTION_FLAG_RECEIVER or 622 ATTRIBUTION_FLAG_TRUSTED), intThat(attributionChainIdMatcher)) 623 } finally { 624 // Take down the recognition service 625 instrumentation.runOnMainSync { recognizerRef.get().destroy() } 626 } 627 } 628 } 629 630 fun runWithAuxiliaryApps(worker: () -> Unit) { 631 ensureAuxiliaryAppsNotRunningAndNoResidualProcessState() 632 try { 633 worker.invoke() 634 } finally { 635 ensureAuxiliaryAppsNotRunningAndNoResidualProcessState() 636 } 637 } 638 639 companion object { 640 private const val ASYNC_OPERATION_TIMEOUT_MILLIS: Long = 5000 // 5 sec 641 private const val INTERVAL_COMPRESSION_MULTIPLIER = 10 642 private const val SNAPSHOT_INTERVAL_MILLIS: Long = 1000 643 644 val SHELL_PACKAGE_NAME = "com.android.shell" 645 val RECEIVER_PACKAGE_NAME = "android.permission5.cts.blamed" 646 val BRING_TO_FOREGROUND_ACTIVITY = 647 "android.permission5.cts.blamed.BringToForegroundActivity" 648 val RECOGNITION_SERVICE = "android.permission5.cts.blamed2.MyRecognitionService" 649 val REMOTE_CALLBACK = "remote_callback" 650 val ATTRIBUTION_SOURCE = "attribution_source" 651 val ACCESSOR_ATTRIBUTION_TAG = "accessor_attribution_tag" 652 val RECEIVER2_PACKAGE_NAME = "android.permission5.cts.blamed2" 653 val RECEIVER_ATTRIBUTION_TAG = "receiver_attribution_tag" 654 val RECEIVER2_ATTRIBUTION_TAG = "receiver2_attribution_tag" 655 656 val OPERATION = "operation" 657 val OPERATION_MIC_RECO_WITH_ATTRIBUTION = "operation:mic_reco_with_attribution" 658 val OPERATION_INJECT_RECO_WITHOUT_ATTRIBUTION = "operation:inject_reco_without_attribution" 659 660 val ATTRIBUTION_FLAG_TRUSTED = 0x8 661 662 private val context: Context 663 get() = InstrumentationRegistry.getInstrumentation().getContext() 664 665 private val instrumentation: Instrumentation 666 get() = InstrumentationRegistry.getInstrumentation() 667 668 private val isTv = context.packageManager.hasSystemFeature(FEATURE_LEANBACK) 669 670 fun ensureAuxiliaryAppsNotRunningAndNoResidualProcessState() { 671 SystemUtil.runShellCommand("am force-stop $RECEIVER_PACKAGE_NAME") 672 SystemUtil.runShellCommand("am force-stop $RECEIVER2_PACKAGE_NAME") 673 SystemClock.sleep(ASYNC_OPERATION_TIMEOUT_MILLIS) 674 } 675 676 @Throws(Exception::class) 677 private fun assertRunningOpAccess( 678 op: String, 679 beginEndMillis: Long, 680 endTimeMillis: Long, 681 attributionSource: AttributionSource, 682 accessorForeground: Boolean, 683 receiverForeground: Boolean, 684 accessorTrusted: Boolean, 685 accessorAccessCount: Int, 686 receiverAccessCount: Int, 687 checkAccessor: Boolean, 688 fromDatasource: Boolean 689 ) { 690 assertOpAccess(op, beginEndMillis, endTimeMillis, attributionSource, 691 accessorForeground, receiverForeground, accessorTrusted, 692 /*assertRunning*/ true, accessorAccessCount, receiverAccessCount, 693 checkAccessor, fromDatasource) 694 } 695 696 @Throws(Exception::class) 697 private fun assertNotRunningOpAccess( 698 op: String, 699 beginEndMillis: Long, 700 endTimeMillis: Long, 701 attributionSource: AttributionSource, 702 accessorForeground: Boolean, 703 receiverForeground: Boolean, 704 accessorTrusted: Boolean, 705 accessorAccessCount: Int, 706 receiverAccessCount: Int, 707 checkAccessor: Boolean, 708 fromDatasource: Boolean 709 ) { 710 assertOpAccess(op, beginEndMillis, endTimeMillis, attributionSource, 711 accessorForeground, receiverForeground, accessorTrusted, 712 /*assertRunning*/ false, accessorAccessCount, receiverAccessCount, 713 checkAccessor, fromDatasource) 714 } 715 716 @Throws(Exception::class) 717 private fun assertOpAccess( 718 op: String, 719 beginEndMillis: Long, 720 endTimeMillis: Long, 721 attributionSource: AttributionSource, 722 accessorForeground: Boolean, 723 receiverForeground: Boolean, 724 accessorTrusted: Boolean, 725 assertRunning: Boolean, 726 accessorAccessCount: Int, 727 receiverAccessCount: Int, 728 checkAccessor: Boolean, 729 fromDatasource: Boolean 730 ) { 731 assertLastOpAccess(op, beginEndMillis, endTimeMillis, attributionSource, 732 accessorForeground, receiverForeground, accessorTrusted, assertRunning, 733 checkAccessor, fromDatasource) 734 assertHistoricalOpAccess(op, attributionSource, accessorForeground, 735 receiverForeground, accessorTrusted, accessorAccessCount, receiverAccessCount, 736 checkAccessor, fromDatasource) 737 } 738 739 private fun assertLastOpAccess( 740 op: String, 741 beginEndMillis: Long, 742 endTimeMillis: Long, 743 attributionSource: AttributionSource, 744 accessorForeground: Boolean, 745 receiverForeground: Boolean, 746 accessorTrusted: Boolean, 747 assertRunning: Boolean, 748 checkAccessor: Boolean, 749 fromDatasource: Boolean 750 ) { 751 val appOpsManager = context.getSystemService(AppOpsManager::class.java)!! 752 val allPackagesOps: MutableList<AppOpsManager.PackageOps?> = ArrayList() 753 SystemUtil.runWithShellPermissionIdentity<Boolean> { 754 allPackagesOps.addAll(appOpsManager.getPackagesForOps(arrayOf(op))) 755 } 756 if (checkAccessor) { 757 assertLastAccessorOps(op, beginEndMillis, endTimeMillis, attributionSource, 758 accessorForeground, accessorTrusted, assertRunning, fromDatasource, 759 allPackagesOps) 760 } else { 761 assertNotLastAccessorOps(op, attributionSource, allPackagesOps) 762 } 763 if (attributionSource.next != null) { 764 assertLastReceiverOps(op, beginEndMillis, endTimeMillis, attributionSource, 765 receiverForeground, accessorTrusted, assertRunning, allPackagesOps) 766 } 767 } 768 769 @Throws(Exception::class) 770 private fun assertHistoricalOpAccess( 771 op: String, 772 attributionSource: AttributionSource, 773 accessorForeground: Boolean, 774 receiverForeground: Boolean, 775 accessorTrusted: Boolean, 776 accessorAccessCount: Int, 777 receiverAccessCount: Int, 778 checkAccessor: Boolean, 779 fromDatasource: Boolean 780 ) { 781 val appOpsManager = context.getSystemService(AppOpsManager::class.java)!! 782 val request = AppOpsManager.HistoricalOpsRequest.Builder(0, Long.MAX_VALUE) 783 .setOpNames(listOf(op)) 784 .build() 785 val historicalOpsRef = AtomicReference<AppOpsManager.HistoricalOps>() 786 val lock = ReentrantLock() 787 val condition = lock.newCondition() 788 SystemUtil.runWithShellPermissionIdentity { 789 appOpsManager.getHistoricalOps(request, context.mainExecutor, 790 Consumer { historicalOps: AppOpsManager.HistoricalOps -> 791 historicalOpsRef.set(historicalOps) 792 lock.lock() 793 try { 794 condition.signalAll() 795 } finally { 796 lock.unlock() 797 } 798 }) 799 } 800 lock.lock() 801 try { 802 condition.await(ASYNC_OPERATION_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS) 803 } finally { 804 lock.unlock() 805 } 806 807 val historicalOps = historicalOpsRef.get() 808 if (checkAccessor) { 809 assertHistoricalAccessorOps(op, attributionSource, accessorForeground, 810 accessorTrusted, fromDatasource, accessorAccessCount, historicalOps) 811 } else { 812 assertNoHistoricalAccessorOps(op, attributionSource, historicalOps) 813 } 814 if (attributionSource.next != null) { 815 assertHistoricalReceiverOps(op, attributionSource, receiverForeground, 816 accessorTrusted, receiverAccessCount, historicalOps) 817 } 818 } 819 820 private fun assertLastAccessorOps( 821 op: String, 822 beginEndMillis: Long, 823 endTimeMillis: Long, 824 attributionSource: AttributionSource, 825 accessorForeground: Boolean, 826 accessorTrusted: Boolean, 827 assertRunning: Boolean, 828 fromDatasource: Boolean, 829 allPackagesOps: List<AppOpsManager.PackageOps?> 830 ) { 831 val accessorPackageOps = findPackageOps(attributionSource.uid, 832 attributionSource.packageName!!, allPackagesOps) 833 for (opEntry in accessorPackageOps!!.ops) { 834 if (!op.equals(opEntry.opStr)) { 835 continue 836 } 837 val attributedOpEntry = opEntry.attributedOpEntries[ 838 attributionSource.attributionTag] 839 if (attributionSource.next == null) { 840 // Access for ourselves 841 assertLastAccessInRange(attributedOpEntry!!, beginEndMillis, endTimeMillis, 842 AppOpsManager.OP_FLAG_SELF, accessorForeground, assertRunning) 843 } else if (accessorTrusted) { 844 // Access for others and we are trusted. If we got the data from a datasource 845 // the latter is the proxy and we proxied, otherwise we are the proxy. 846 if (fromDatasource) { 847 assertLastAccessInRange(attributedOpEntry!!, beginEndMillis, endTimeMillis, 848 AppOpsManager.OP_FLAG_TRUSTED_PROXIED, accessorForeground, 849 assertRunning) 850 } else { 851 assertLastAccessInRange(attributedOpEntry!!, beginEndMillis, endTimeMillis, 852 AppOpsManager.OP_FLAG_TRUSTED_PROXY, accessorForeground, 853 assertRunning) 854 } 855 } else { 856 // Access for others and we are not trusted. 857 assertLastAccessInRange(attributedOpEntry!!, beginEndMillis, endTimeMillis, 858 AppOpsManager.OP_FLAG_UNTRUSTED_PROXY, accessorForeground, 859 assertRunning) 860 } 861 } 862 } 863 864 private fun assertNotLastAccessorOps( 865 op: String, 866 attributionSource: AttributionSource, 867 allPackagesOps: List<AppOpsManager.PackageOps?> 868 ) { 869 val accessorPackageOps = findPackageOps(attributionSource.uid, 870 attributionSource.packageName!!, allPackagesOps) ?: return 871 for (opEntry in accessorPackageOps.ops) { 872 if (!op.equals(opEntry.opStr)) { 873 continue 874 } 875 val attributedOpEntry = opEntry.attributedOpEntries[ 876 attributionSource.attributionTag] 877 if (attributedOpEntry != null) { 878 assertThat(attributedOpEntry.getLastAccessBackgroundTime( 879 AppOpsManager.OP_FLAG_SELF 880 or AppOpsManager.OP_FLAG_UNTRUSTED_PROXY 881 or AppOpsManager.OP_FLAG_TRUSTED_PROXY)).isEqualTo(-1) 882 assertThat(attributedOpEntry.getLastAccessBackgroundTime( 883 AppOpsManager.OP_FLAG_SELF 884 or AppOpsManager.OP_FLAG_UNTRUSTED_PROXY 885 or AppOpsManager.OP_FLAG_TRUSTED_PROXY)).isEqualTo(-1) 886 } 887 } 888 } 889 890 private fun assertHistoricalAccessorOps( 891 op: String, 892 attributionSource: AttributionSource, 893 accessorForeground: Boolean, 894 accessorTrusted: Boolean, 895 fromDatasource: Boolean, 896 assertedAccessCount: Int, 897 historicalOps: AppOpsManager.HistoricalOps 898 ) { 899 val accessorPackageOps = findPackageOps( 900 attributionSource.uid, attributionSource.packageName!!, 901 historicalOps) 902 val attributedPackageOps = accessorPackageOps?.getAttributedOps( 903 attributionSource.attributionTag) 904 905 val attributedPackageOp = attributedPackageOps!!.getOp(op) 906 if (attributionSource.next == null) { 907 // Access for ourselves 908 assertAccessCount(attributedPackageOp!!, AppOpsManager.OP_FLAG_SELF, 909 accessorForeground, assertedAccessCount) 910 } else if (accessorTrusted) { 911 // Access for others and we are trusted. If we got the data from a datasource it 912 // would blame the accessor in a trusted way 913 if (fromDatasource) { 914 assertAccessCount(attributedPackageOp!!, AppOpsManager.OP_FLAG_TRUSTED_PROXIED, 915 accessorForeground, assertedAccessCount) 916 } else { 917 assertAccessCount(attributedPackageOp!!, AppOpsManager.OP_FLAG_TRUSTED_PROXY, 918 accessorForeground, assertedAccessCount) 919 } 920 } else { 921 // Access for others and we are not trusted 922 assertAccessCount(attributedPackageOp!!, AppOpsManager.OP_FLAG_UNTRUSTED_PROXY, 923 accessorForeground, assertedAccessCount) 924 } 925 } 926 927 private fun assertNoHistoricalAccessorOps( 928 op: String, 929 attributionSource: AttributionSource, 930 historicalOps: AppOpsManager.HistoricalOps 931 ) { 932 val accessorPackageOps = findPackageOps( 933 attributionSource.uid, attributionSource.packageName!!, 934 historicalOps) 935 val attributedPackageOps = accessorPackageOps?.getAttributedOps( 936 attributionSource.attributionTag) ?: return 937 val attributedPackageOp = attributedPackageOps.getOp(op) 938 if (attributedPackageOp != null) { 939 assertThat(attributedPackageOp.getBackgroundAccessCount( 940 AppOpsManager.OP_FLAG_SELF 941 or AppOpsManager.OP_FLAG_UNTRUSTED_PROXY 942 or AppOpsManager.OP_FLAG_TRUSTED_PROXY)).isEqualTo(0) 943 assertThat(attributedPackageOp.getBackgroundAccessCount( 944 AppOpsManager.OP_FLAG_SELF 945 or AppOpsManager.OP_FLAG_UNTRUSTED_PROXY 946 or AppOpsManager.OP_FLAG_TRUSTED_PROXY)).isEqualTo(0) 947 } 948 } 949 950 private fun assertLastReceiverOps( 951 op: String, 952 beginTimeMillis: Long, 953 endTimeMillis: Long, 954 attributionSource: AttributionSource, 955 receiverForeground: Boolean, 956 accessorTrusted: Boolean, 957 assertRunning: Boolean, 958 allPackagesOps: List<AppOpsManager.PackageOps?> 959 ) { 960 val receiverPackageOps = findPackageOps( 961 attributionSource.next!!.uid, 962 attributionSource.next!!.packageName!!, 963 allPackagesOps) 964 for (opEntry in receiverPackageOps!!.ops) { 965 if (op != opEntry.opStr) { 966 continue 967 } 968 val attributedOpEntry = opEntry.attributedOpEntries[ 969 attributionSource.next!!.attributionTag] 970 val opProxyInfo: AppOpsManager.OpEventProxyInfo? 971 opProxyInfo = if (accessorTrusted) { 972 // Received from a trusted accessor. If we got the data from a datasource it 973 // would blame the accessor in a trusted way 974 assertLastAccessInRange(attributedOpEntry!!, beginTimeMillis, endTimeMillis, 975 AppOpsManager.OP_FLAG_TRUSTED_PROXIED, receiverForeground, 976 assertRunning) 977 attributedOpEntry.getLastProxyInfo(AppOpsManager.OP_FLAG_TRUSTED_PROXIED) 978 } else { 979 // Received from an untrusted accessor 980 assertLastAccessInRange(attributedOpEntry!!, beginTimeMillis, endTimeMillis, 981 AppOpsManager.OP_FLAG_UNTRUSTED_PROXIED, receiverForeground, 982 assertRunning) 983 attributedOpEntry.getLastProxyInfo( 984 AppOpsManager.OP_FLAG_UNTRUSTED_PROXIED) 985 } 986 assertThat(opProxyInfo!!.uid).isEqualTo(attributionSource.uid) 987 assertThat(opProxyInfo.packageName).isEqualTo(attributionSource.packageName) 988 assertThat(opProxyInfo.attributionTag).isEqualTo(attributionSource.attributionTag) 989 } 990 } 991 992 private fun assertHistoricalReceiverOps( 993 op: String, 994 attributionSource: AttributionSource, 995 receiverForeground: Boolean, 996 accessorTrusted: Boolean, 997 assertedAccessCount: Int, 998 historicalOps: AppOpsManager.HistoricalOps 999 ) { 1000 val accessorPackageOps = findPackageOps( 1001 attributionSource.next!!.uid, 1002 attributionSource.next!!.packageName!!, 1003 historicalOps) 1004 val attributedPackageOps = accessorPackageOps?.getAttributedOps( 1005 attributionSource.next!!.attributionTag!!) 1006 val attributedPackageOp = attributedPackageOps!!.getOp(op) 1007 if (accessorTrusted) { 1008 // Received from a trusted accessor. 1009 assertAccessCount(attributedPackageOp!!, AppOpsManager.OP_FLAG_TRUSTED_PROXIED, 1010 receiverForeground, assertedAccessCount) 1011 } else { 1012 // Received from an untrusted accessor 1013 assertAccessCount(attributedPackageOp!!, AppOpsManager.OP_FLAG_UNTRUSTED_PROXIED, 1014 receiverForeground, assertedAccessCount) 1015 } 1016 } 1017 1018 private fun assertLastAccessInRange( 1019 opEntry: AppOpsManager.AttributedOpEntry, 1020 beginTimeMillis: Long, 1021 endTimeMillis: Long, 1022 assertedFlag: Int, 1023 assertForeground: Boolean, 1024 assertRunning: Boolean 1025 ) { 1026 assertThat(opEntry.isRunning).isEqualTo(assertRunning) 1027 assertTimeInRangeIfRequired(opEntry, assertedFlag, 1028 AppOpsManager.OP_FLAG_SELF, 1029 assertForeground, beginTimeMillis, endTimeMillis) 1030 assertTimeInRangeIfRequired(opEntry, assertedFlag, 1031 AppOpsManager.OP_FLAG_TRUSTED_PROXY, 1032 assertForeground, beginTimeMillis, endTimeMillis) 1033 assertTimeInRangeIfRequired(opEntry, assertedFlag, 1034 AppOpsManager.OP_FLAG_UNTRUSTED_PROXY, 1035 assertForeground, beginTimeMillis, endTimeMillis) 1036 assertTimeInRangeIfRequired(opEntry, assertedFlag, 1037 AppOpsManager.OP_FLAG_TRUSTED_PROXIED, 1038 assertForeground, beginTimeMillis, endTimeMillis) 1039 assertTimeInRangeIfRequired(opEntry, assertedFlag, 1040 AppOpsManager.OP_FLAG_UNTRUSTED_PROXIED, 1041 assertForeground, beginTimeMillis, endTimeMillis) 1042 if (assertForeground) { 1043 assertThat(opEntry.getLastAccessBackgroundTime(AppOpsManager.OP_FLAGS_ALL)) 1044 .isEqualTo(-1) 1045 } else { 1046 assertThat(opEntry.getLastAccessForegroundTime(AppOpsManager.OP_FLAGS_ALL)) 1047 .isEqualTo(-1) 1048 } 1049 } 1050 1051 private fun assertTimeInRangeIfRequired( 1052 opEntry: AppOpsManager.AttributedOpEntry, 1053 assertedFlag: Int, 1054 accessedFlag: Int, 1055 assertForeground: Boolean, 1056 beginTimeMillis: Long, 1057 endTimeMillis: Long 1058 ) { 1059 if (assertedFlag != accessedFlag) { 1060 return 1061 } 1062 val accessTime: Long 1063 accessTime = if (assertForeground) { 1064 opEntry.getLastAccessForegroundTime(accessedFlag) 1065 } else { 1066 opEntry.getLastAccessBackgroundTime(accessedFlag) 1067 } 1068 assertThat(accessTime).isAtLeast(beginTimeMillis) 1069 assertThat(accessTime).isAtMost(endTimeMillis) 1070 } 1071 1072 private fun assertAccessCount( 1073 historicalOp: AppOpsManager.HistoricalOp, 1074 assertedFlag: Int, 1075 assertForeground: Boolean, 1076 assertedAccessCount: Int 1077 ) { 1078 assertAccessCountIfRequired(historicalOp, AppOpsManager.OP_FLAG_SELF, 1079 assertedFlag, assertForeground, assertedAccessCount) 1080 assertAccessCountIfRequired(historicalOp, AppOpsManager.OP_FLAG_TRUSTED_PROXY, 1081 assertedFlag, assertForeground, assertedAccessCount) 1082 assertAccessCountIfRequired(historicalOp, AppOpsManager.OP_FLAG_UNTRUSTED_PROXY, 1083 assertedFlag, assertForeground, assertedAccessCount) 1084 assertAccessCountIfRequired(historicalOp, AppOpsManager.OP_FLAG_TRUSTED_PROXIED, 1085 assertedFlag, assertForeground, assertedAccessCount) 1086 assertAccessCountIfRequired(historicalOp, AppOpsManager.OP_FLAG_UNTRUSTED_PROXIED, 1087 assertedFlag, assertForeground, assertedAccessCount) 1088 if (assertForeground) { 1089 assertThat(historicalOp.getBackgroundAccessCount( 1090 AppOpsManager.OP_FLAGS_ALL)).isEqualTo(0) 1091 } else { 1092 assertThat(historicalOp.getForegroundAccessCount( 1093 AppOpsManager.OP_FLAGS_ALL)).isEqualTo(0) 1094 } 1095 } 1096 1097 private fun assertAccessCountIfRequired( 1098 historicalOp: AppOpsManager.HistoricalOp, 1099 assertedFlag: Int, 1100 accessedFlag: Int, 1101 assertForeground: Boolean, 1102 assertedAccessCount: Int 1103 ) { 1104 if (assertedFlag != accessedFlag) { 1105 return 1106 } 1107 val accessCount: Long 1108 accessCount = if (assertForeground) { 1109 historicalOp.getForegroundAccessCount(accessedFlag) 1110 } else { 1111 historicalOp.getBackgroundAccessCount(accessedFlag) 1112 } 1113 assertThat(accessCount).isEqualTo(assertedAccessCount) 1114 } 1115 1116 private fun findPackageOps( 1117 uid: Int, 1118 packageName: String, 1119 searchedList: List<AppOpsManager.PackageOps?> 1120 ): AppOpsManager.PackageOps? { 1121 return searchedList.stream() 1122 .filter { packageOps: AppOpsManager.PackageOps? -> 1123 packageOps!!.uid == uid && packageOps.packageName == packageName 1124 } 1125 .findAny() 1126 .orElse(null) 1127 } 1128 1129 private fun findPackageOps( 1130 uid: Int, 1131 packageName: String, 1132 historicalOps: AppOpsManager.HistoricalOps 1133 ): AppOpsManager.HistoricalPackageOps? { 1134 val uidOps = historicalOps.getUidOps(uid) 1135 return uidOps?.getPackageOps(packageName) 1136 } 1137 1138 fun createAttributionContext( 1139 attributionTag: String?, 1140 receiverPackageName: String?, 1141 receiverAttributionTag: String? 1142 ): Context { 1143 val attributionParamsBuilder = ContextParams.Builder() 1144 if (attributionTag != null) { 1145 attributionParamsBuilder.setAttributionTag(attributionTag) 1146 } 1147 if (receiverPackageName != null) { 1148 val attributionSourceBuilder = AttributionSource.Builder( 1149 context.packageManager.getPackageUid(receiverPackageName, 0)) 1150 attributionSourceBuilder.setPackageName(receiverPackageName) 1151 if (receiverAttributionTag != null) { 1152 attributionSourceBuilder.setAttributionTag(receiverAttributionTag) 1153 } 1154 var receiverAttributionSource = attributionSourceBuilder.build() 1155 SystemUtil.runWithShellPermissionIdentity { 1156 receiverAttributionSource = context.getSystemService( 1157 PermissionManager::class.java)!!.registerAttributionSource( 1158 receiverAttributionSource) 1159 } 1160 attributionParamsBuilder.setNextAttributionSource(receiverAttributionSource) 1161 } 1162 return context.createContext(attributionParamsBuilder.build()) 1163 } 1164 1165 fun startBlamedAppActivity(): AttributionSource { 1166 val activityStatedLatch = CountDownLatch(1) 1167 val attributionSourceRef = AtomicReference<AttributionSource>() 1168 val intent = Intent() 1169 intent.setClassName(RECEIVER_PACKAGE_NAME, BRING_TO_FOREGROUND_ACTIVITY) 1170 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP) 1171 intent.putExtra(REMOTE_CALLBACK, RemoteCallback { 1172 attributionSourceRef.set(it?.getParcelable(ATTRIBUTION_SOURCE)) 1173 activityStatedLatch.countDown() 1174 }) 1175 context.startActivity(intent) 1176 activityStatedLatch.await(ASYNC_OPERATION_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS) 1177 return attributionSourceRef.get() 1178 } 1179 1180 private fun assumeNotTv() = assumeFalse(isTv) 1181 } 1182 } 1183