1 /* 2 * Copyright (C) 2016 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.cts.ephemeralapp1; 18 19 import static android.media.AudioFormat.CHANNEL_IN_MONO; 20 import static android.media.AudioFormat.ENCODING_PCM_16BIT; 21 import static android.media.MediaRecorder.AudioSource.MIC; 22 23 import static org.hamcrest.CoreMatchers.equalTo; 24 import static org.hamcrest.CoreMatchers.hasItems; 25 import static org.hamcrest.CoreMatchers.is; 26 import static org.hamcrest.CoreMatchers.not; 27 import static org.hamcrest.CoreMatchers.notNullValue; 28 import static org.hamcrest.CoreMatchers.nullValue; 29 import static org.junit.Assert.assertSame; 30 import static org.junit.Assert.assertThat; 31 import static org.junit.Assert.fail; 32 import static org.testng.Assert.assertNull; 33 import static org.testng.Assert.assertThrows; 34 35 import android.Manifest; 36 import android.app.NotificationChannel; 37 import android.app.NotificationManager; 38 import android.app.SearchManager; 39 import android.app.SearchableInfo; 40 import android.content.ActivityNotFoundException; 41 import android.content.BroadcastReceiver; 42 import android.content.ComponentName; 43 import android.content.Context; 44 import android.content.Intent; 45 import android.content.IntentFilter; 46 import android.content.ServiceConnection; 47 import android.content.pm.ActivityInfo; 48 import android.content.pm.ChangedPackages; 49 import android.content.pm.PackageInfo; 50 import android.content.pm.PackageManager; 51 import android.content.pm.ProviderInfo; 52 import android.content.pm.ResolveInfo; 53 import android.database.Cursor; 54 import android.hardware.camera2.CameraDevice; 55 import android.hardware.camera2.CameraManager; 56 import android.location.Criteria; 57 import android.location.LocationManager; 58 import android.media.AudioRecord; 59 import android.net.ConnectivityManager; 60 import android.net.Uri; 61 import android.os.Build; 62 import android.os.Bundle; 63 import android.os.Handler; 64 import android.os.HandlerThread; 65 import android.os.IBinder; 66 import android.os.PowerManager; 67 import android.os.PowerManager.WakeLock; 68 import android.os.VibrationEffect; 69 import android.os.Vibrator; 70 import android.telephony.PhoneStateListener; 71 import android.telephony.TelephonyManager; 72 73 import androidx.test.InstrumentationRegistry; 74 import androidx.test.runner.AndroidJUnit4; 75 import android.platform.test.annotations.AsbSecurityTest; 76 77 import com.android.cts.util.TestResult; 78 79 import org.junit.After; 80 import org.junit.Before; 81 import org.junit.Test; 82 import org.junit.runner.RunWith; 83 84 import java.io.IOException; 85 import java.util.Arrays; 86 import java.util.Iterator; 87 import java.util.List; 88 import java.util.concurrent.CountDownLatch; 89 import java.util.concurrent.SynchronousQueue; 90 import java.util.concurrent.TimeUnit; 91 92 @RunWith(AndroidJUnit4.class) 93 public class ClientTest { 94 /** Action to start normal test activities */ 95 private static final String ACTION_START_NORMAL = 96 "com.android.cts.ephemeraltest.START_NORMAL"; 97 /** Action to start normal, exposed test activities */ 98 private static final String ACTION_START_EXPOSED = 99 "com.android.cts.ephemeraltest.START_EXPOSED"; 100 /** Action to start ephemeral test activities */ 101 private static final String ACTION_START_EPHEMERAL = 102 "com.android.cts.ephemeraltest.START_EPHEMERAL"; 103 /** Action to start private ephemeral test activities */ 104 private static final String ACTION_START_EPHEMERAL_PRIVATE = 105 "com.android.cts.ephemeraltest.START_EPHEMERAL_PRIVATE"; 106 private static final String ACTION_START_EPHEMERAL_ACTIVITY = 107 "com.android.cts.ephemeraltest.START_OTHER_EPHEMERAL"; 108 /** Action to query for test activities */ 109 private static final String ACTION_QUERY = 110 "com.android.cts.ephemeraltest.QUERY"; 111 private static final String EXTRA_ACTIVITY_NAME = 112 "com.android.cts.ephemeraltest.EXTRA_ACTIVITY_NAME"; 113 private static final String EXTRA_ACTIVITY_RESULT = 114 "com.android.cts.ephemeraltest.EXTRA_ACTIVITY_RESULT"; 115 116 private BroadcastReceiver mReceiver; 117 private PhoneStateListener mPhoneStateListener; 118 private final SynchronousQueue<TestResult> mResultQueue = new SynchronousQueue<>(); 119 120 @Before setUp()121 public void setUp() throws Exception { 122 final IntentFilter filter = 123 new IntentFilter("com.android.cts.ephemeraltest.START_ACTIVITY"); 124 filter.addCategory(Intent.CATEGORY_DEFAULT); 125 mReceiver = new ActivityBroadcastReceiver(mResultQueue); 126 InstrumentationRegistry.getContext() 127 .registerReceiver(mReceiver, filter, Context.RECEIVER_VISIBLE_TO_INSTANT_APPS); 128 } 129 130 @After tearDown()131 public void tearDown() throws Exception { 132 InstrumentationRegistry.getContext().unregisterReceiver(mReceiver); 133 } 134 135 @Test testQuery()136 public void testQuery() throws Exception { 137 // query normal activities 138 { 139 final Intent queryIntent = new Intent(ACTION_QUERY); 140 final List<ResolveInfo> resolveInfo = InstrumentationRegistry.getContext() 141 .getPackageManager().queryIntentActivities(queryIntent, 0 /*flags*/); 142 if (resolveInfo == null || resolveInfo.size() == 0) { 143 fail("didn't resolve any intents"); 144 } 145 assertThat(resolveInfo.size(), is(2)); 146 assertThat(resolveInfo.get(0).activityInfo.packageName, 147 is("com.android.cts.ephemeralapp1")); 148 assertThat(resolveInfo.get(0).activityInfo.name, 149 is("com.android.cts.ephemeralapp1.EphemeralActivity")); 150 assertThat(resolveInfo.get(0).isInstantAppAvailable, 151 is(true)); 152 assertThat(resolveInfo.get(1).activityInfo.packageName, 153 is("com.android.cts.normalapp")); 154 assertThat(resolveInfo.get(1).activityInfo.name, 155 is("com.android.cts.normalapp.ExposedActivity")); 156 assertThat(resolveInfo.get(1).isInstantAppAvailable, 157 is(false)); 158 } 159 160 // query normal activities; directed package 161 { 162 final Intent queryIntent = new Intent(ACTION_QUERY); 163 final List<ResolveInfo> resolveInfo = InstrumentationRegistry.getContext() 164 .getPackageManager().queryIntentActivities(queryIntent, 0 /*flags*/); 165 if (resolveInfo == null || resolveInfo.size() == 0) { 166 fail("didn't resolve any intents"); 167 } 168 assertThat(resolveInfo.size(), is(2)); 169 assertThat(resolveInfo.get(0).activityInfo.packageName, 170 is("com.android.cts.ephemeralapp1")); 171 assertThat(resolveInfo.get(0).activityInfo.name, 172 is("com.android.cts.ephemeralapp1.EphemeralActivity")); 173 assertThat(resolveInfo.get(0).isInstantAppAvailable, 174 is(true)); 175 assertThat(resolveInfo.get(1).activityInfo.packageName, 176 is("com.android.cts.normalapp")); 177 assertThat(resolveInfo.get(1).activityInfo.name, 178 is("com.android.cts.normalapp.ExposedActivity")); 179 assertThat(resolveInfo.get(1).isInstantAppAvailable, 180 is(false)); 181 } 182 183 // query normal activities; directed component 184 { 185 final Intent queryIntent = new Intent(ACTION_QUERY); 186 final List<ResolveInfo> resolveInfo = InstrumentationRegistry.getContext() 187 .getPackageManager().queryIntentActivities(queryIntent, 0 /*flags*/); 188 if (resolveInfo == null || resolveInfo.size() == 0) { 189 fail("didn't resolve any intents"); 190 } 191 assertThat(resolveInfo.size(), is(2)); 192 assertThat(resolveInfo.get(0).activityInfo.packageName, 193 is("com.android.cts.ephemeralapp1")); 194 assertThat(resolveInfo.get(0).activityInfo.name, 195 is("com.android.cts.ephemeralapp1.EphemeralActivity")); 196 assertThat(resolveInfo.get(0).isInstantAppAvailable, 197 is(true)); 198 assertThat(resolveInfo.get(1).activityInfo.packageName, 199 is("com.android.cts.normalapp")); 200 assertThat(resolveInfo.get(1).activityInfo.name, 201 is("com.android.cts.normalapp.ExposedActivity")); 202 assertThat(resolveInfo.get(1).isInstantAppAvailable, 203 is(false)); 204 } 205 206 // query own ephemeral application activities with a web URI 207 { 208 final Intent queryIntent = new Intent(Intent.ACTION_VIEW); 209 queryIntent.addCategory(Intent.CATEGORY_BROWSABLE); 210 queryIntent.setData(Uri.parse("https://cts.google.com/ephemeral")); 211 final List<ResolveInfo> resolveInfo = InstrumentationRegistry.getContext() 212 .getPackageManager().queryIntentActivities( 213 queryIntent, PackageManager.GET_RESOLVED_FILTER); 214 if (resolveInfo == null || resolveInfo.size() == 0) { 215 fail("didn't resolve any intents"); 216 } 217 for (ResolveInfo info: resolveInfo) { 218 assertThat(info.filter, is(notNullValue())); 219 if (handlesAllWebData(info.filter)) { 220 continue; 221 } 222 assertThat(info.activityInfo.packageName, 223 is("com.android.cts.ephemeralapp1")); 224 assertThat(info.activityInfo.name, 225 is("com.android.cts.ephemeralapp1.EphemeralActivity")); 226 assertThat(info.isInstantAppAvailable, 227 is(true)); 228 } 229 } 230 231 // query other ephemeral application activities with a web URI 232 { 233 final Intent queryIntent = new Intent(Intent.ACTION_VIEW); 234 queryIntent.addCategory(Intent.CATEGORY_BROWSABLE); 235 queryIntent.setData(Uri.parse("https://cts.google.com/other")); 236 final List<ResolveInfo> resolveInfo = InstrumentationRegistry.getContext() 237 .getPackageManager().queryIntentActivities( 238 queryIntent, PackageManager.GET_RESOLVED_FILTER); 239 if (resolveInfo == null || resolveInfo.size() == 0) { 240 fail("didn't resolve any intents"); 241 } 242 for (ResolveInfo info: resolveInfo) { 243 assertThat(info.filter, is(notNullValue())); 244 if (handlesAllWebData(info.filter)) { 245 continue; 246 } 247 fail("resolution should have only matched browsers"); 248 } 249 } 250 251 // query services 252 { 253 final Intent queryIntent = new Intent(ACTION_QUERY); 254 final List<ResolveInfo> resolveInfo = InstrumentationRegistry 255 .getContext().getPackageManager().queryIntentServices(queryIntent, 0 /*flags*/); 256 if (resolveInfo == null || resolveInfo.size() == 0) { 257 fail("didn't resolve any intents"); 258 } 259 assertThat(resolveInfo.size(), is(2)); 260 assertThat(resolveInfo.get(0).serviceInfo.packageName, 261 is("com.android.cts.ephemeralapp1")); 262 assertThat(resolveInfo.get(0).serviceInfo.name, 263 is("com.android.cts.ephemeralapp1.EphemeralService")); 264 assertThat(resolveInfo.get(1).serviceInfo.packageName, 265 is("com.android.cts.normalapp")); 266 assertThat(resolveInfo.get(1).serviceInfo.name, 267 is("com.android.cts.normalapp.ExposedService")); 268 assertThat(resolveInfo.get(1).isInstantAppAvailable, 269 is(false)); 270 } 271 272 // query services; directed package 273 { 274 final Intent queryIntent = new Intent(ACTION_QUERY); 275 queryIntent.setPackage("com.android.cts.ephemeralapp1"); 276 final List<ResolveInfo> resolveInfo = InstrumentationRegistry 277 .getContext().getPackageManager().queryIntentServices(queryIntent, 0 /*flags*/); 278 if (resolveInfo == null || resolveInfo.size() == 0) { 279 fail("didn't resolve any intents"); 280 } 281 assertThat(resolveInfo.size(), is(1)); 282 assertThat(resolveInfo.get(0).serviceInfo.packageName, 283 is("com.android.cts.ephemeralapp1")); 284 assertThat(resolveInfo.get(0).serviceInfo.name, 285 is("com.android.cts.ephemeralapp1.EphemeralService")); 286 } 287 288 // query services; directed component 289 { 290 final Intent queryIntent = new Intent(ACTION_QUERY); 291 queryIntent.setComponent( 292 new ComponentName("com.android.cts.ephemeralapp1", 293 "com.android.cts.ephemeralapp1.EphemeralService")); 294 final List<ResolveInfo> resolveInfo = InstrumentationRegistry 295 .getContext().getPackageManager().queryIntentServices(queryIntent, 0 /*flags*/); 296 if (resolveInfo == null || resolveInfo.size() == 0) { 297 fail("didn't resolve any intents"); 298 } 299 assertThat(resolveInfo.size(), is(1)); 300 assertThat(resolveInfo.get(0).serviceInfo.packageName, 301 is("com.android.cts.ephemeralapp1")); 302 assertThat(resolveInfo.get(0).serviceInfo.name, 303 is("com.android.cts.ephemeralapp1.EphemeralService")); 304 } 305 306 // query instant application provider 307 { 308 final Intent queryIntent = new Intent(ACTION_QUERY); 309 final List<ResolveInfo> resolveInfo = InstrumentationRegistry 310 .getContext().getPackageManager().queryIntentContentProviders( 311 queryIntent, 0 /*flags*/); 312 if (resolveInfo == null || resolveInfo.size() == 0) { 313 fail("didn't resolve any intents"); 314 } 315 assertThat(resolveInfo.size(), is(2)); 316 assertThat(resolveInfo.get(0).providerInfo.packageName, 317 is("com.android.cts.ephemeralapp1")); 318 assertThat(resolveInfo.get(0).providerInfo.name, 319 is("com.android.cts.ephemeralapp1.EphemeralProvider")); 320 assertThat(resolveInfo.get(1).providerInfo.packageName, 321 is("com.android.cts.normalapp")); 322 assertThat(resolveInfo.get(1).providerInfo.name, 323 is("com.android.cts.normalapp.ExposedProvider")); 324 assertThat(resolveInfo.get(1).isInstantAppAvailable, 325 is(false)); 326 } 327 328 // query instant application provider ; directed package 329 { 330 final Intent queryIntent = new Intent(ACTION_QUERY); 331 queryIntent.setPackage("com.android.cts.ephemeralapp1"); 332 final List<ResolveInfo> resolveInfo = InstrumentationRegistry 333 .getContext().getPackageManager().queryIntentContentProviders( 334 queryIntent, 0 /*flags*/); 335 if (resolveInfo == null || resolveInfo.size() == 0) { 336 fail("didn't resolve any intents"); 337 } 338 assertThat(resolveInfo.size(), is(1)); 339 assertThat(resolveInfo.get(0).providerInfo.packageName, 340 is("com.android.cts.ephemeralapp1")); 341 assertThat(resolveInfo.get(0).providerInfo.name, 342 is("com.android.cts.ephemeralapp1.EphemeralProvider")); 343 } 344 345 // query instant application provider ; directed component 346 { 347 final Intent queryIntent = new Intent(ACTION_QUERY); 348 queryIntent.setComponent( 349 new ComponentName("com.android.cts.ephemeralapp1", 350 "com.android.cts.ephemeralapp1.EphemeralProvider")); 351 final List<ResolveInfo> resolveInfo = InstrumentationRegistry 352 .getContext().getPackageManager().queryIntentContentProviders( 353 queryIntent, 0 /*flags*/); 354 if (resolveInfo == null || resolveInfo.size() == 0) { 355 fail("didn't resolve any intents"); 356 } 357 assertThat(resolveInfo.size(), is(1)); 358 assertThat(resolveInfo.get(0).providerInfo.packageName, 359 is("com.android.cts.ephemeralapp1")); 360 assertThat(resolveInfo.get(0).providerInfo.name, 361 is("com.android.cts.ephemeralapp1.EphemeralProvider")); 362 } 363 364 // resolve normal provider 365 { 366 final ProviderInfo providerInfo = InstrumentationRegistry 367 .getContext().getPackageManager().resolveContentProvider( 368 "com.android.cts.normalapp.provider", 0 /*flags*/); 369 assertThat(providerInfo, is(nullValue())); 370 } 371 372 // resolve exposed provider 373 { 374 final ProviderInfo providerInfo = InstrumentationRegistry 375 .getContext().getPackageManager().resolveContentProvider( 376 "com.android.cts.normalapp.exposed.provider", 0 /*flags*/); 377 assertThat(providerInfo, is(notNullValue())); 378 assertThat(providerInfo.packageName, 379 is("com.android.cts.normalapp")); 380 assertThat(providerInfo.name, 381 is("com.android.cts.normalapp.ExposedProvider")); 382 } 383 384 // resolve instant application provider 385 { 386 final ProviderInfo providerInfo = InstrumentationRegistry 387 .getContext().getPackageManager().resolveContentProvider( 388 "com.android.cts.ephemeralapp1.provider", 0 /*flags*/); 389 assertThat(providerInfo, is(notNullValue())); 390 assertThat(providerInfo.packageName, 391 is("com.android.cts.ephemeralapp1")); 392 assertThat(providerInfo.name, 393 is("com.android.cts.ephemeralapp1.EphemeralProvider")); 394 } 395 } 396 397 @Test testStartNormal()398 public void testStartNormal() throws Exception { 399 // start the normal activity 400 try { 401 final Intent startNormalIntent = new Intent(ACTION_START_NORMAL) 402 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 403 InstrumentationRegistry 404 .getContext().startActivity(startNormalIntent, null /*options*/); 405 final TestResult testResult = getResult(); 406 fail(); 407 } catch (ActivityNotFoundException expected) { 408 } 409 410 // start the normal activity; directed package 411 try { 412 final Intent startNormalIntent = new Intent(ACTION_START_NORMAL) 413 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 414 startNormalIntent.setPackage("com.android.cts.normalapp"); 415 InstrumentationRegistry 416 .getContext().startActivity(startNormalIntent, null /*options*/); 417 final TestResult testResult = getResult(); 418 fail(); 419 } catch (ActivityNotFoundException expected) { 420 } 421 422 // start the normal activity; directed component 423 try { 424 final Intent startNormalIntent = new Intent(ACTION_START_NORMAL) 425 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 426 startNormalIntent.setComponent(new ComponentName( 427 "com.android.cts.normalapp", "com.android.cts.normalapp.NormalActivity")); 428 InstrumentationRegistry 429 .getContext().startActivity(startNormalIntent, null /*options*/); 430 final TestResult testResult = getResult(); 431 fail(); 432 } catch (ActivityNotFoundException expected) { 433 } 434 435 // TODO: Ideally we should have a test for this. However, it shows a disambig between the 436 // the normal app and chrome; for which there is no easy solution. 437 // // start the normal activity; using VIEW/BROWSABLE 438 // { 439 // final Intent startViewIntent = new Intent(Intent.ACTION_VIEW) 440 // .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 441 // startViewIntent.addCategory(Intent.CATEGORY_BROWSABLE); 442 // startViewIntent.setData(Uri.parse("https://cts.google.com/normal")); 443 // InstrumentationRegistry.getContext().startActivity(startViewIntent, null /*options*/); 444 // final TestResult testResult = getResult(); 445 // assertThat(testResult.getPackageName(), 446 // is("com.android.cts.normalapp")); 447 // assertThat(testResult.getComponentName(), 448 // is("NormalWebActivity")); 449 // assertThat(testResult.getStatus(), 450 // is("PASS")); 451 // assertThat(testResult.getEphemeralPackageInfoExposed(), 452 // is(false)); 453 // assertThat(testResult.getException(), 454 // is(nullValue())); 455 // } 456 457 // We don't attempt to start the service since it will merely return and not 458 // provide any feedback. The alternative is to wait for the broadcast timeout 459 // but it's silly to artificially slow down CTS. We'll rely on queryIntentService 460 // to check whether or not the service is actually exposed 461 462 // bind to the normal service; directed package 463 { 464 final Intent startNormalIntent = new Intent(ACTION_START_NORMAL); 465 startNormalIntent.setPackage("com.android.cts.normalapp"); 466 final TestServiceConnection connection = new TestServiceConnection(); 467 try { 468 assertThat(InstrumentationRegistry.getContext().bindService( 469 startNormalIntent, connection, Context.BIND_AUTO_CREATE /*flags*/), 470 is(false)); 471 } finally { 472 InstrumentationRegistry.getContext().unbindService(connection); 473 } 474 } 475 476 // bind to the normal service; directed component 477 { 478 final Intent startNormalIntent = new Intent(ACTION_START_NORMAL); 479 startNormalIntent.setComponent(new ComponentName( 480 "com.android.cts.normalapp", "com.android.cts.normalapp.NormalService")); 481 final TestServiceConnection connection = new TestServiceConnection(); 482 try { 483 assertThat(InstrumentationRegistry.getContext().bindService( 484 startNormalIntent, connection, Context.BIND_AUTO_CREATE /*flags*/), 485 is(false)); 486 } finally { 487 InstrumentationRegistry.getContext().unbindService(connection); 488 } 489 } 490 491 // connect to the normal provider 492 { 493 final String provider = "content://com.android.cts.normalapp.provider/table"; 494 final Cursor testCursor = InstrumentationRegistry 495 .getContext().getContentResolver().query( 496 Uri.parse(provider), 497 null /*projection*/, 498 null /*selection*/, 499 null /*selectionArgs*/, 500 null /*sortOrder*/); 501 assertThat(testCursor, is(nullValue())); 502 } 503 } 504 505 @Test testStartExposed01()506 public void testStartExposed01() throws Exception { 507 // start the explicitly exposed activity 508 final Intent startExposedIntent = new Intent(ACTION_START_EXPOSED) 509 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 510 InstrumentationRegistry 511 .getContext().startActivity(startExposedIntent, null /*options*/); 512 final TestResult testResult = getResult(); 513 assertThat(testResult.getPackageName(), 514 is("com.android.cts.normalapp")); 515 assertThat(testResult.getComponentName(), 516 is("ExposedActivity")); 517 assertThat(testResult.getStatus(), 518 is("PASS")); 519 assertThat(testResult.getEphemeralPackageInfoExposed(), 520 is(false)); 521 assertThat(testResult.getException(), 522 is(PackageManager.NameNotFoundException.class.getName())); 523 } 524 525 @Test testStartExposed02()526 public void testStartExposed02() throws Exception { 527 // start the explicitly exposed activity; directed package 528 final Intent startExposedIntent = new Intent(ACTION_START_EXPOSED) 529 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 530 startExposedIntent.setPackage("com.android.cts.normalapp"); 531 InstrumentationRegistry 532 .getContext().startActivity(startExposedIntent, null /*options*/); 533 final TestResult testResult = getResult(); 534 assertThat(testResult.getPackageName(), 535 is("com.android.cts.normalapp")); 536 assertThat(testResult.getComponentName(), 537 is("ExposedActivity")); 538 assertThat(testResult.getStatus(), 539 is("PASS")); 540 assertThat(testResult.getEphemeralPackageInfoExposed(), 541 is(false)); 542 assertThat(testResult.getException(), 543 is(PackageManager.NameNotFoundException.class.getName())); 544 } 545 546 @Test testStartExposed03()547 public void testStartExposed03() throws Exception { 548 // start the explicitly exposed activity; directed component 549 final Intent startExposedIntent = new Intent(ACTION_START_EXPOSED) 550 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 551 startExposedIntent.setComponent(new ComponentName( 552 "com.android.cts.normalapp", "com.android.cts.normalapp.ExposedActivity")); 553 InstrumentationRegistry 554 .getContext().startActivity(startExposedIntent, null /*options*/); 555 final TestResult testResult = getResult(); 556 assertThat(testResult.getPackageName(), 557 is("com.android.cts.normalapp")); 558 assertThat(testResult.getComponentName(), 559 is("ExposedActivity")); 560 assertThat(testResult.getStatus(), 561 is("PASS")); 562 assertThat(testResult.getEphemeralPackageInfoExposed(), 563 is(false)); 564 assertThat(testResult.getException(), 565 is(PackageManager.NameNotFoundException.class.getName())); 566 } 567 568 @Test testStartExposed04()569 public void testStartExposed04() throws Exception { 570 // start the implicitly exposed activity; directed package 571 try { 572 final Intent startExposedIntent = new Intent(Intent.ACTION_VIEW) 573 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 574 startExposedIntent.setPackage("com.android.cts.implicitapp"); 575 startExposedIntent.addCategory(Intent.CATEGORY_BROWSABLE); 576 startExposedIntent.setData(Uri.parse("https://cts.google.com/implicit")); 577 InstrumentationRegistry 578 .getContext().startActivity(startExposedIntent, null /*options*/); 579 fail("activity started"); 580 } catch (ActivityNotFoundException expected) { } 581 } 582 583 @Test testStartExposed05()584 public void testStartExposed05() throws Exception { 585 // start the implicitly exposed activity; directed component 586 try { 587 final Intent startExposedIntent = new Intent(Intent.ACTION_VIEW) 588 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 589 startExposedIntent.setComponent(new ComponentName( 590 "com.android.cts.implicitapp", 591 "com.android.cts.implicitapp.ImplicitActivity")); 592 startExposedIntent.addCategory(Intent.CATEGORY_BROWSABLE); 593 startExposedIntent.setData(Uri.parse("https://cts.google.com/implicit")); 594 InstrumentationRegistry 595 .getContext().startActivity(startExposedIntent, null /*options*/); 596 fail("activity started"); 597 } catch (ActivityNotFoundException expected) { } 598 } 599 600 @Test testStartExposed06()601 public void testStartExposed06() throws Exception { 602 // start the exposed service; directed package 603 final Intent startExposedIntent = new Intent(ACTION_START_EXPOSED) 604 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 605 startExposedIntent.setPackage("com.android.cts.normalapp"); 606 InstrumentationRegistry.getContext().startForegroundService(startExposedIntent); 607 final TestResult testResult = getResult(); 608 assertThat(testResult.getPackageName(), 609 is("com.android.cts.normalapp")); 610 assertThat(testResult.getComponentName(), 611 is("ExposedService")); 612 assertThat(testResult.getStatus(), 613 is("PASS")); 614 assertThat(testResult.getEphemeralPackageInfoExposed(), 615 is(true)); 616 assertThat(testResult.getException(), 617 is(nullValue())); 618 } 619 620 @Test testStartExposed07()621 public void testStartExposed07() throws Exception { 622 // start the exposed service; directed component 623 final Intent startExposedIntent = new Intent(ACTION_START_EXPOSED); 624 startExposedIntent.setComponent(new ComponentName( 625 "com.android.cts.normalapp", "com.android.cts.normalapp.ExposedService")); 626 InstrumentationRegistry.getContext().startForegroundService(startExposedIntent); 627 final TestResult testResult = getResult(); 628 assertThat(testResult.getPackageName(), 629 is("com.android.cts.normalapp")); 630 assertThat(testResult.getComponentName(), 631 is("ExposedService")); 632 assertThat(testResult.getMethodName(), 633 is("onStartCommand")); 634 assertThat(testResult.getStatus(), 635 is("PASS")); 636 assertThat(testResult.getEphemeralPackageInfoExposed(), 637 is(true)); 638 assertThat(testResult.getException(), 639 is(nullValue())); 640 } 641 642 @Test testStartExposed08()643 public void testStartExposed08() throws Exception { 644 // bind to the exposed service; directed package 645 final Intent startExposedIntent = new Intent(ACTION_START_EXPOSED); 646 startExposedIntent.setPackage("com.android.cts.normalapp"); 647 final TestServiceConnection connection = new TestServiceConnection(); 648 try { 649 assertThat(InstrumentationRegistry.getContext().bindService( 650 startExposedIntent, connection, Context.BIND_AUTO_CREATE /*flags*/), 651 is(true)); 652 final TestResult testResult = getResult(); 653 assertThat(testResult.getPackageName(), 654 is("com.android.cts.normalapp")); 655 assertThat(testResult.getComponentName(), 656 is("ExposedService")); 657 assertThat(testResult.getMethodName(), 658 is("onBind")); 659 assertThat(testResult.getStatus(), 660 is("PASS")); 661 assertThat(testResult.getEphemeralPackageInfoExposed(), 662 is(true)); 663 assertThat(testResult.getException(), 664 is(nullValue())); 665 } finally { 666 InstrumentationRegistry.getContext().unbindService(connection); 667 } 668 } 669 670 @Test testStartExposed09()671 public void testStartExposed09() throws Exception { 672 // bind to the exposed service; directed component 673 final Intent startExposedIntent = new Intent(ACTION_START_EXPOSED); 674 startExposedIntent.setComponent(new ComponentName( 675 "com.android.cts.normalapp", "com.android.cts.normalapp.ExposedService")); 676 final TestServiceConnection connection = new TestServiceConnection(); 677 try { 678 assertThat(InstrumentationRegistry.getContext().bindService( 679 startExposedIntent, connection, Context.BIND_AUTO_CREATE /*flags*/), 680 is(true)); 681 final TestResult testResult = getResult(); 682 assertThat(testResult.getPackageName(), 683 is("com.android.cts.normalapp")); 684 assertThat(testResult.getComponentName(), 685 is("ExposedService")); 686 assertThat(testResult.getMethodName(), 687 is("onBind")); 688 assertThat(testResult.getStatus(), 689 is("PASS")); 690 assertThat(testResult.getEphemeralPackageInfoExposed(), 691 is(true)); 692 assertThat(testResult.getException(), 693 is(nullValue())); 694 } finally { 695 InstrumentationRegistry.getContext().unbindService(connection); 696 } 697 } 698 699 @Test testStartExposed10()700 public void testStartExposed10() throws Exception { 701 // connect to exposed provider 702 final String provider = "content://com.android.cts.normalapp.exposed.provider/table"; 703 final Cursor testCursor = InstrumentationRegistry 704 .getContext().getContentResolver().query( 705 Uri.parse(provider), 706 null /*projection*/, 707 null /*selection*/, 708 null /*selectionArgs*/, 709 null /*sortOrder*/); 710 assertThat(testCursor, is(notNullValue())); 711 assertThat(testCursor.getCount(), is(1)); 712 assertThat(testCursor.getColumnCount(), is(2)); 713 assertThat(testCursor.moveToFirst(), is(true)); 714 assertThat(testCursor.getInt(0), is(1)); 715 assertThat(testCursor.getString(1), is("ExposedProvider")); 716 final TestResult testResult = getResult(); 717 assertThat(testResult.getPackageName(), 718 is("com.android.cts.normalapp")); 719 assertThat(testResult.getComponentName(), 720 is("ExposedProvider")); 721 assertThat(testResult.getStatus(), 722 is("PASS")); 723 assertThat(testResult.getEphemeralPackageInfoExposed(), 724 is(true)); 725 assertThat(testResult.getException(), 726 is(nullValue())); 727 } 728 729 @Test testStartExposed11()730 public void testStartExposed11() throws Exception { 731 // start the explicitly exposed activity 732 final Intent startExposedIntent = new Intent(ACTION_START_EXPOSED) 733 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 734 735 final Context context = InstrumentationRegistry.getContext(); 736 context.startActivity(startExposedIntent.setComponent( 737 new ComponentName(context, StartForResultActivity.class))); 738 739 final TestResult testResult = getResult(); 740 assertThat(testResult.getPackageName(), 741 is("com.android.cts.normalapp")); 742 assertThat(testResult.getComponentName(), 743 is("ExposedActivity")); 744 assertThat(testResult.getStatus(), 745 is("PASS")); 746 assertThat(testResult.getEphemeralPackageInfoExposed(), 747 is(true)); 748 assertThat(testResult.getException(), 749 is(nullValue())); 750 } 751 752 @Test testStartEphemeral()753 public void testStartEphemeral() throws Exception { 754 // start the ephemeral activity 755 { 756 final Intent startEphemeralIntent = new Intent(ACTION_START_EPHEMERAL) 757 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 758 InstrumentationRegistry 759 .getContext().startActivity(startEphemeralIntent, null /*options*/); 760 final TestResult testResult = getResult(); 761 assertThat(testResult.getPackageName(), 762 is("com.android.cts.ephemeralapp1")); 763 assertThat(testResult.getComponentName(), 764 is("EphemeralActivity")); 765 assertThat(testResult.getStatus(), 766 is("PASS")); 767 assertThat(testResult.getException(), 768 is(nullValue())); 769 } 770 771 // start the ephemeral activity; directed package 772 { 773 final Intent startEphemeralIntent = new Intent(ACTION_START_EPHEMERAL) 774 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 775 startEphemeralIntent.setPackage("com.android.cts.ephemeralapp1"); 776 InstrumentationRegistry 777 .getContext().startActivity(startEphemeralIntent, null /*options*/); 778 final TestResult testResult = getResult(); 779 assertThat(testResult.getPackageName(), 780 is("com.android.cts.ephemeralapp1")); 781 assertThat(testResult.getComponentName(), 782 is("EphemeralActivity")); 783 assertThat(testResult.getStatus(), 784 is("PASS")); 785 assertThat(testResult.getException(), 786 is(nullValue())); 787 } 788 789 // start the ephemeral activity; directed component 790 { 791 final Intent startEphemeralIntent = new Intent(ACTION_START_EPHEMERAL) 792 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 793 startEphemeralIntent.setComponent( 794 new ComponentName("com.android.cts.ephemeralapp1", 795 "com.android.cts.ephemeralapp1.EphemeralActivity")); 796 InstrumentationRegistry 797 .getContext().startActivity(startEphemeralIntent, null /*options*/); 798 final TestResult testResult = getResult(); 799 assertThat(testResult.getPackageName(), 800 is("com.android.cts.ephemeralapp1")); 801 assertThat(testResult.getComponentName(), 802 is("EphemeralActivity")); 803 assertThat(testResult.getStatus(), 804 is("PASS")); 805 assertThat(testResult.getException(), 806 is(nullValue())); 807 } 808 809 // start a private ephemeral activity 810 { 811 final Intent startEphemeralIntent = new Intent(ACTION_START_EPHEMERAL_PRIVATE) 812 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 813 InstrumentationRegistry 814 .getContext().startActivity(startEphemeralIntent, null /*options*/); 815 final TestResult testResult = getResult(); 816 assertThat(testResult.getPackageName(), 817 is("com.android.cts.ephemeralapp1")); 818 assertThat(testResult.getComponentName(), 819 is("EphemeralActivity2")); 820 assertThat(testResult.getStatus(), 821 is("PASS")); 822 assertThat(testResult.getException(), 823 is(nullValue())); 824 } 825 826 // start a private ephemeral activity; directed package 827 { 828 final Intent startEphemeralIntent = new Intent(ACTION_START_EPHEMERAL_PRIVATE) 829 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 830 startEphemeralIntent.setPackage("com.android.cts.ephemeralapp1"); 831 InstrumentationRegistry 832 .getContext().startActivity(startEphemeralIntent, null /*options*/); 833 final TestResult testResult = getResult(); 834 assertThat(testResult.getPackageName(), 835 is("com.android.cts.ephemeralapp1")); 836 assertThat(testResult.getComponentName(), 837 is("EphemeralActivity2")); 838 assertThat(testResult.getStatus(), 839 is("PASS")); 840 assertThat(testResult.getException(), 841 is(nullValue())); 842 } 843 844 // start a private ephemeral activity; directed component 845 { 846 final Intent startEphemeralIntent = new Intent(ACTION_START_EPHEMERAL_PRIVATE) 847 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 848 startEphemeralIntent.setComponent( 849 new ComponentName("com.android.cts.ephemeralapp1", 850 "com.android.cts.ephemeralapp1.EphemeralActivity2")); 851 InstrumentationRegistry 852 .getContext().startActivity(startEphemeralIntent, null /*options*/); 853 final TestResult testResult = getResult(); 854 assertThat(testResult.getPackageName(), 855 is("com.android.cts.ephemeralapp1")); 856 assertThat(testResult.getComponentName(), 857 is("EphemeralActivity2")); 858 assertThat(testResult.getStatus(), 859 is("PASS")); 860 assertThat(testResult.getException(), 861 is(nullValue())); 862 } 863 864 // start a private ephemeral activity; directed component 865 { 866 final Intent startEphemeralIntent = new Intent() 867 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 868 startEphemeralIntent.setComponent( 869 new ComponentName("com.android.cts.ephemeralapp1", 870 "com.android.cts.ephemeralapp1.EphemeralActivity3")); 871 InstrumentationRegistry 872 .getContext().startActivity(startEphemeralIntent, null /*options*/); 873 final TestResult testResult = getResult(); 874 assertThat(testResult.getPackageName(), 875 is("com.android.cts.ephemeralapp1")); 876 assertThat(testResult.getComponentName(), 877 is("EphemeralActivity3")); 878 assertThat(testResult.getStatus(), 879 is("PASS")); 880 assertThat(testResult.getException(), 881 is(nullValue())); 882 } 883 884 // start an ephemeral activity; VIEW / BROWSABLE intent 885 { 886 final Intent startEphemeralIntent = new Intent(Intent.ACTION_VIEW) 887 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 888 startEphemeralIntent.addCategory(Intent.CATEGORY_BROWSABLE); 889 startEphemeralIntent.setData(Uri.parse("https://cts.google.com/other")); 890 InstrumentationRegistry 891 .getContext().startActivity(startEphemeralIntent, null /*options*/); 892 final TestResult testResult = getResult(); 893 assertThat(testResult.getPackageName(), 894 is("com.android.cts.ephemeralapp2")); 895 assertThat(testResult.getComponentName(), 896 is("EphemeralActivity")); 897 assertThat(testResult.getIntent().getAction(), 898 is(Intent.ACTION_VIEW)); 899 assertThat(testResult.getIntent().getCategories(), 900 hasItems(Intent.CATEGORY_BROWSABLE)); 901 assertThat(testResult.getIntent().getData().toString(), 902 is("https://cts.google.com/other")); 903 assertThat(testResult.getStatus(), 904 is("PASS")); 905 assertThat(testResult.getException(), 906 is(nullValue())); 907 } 908 909 // start an ephemeral activity; EXTERNAL flag 910 { 911 final Intent startEphemeralIntent = new Intent(ACTION_START_EPHEMERAL_ACTIVITY) 912 .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MATCH_EXTERNAL); 913 InstrumentationRegistry.getContext().startActivity( 914 startEphemeralIntent, null /*options*/); 915 final TestResult testResult = getResult(); 916 assertThat(testResult.getPackageName(), 917 is("com.android.cts.ephemeralapp2")); 918 assertThat(testResult.getComponentName(), 919 is("EphemeralActivity")); 920 assertThat(testResult.getIntent().getAction(), 921 is(ACTION_START_EPHEMERAL_ACTIVITY)); 922 assertThat(testResult.getIntent().getData(), 923 is(nullValue())); 924 assertThat(testResult.getStatus(), 925 is("PASS")); 926 assertThat(testResult.getException(), 927 is(nullValue())); 928 } 929 930 // start the ephemeral service; directed package 931 { 932 final Intent startEphemeralIntent = new Intent(ACTION_START_EPHEMERAL); 933 startEphemeralIntent.setPackage("com.android.cts.ephemeralapp1"); 934 try { 935 InstrumentationRegistry.getContext().startService(startEphemeralIntent); 936 final TestResult testResult = getResult(); 937 assertThat(testResult.getPackageName(), 938 is("com.android.cts.ephemeralapp1")); 939 assertThat(testResult.getComponentName(), 940 is("EphemeralService")); 941 assertThat(testResult.getMethodName(), 942 is("onStartCommand")); 943 assertThat(testResult.getStatus(), 944 is("PASS")); 945 assertThat(testResult.getException(), 946 is(nullValue())); 947 } finally { 948 InstrumentationRegistry.getContext().stopService(startEphemeralIntent); 949 } 950 } 951 952 // start the ephemeral service; directed component 953 { 954 final Intent startEphemeralIntent = new Intent(ACTION_START_EPHEMERAL); 955 startEphemeralIntent.setComponent( 956 new ComponentName("com.android.cts.ephemeralapp1", 957 "com.android.cts.ephemeralapp1.EphemeralService")); 958 try { 959 assertThat(InstrumentationRegistry.getContext().startService(startEphemeralIntent), 960 is(notNullValue())); 961 final TestResult testResult = getResult(); 962 assertThat(testResult.getPackageName(), 963 is("com.android.cts.ephemeralapp1")); 964 assertThat(testResult.getComponentName(), 965 is("EphemeralService")); 966 assertThat(testResult.getMethodName(), 967 is("onStartCommand")); 968 assertThat(testResult.getStatus(), 969 is("PASS")); 970 assertThat(testResult.getException(), 971 is(nullValue())); 972 } finally { 973 InstrumentationRegistry.getContext().stopService(startEphemeralIntent); 974 } 975 } 976 977 // bind to the ephemeral service; directed package 978 { 979 final Intent startEphemeralIntent = new Intent(ACTION_START_EPHEMERAL); 980 startEphemeralIntent.setPackage("com.android.cts.ephemeralapp1"); 981 final TestServiceConnection connection = new TestServiceConnection(); 982 try { 983 assertThat(InstrumentationRegistry.getContext().bindService( 984 startEphemeralIntent, connection, Context.BIND_AUTO_CREATE /*flags*/), 985 is(true)); 986 final TestResult testResult = getResult(); 987 assertThat(testResult.getPackageName(), 988 is("com.android.cts.ephemeralapp1")); 989 assertThat(testResult.getComponentName(), 990 is("EphemeralService")); 991 assertThat(testResult.getMethodName(), 992 is("onBind")); 993 assertThat(testResult.getStatus(), 994 is("PASS")); 995 assertThat(testResult.getException(), 996 is(nullValue())); 997 } finally { 998 InstrumentationRegistry.getContext().unbindService(connection); 999 } 1000 } 1001 1002 // bind to the ephemeral service; directed component 1003 { 1004 final Intent startEphemeralIntent = new Intent(ACTION_START_EPHEMERAL); 1005 startEphemeralIntent.setComponent( 1006 new ComponentName("com.android.cts.ephemeralapp1", 1007 "com.android.cts.ephemeralapp1.EphemeralService")); 1008 final TestServiceConnection connection = new TestServiceConnection(); 1009 try { 1010 assertThat(InstrumentationRegistry.getContext().bindService( 1011 startEphemeralIntent, connection, Context.BIND_AUTO_CREATE /*flags*/), 1012 is(true)); 1013 final TestResult testResult = getResult(); 1014 assertThat(testResult.getPackageName(), 1015 is("com.android.cts.ephemeralapp1")); 1016 assertThat(testResult.getComponentName(), 1017 is("EphemeralService")); 1018 assertThat(testResult.getMethodName(), 1019 is("onBind")); 1020 assertThat(testResult.getStatus(), 1021 is("PASS")); 1022 assertThat(testResult.getException(), 1023 is(nullValue())); 1024 } finally { 1025 InstrumentationRegistry.getContext().unbindService(connection); 1026 } 1027 } 1028 1029 // connect to the instant app provider 1030 { 1031 final String provider = "content://com.android.cts.ephemeralapp1.provider/table"; 1032 final Cursor testCursor = InstrumentationRegistry 1033 .getContext().getContentResolver().query( 1034 Uri.parse(provider), 1035 null /*projection*/, 1036 null /*selection*/, 1037 null /*selectionArgs*/, 1038 null /*sortOrder*/); 1039 assertThat(testCursor, is(notNullValue())); 1040 assertThat(testCursor.getCount(), is(1)); 1041 assertThat(testCursor.getColumnCount(), is(2)); 1042 assertThat(testCursor.moveToFirst(), is(true)); 1043 assertThat(testCursor.getInt(0), is(1)); 1044 assertThat(testCursor.getString(1), is("InstantAppProvider")); 1045 } 1046 } 1047 1048 @Test testBuildSerialUnknown()1049 public void testBuildSerialUnknown() throws Exception { 1050 assertThat(Build.SERIAL, is(Build.UNKNOWN)); 1051 } 1052 1053 @Test testPackageInfo()1054 public void testPackageInfo() throws Exception { 1055 PackageInfo info; 1056 // own package info 1057 info = InstrumentationRegistry.getContext().getPackageManager() 1058 .getPackageInfo("com.android.cts.ephemeralapp1", 0); 1059 assertThat(info.packageName, 1060 is("com.android.cts.ephemeralapp1")); 1061 1062 // exposed application package info 1063 info = InstrumentationRegistry.getContext().getPackageManager() 1064 .getPackageInfo("com.android.cts.normalapp", 0); 1065 assertThat(info.packageName, 1066 is("com.android.cts.normalapp")); 1067 1068 // implicitly exposed application package info not accessible 1069 try { 1070 info = InstrumentationRegistry.getContext().getPackageManager() 1071 .getPackageInfo("com.android.cts.implicitapp", 0); 1072 fail("Instant apps should not be able to access PackageInfo for an app that does not" + 1073 " expose itself to Instant Apps."); 1074 } catch (PackageManager.NameNotFoundException expected) { 1075 } 1076 1077 // unexposed application package info not accessible 1078 try { 1079 info = InstrumentationRegistry.getContext().getPackageManager() 1080 .getPackageInfo("com.android.cts.unexposedapp", 0); 1081 fail("Instant apps should not be able to access PackageInfo for an app that does not" + 1082 " expose itself to Instant Apps."); 1083 } catch (PackageManager.NameNotFoundException expected) { 1084 } 1085 1086 // instant application (with visibleToInstantApp component) package info not accessible 1087 try { 1088 info = InstrumentationRegistry.getContext().getPackageManager() 1089 .getPackageInfo("com.android.cts.ephemeralapp2", 0); 1090 fail("Instant apps should not be able to access PackageInfo for another Instant App."); 1091 } catch (PackageManager.NameNotFoundException expected) { 1092 } 1093 } 1094 1095 @Test testActivityInfo()1096 public void testActivityInfo() throws Exception { 1097 // own package info 1098 { 1099 final ComponentName component = new ComponentName( 1100 "com.android.cts.ephemeralapp1", 1101 "com.android.cts.ephemeralapp1.EphemeralActivity"); 1102 final ActivityInfo info = InstrumentationRegistry.getContext().getPackageManager() 1103 .getActivityInfo(component, 0); 1104 assertThat(info.packageName, 1105 is("com.android.cts.ephemeralapp1")); 1106 } 1107 1108 // exposed application package info 1109 { 1110 final ComponentName component = new ComponentName( 1111 "com.android.cts.normalapp", 1112 "com.android.cts.normalapp.ExposedActivity"); 1113 final ActivityInfo info = InstrumentationRegistry.getContext().getPackageManager() 1114 .getActivityInfo(component, 0); 1115 assertThat(info.packageName, 1116 is("com.android.cts.normalapp")); 1117 } 1118 1119 // implicitly exposed application package info not accessible 1120 { 1121 try { 1122 final ComponentName component = new ComponentName( 1123 "com.android.cts.normalapp", 1124 "com.android.cts.normalapp.NormalWebActivity"); 1125 final ActivityInfo info = InstrumentationRegistry.getContext().getPackageManager() 1126 .getActivityInfo(component, 0); 1127 fail("Instant apps should not be able to access ActivityInfo for" 1128 + " an activity that implicitly exposes itself to Instant Apps."); 1129 } catch (PackageManager.NameNotFoundException expected) { 1130 } 1131 } 1132 1133 // unexposed application package info not accessible 1134 { 1135 try { 1136 final ComponentName component = new ComponentName( 1137 "com.android.cts.normalapp", 1138 "com.android.cts.normalapp.NormalActivity"); 1139 final ActivityInfo info = InstrumentationRegistry.getContext().getPackageManager() 1140 .getActivityInfo(component, 0); 1141 fail("Instant apps should not be able to access ActivityInfo for" 1142 + " an activity that does not expose itself to Instant Apps."); 1143 } catch (PackageManager.NameNotFoundException expected) { 1144 } 1145 } 1146 1147 // instant application (with visibleToInstantApp component) package info not accessible 1148 { 1149 try { 1150 final ComponentName component = new ComponentName( 1151 "com.android.cts.ephemeralapp2", 1152 "com.android.cts.ephemeralapp2.ExposedActivity"); 1153 final ActivityInfo info = InstrumentationRegistry.getContext().getPackageManager() 1154 .getActivityInfo(component, 0); 1155 fail("Instant apps should not be able to access ActivityInfo for" 1156 + " another Instant App."); 1157 } catch (PackageManager.NameNotFoundException expected) { 1158 } 1159 } 1160 } 1161 1162 @Test testInstallPermissionNotGranted()1163 public void testInstallPermissionNotGranted() throws Exception { 1164 assertThat(InstrumentationRegistry.getContext() 1165 .checkCallingOrSelfPermission(Manifest.permission.SET_ALARM), 1166 is(PackageManager.PERMISSION_DENIED)); 1167 } 1168 1169 @Test testInstallPermissionGranted()1170 public void testInstallPermissionGranted() throws Exception { 1171 assertThat(InstrumentationRegistry.getContext() 1172 .checkCallingOrSelfPermission(Manifest.permission.INTERNET), 1173 is(PackageManager.PERMISSION_GRANTED)); 1174 } 1175 1176 @Test 1177 @AsbSecurityTest(cveBugId = 140256621) testInstallPermissionNotGrantedInPackageInfo()1178 public void testInstallPermissionNotGrantedInPackageInfo() throws Exception { 1179 assertThat(isPermissionGrantedInPackageInfo(Manifest.permission.SET_ALARM), is(false)); 1180 } 1181 1182 @Test 1183 @AsbSecurityTest(cveBugId = 140256621) testInstallPermissionGrantedInPackageInfo()1184 public void testInstallPermissionGrantedInPackageInfo() throws Exception { 1185 assertThat(isPermissionGrantedInPackageInfo(Manifest.permission.INTERNET), is(true)); 1186 } 1187 isPermissionGrantedInPackageInfo(String permissionName)1188 private static boolean isPermissionGrantedInPackageInfo(String permissionName) 1189 throws Exception { 1190 final Context context = InstrumentationRegistry.getContext(); 1191 final PackageInfo packageInfo = context.getPackageManager().getPackageInfo( 1192 context.getPackageName(), PackageManager.GET_PERMISSIONS); 1193 final int permissionIndex = Arrays.asList(packageInfo.requestedPermissions).indexOf( 1194 permissionName); 1195 assertThat(permissionIndex, is(not(-1))); 1196 return (packageInfo.requestedPermissionsFlags[permissionIndex] 1197 & PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0; 1198 } 1199 1200 @Test testExposedActivity()1201 public void testExposedActivity() throws Exception { 1202 final Bundle testArgs = InstrumentationRegistry.getArguments(); 1203 assertThat(testArgs, is(notNullValue())); 1204 final String action = testArgs.getString("action"); 1205 final String category = testArgs.getString("category"); 1206 final String mimeType = testArgs.getString("mime_type"); 1207 assertThat(action, is(notNullValue())); 1208 final Intent queryIntent = makeIntent(action, category, mimeType); 1209 final List<ResolveInfo> resolveInfo = InstrumentationRegistry.getContext() 1210 .getPackageManager().queryIntentActivities(queryIntent, 0 /*flags*/); 1211 if (resolveInfo == null || resolveInfo.size() == 0) { 1212 fail("No activies found for Intent: " + queryIntent); 1213 } 1214 } 1215 1216 @Test testGetInstaller01()1217 public void testGetInstaller01() throws Exception { 1218 // test we can read our own installer 1219 final String installerPackageName = InstrumentationRegistry.getContext().getPackageManager() 1220 .getInstallerPackageName("com.android.cts.ephemeralapp1"); 1221 assertThat(installerPackageName, is("com.android.cts.normalapp")); 1222 } 1223 @Test testGetInstaller02()1224 public void testGetInstaller02() throws Exception { 1225 // test we can read someone else's installer if they're exposed to instant applications 1226 final String installerPackageName = InstrumentationRegistry.getContext().getPackageManager() 1227 .getInstallerPackageName("com.android.cts.normalapp"); 1228 assertThat(installerPackageName, is("com.android.cts.normalapp")); 1229 } 1230 @Test testGetInstaller03()1231 public void testGetInstaller03() throws Exception { 1232 // test we can't read installer if they're not exposed to instant applications 1233 final PackageManager pm = InstrumentationRegistry.getContext().getPackageManager(); 1234 assertThrows(IllegalArgumentException.class, 1235 () -> pm.getInstallerPackageName("com.android.cts.unexposedapp")); 1236 } 1237 1238 @Test testStartForegroundService()1239 public void testStartForegroundService() throws Exception { 1240 final Context context = InstrumentationRegistry.getContext(); 1241 final Intent intent = new Intent(context, SomeService.class); 1242 1243 // Create a notification channel for the foreground notification 1244 final NotificationChannel channel = new NotificationChannel("foo", "foo", 1245 NotificationManager.IMPORTANCE_DEFAULT); 1246 final NotificationManager notificationManager = context.getSystemService( 1247 NotificationManager.class); 1248 notificationManager.createNotificationChannel(channel); 1249 1250 // Shouldn't be able to start without a permission 1251 final CountDownLatch latch1 = new CountDownLatch(1); 1252 SomeService.setOnStartCommandCallback((int result) -> { 1253 assertSame("Shouldn't be able to start without " 1254 + " INSTANT_APP_FOREGROUND_SERVICE permission", 0, result); 1255 latch1.countDown(); 1256 }); 1257 context.startForegroundService(intent); 1258 latch1.await(5, TimeUnit.SECONDS); 1259 1260 // Now grant ourselves INSTANT_APP_FOREGROUND_SERVICE 1261 grantInstantAppForegroundServicePermission(); 1262 1263 // Should be able to start with a permission 1264 final CountDownLatch latch2 = new CountDownLatch(1); 1265 SomeService.setOnStartCommandCallback((int result) -> { 1266 assertSame("Should be able to start with " 1267 + " INSTANT_APP_FOREGROUND_SERVICE permission", 1, result); 1268 latch2.countDown(); 1269 }); 1270 context.startForegroundService(intent); 1271 latch2.await(5, TimeUnit.SECONDS); 1272 } 1273 1274 @Test testRecordAudioPermission()1275 public void testRecordAudioPermission() throws Throwable { 1276 final AudioRecord record = 1277 new AudioRecord(MIC, 8000, CHANNEL_IN_MONO, ENCODING_PCM_16BIT, 4096); 1278 try { 1279 assertThat("audio record not initialized", 1280 record.getState(), is(AudioRecord.STATE_INITIALIZED)); 1281 } finally { 1282 record.release(); 1283 } 1284 } 1285 1286 @Test testReadPhoneNumbersPermission()1287 public void testReadPhoneNumbersPermission() throws Throwable { 1288 final Context context = InstrumentationRegistry.getContext(); 1289 if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 1290 return; 1291 } 1292 1293 try { 1294 final TelephonyManager telephonyManager = 1295 (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); 1296 final String nmbr = telephonyManager.getLine1Number(); 1297 } catch (SecurityException e) { 1298 fail("Permission not granted"); 1299 } 1300 } 1301 1302 @Test testAccessCoarseLocationPermission()1303 public void testAccessCoarseLocationPermission() { 1304 final Context context = InstrumentationRegistry.getContext(); 1305 1306 final LocationManager locationManager = 1307 (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); 1308 1309 final Criteria criteria = new Criteria(); 1310 criteria.setAccuracy(Criteria.ACCURACY_COARSE); 1311 final String bestProvider = locationManager.getBestProvider(criteria, false); 1312 try { 1313 final String provider = 1314 bestProvider == null ? LocationManager.NETWORK_PROVIDER : bestProvider; 1315 locationManager.getLastKnownLocation(provider); 1316 } catch (SecurityException e) { 1317 fail("Permission not granted."); 1318 } 1319 } 1320 1321 @Test testCameraPermission()1322 public void testCameraPermission() throws Throwable { 1323 final Context context = InstrumentationRegistry.getContext(); 1324 final CameraManager manager = 1325 (CameraManager) context.getSystemService(Context.CAMERA_SERVICE); 1326 final String[] cameraIds = manager.getCameraIdList(); 1327 if (cameraIds.length == 0) { 1328 return; 1329 } 1330 final CountDownLatch latch = new CountDownLatch(1); 1331 final HandlerThread backgroundThread = new HandlerThread("camera_bg"); 1332 backgroundThread.start(); 1333 final CameraDevice.StateCallback callback = new CameraDevice.StateCallback() { 1334 @Override 1335 public void onOpened(CameraDevice camera) { 1336 latch.countDown(); 1337 camera.close(); 1338 } 1339 @Override 1340 public void onDisconnected(CameraDevice camera) { 1341 camera.close(); 1342 } 1343 @Override 1344 public void onError(CameraDevice camera, int error) { 1345 camera.close(); 1346 } 1347 }; 1348 manager.openCamera(cameraIds[0], callback, new Handler(backgroundThread.getLooper())); 1349 assertThat(latch.await(1000, TimeUnit.MILLISECONDS), is(true)); 1350 } 1351 1352 @Test testInternetPermission()1353 public void testInternetPermission() throws Throwable { 1354 final ConnectivityManager manager = (ConnectivityManager) InstrumentationRegistry.getContext() 1355 .getSystemService(Context.CONNECTIVITY_SERVICE); 1356 manager.reportNetworkConnectivity(null, false); 1357 } 1358 1359 @Test testVibratePermission()1360 public void testVibratePermission() throws Throwable { 1361 final Vibrator vibrator = (Vibrator) InstrumentationRegistry.getContext() 1362 .getSystemService(Context.VIBRATOR_SERVICE); 1363 final VibrationEffect effect = 1364 VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE); 1365 vibrator.vibrate(effect); 1366 } 1367 1368 @Test testWakeLockPermission()1369 public void testWakeLockPermission() throws Throwable { 1370 WakeLock wakeLock = null; 1371 try { 1372 final PowerManager powerManager = (PowerManager) InstrumentationRegistry.getContext() 1373 .getSystemService(Context.POWER_SERVICE); 1374 wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "test"); 1375 wakeLock.acquire(); 1376 } 1377 finally { 1378 if (wakeLock != null && wakeLock.isHeld()) { 1379 wakeLock.release(); 1380 } 1381 } 1382 } 1383 1384 @Test testGetSearchableInfo()1385 public void testGetSearchableInfo() throws Throwable { 1386 final SearchManager searchManager = (SearchManager) InstrumentationRegistry.getContext() 1387 .getSystemService(Context.SEARCH_SERVICE); 1388 if (searchManager == null) { 1389 return; 1390 } 1391 // get searchable info for a component in ourself; pass 1392 { 1393 final SearchableInfo info = searchManager.getSearchableInfo( 1394 new ComponentName("com.android.cts.ephemeralapp1", 1395 "com.android.cts.ephemeralapp1.EphemeralActivity")); 1396 assertThat(info, is(notNullValue())); 1397 assertThat(info.getSearchActivity(), 1398 is(equalTo( 1399 new ComponentName("com.android.cts.ephemeralapp1", 1400 "com.android.cts.ephemeralapp1.EphemeralActivity")))); 1401 } 1402 1403 // get searchable info for a component in a different instant application; fail 1404 { 1405 final SearchableInfo info = searchManager.getSearchableInfo( 1406 new ComponentName("com.android.cts.ephemeralapp2", 1407 "com.android.cts.ephemeralapp2.EphemeralActivity")); 1408 assertThat(info, is(nullValue())); 1409 } 1410 1411 // get searchable info for an exposed in a full application; pass 1412 { 1413 final SearchableInfo info = searchManager.getSearchableInfo( 1414 new ComponentName("com.android.cts.normalapp", 1415 "com.android.cts.normalapp.ExposedActivity")); 1416 assertThat(info, is(notNullValue())); 1417 assertThat(info.getSearchActivity(), 1418 is(equalTo( 1419 new ComponentName("com.android.cts.normalapp", 1420 "com.android.cts.normalapp.ExposedActivity")))); 1421 } 1422 1423 // get searchable info for an unexposed component in a full application; fail 1424 { 1425 final SearchableInfo info = searchManager.getSearchableInfo( 1426 new ComponentName("com.android.cts.normalapp", 1427 "com.android.cts.normalapp.NormalActivity")); 1428 assertThat(info, is(nullValue())); 1429 } 1430 } 1431 1432 /** Tests getting changed packages for instant app. */ 1433 @Test testGetChangedPackages()1434 public void testGetChangedPackages() { 1435 final PackageManager pm = InstrumentationRegistry.getContext().getPackageManager(); 1436 1437 // Instant apps can't get changed packages. 1438 final ChangedPackages changedPackages = pm.getChangedPackages(0); 1439 assertNull(changedPackages); 1440 } 1441 1442 /** Returns {@code true} if the given filter handles all web URLs, regardless of host. */ handlesAllWebData(IntentFilter filter)1443 private boolean handlesAllWebData(IntentFilter filter) { 1444 return filter.hasCategory(Intent.CATEGORY_APP_BROWSER) || 1445 (handlesWebUris(filter) && filter.countDataAuthorities() == 0); 1446 } 1447 1448 /** Returns {@code true} if the given filter handles at least one web URL. */ handlesWebUris(IntentFilter filter)1449 private boolean handlesWebUris(IntentFilter filter) { 1450 // Require ACTION_VIEW, CATEGORY_BROWSEABLE, and at least one scheme 1451 if (!filter.hasAction(Intent.ACTION_VIEW) 1452 || !filter.hasCategory(Intent.CATEGORY_BROWSABLE) 1453 || filter.countDataSchemes() == 0) { 1454 return false; 1455 } 1456 // Now allow only the schemes "http" and "https" 1457 final Iterator<String> schemesIterator = filter.schemesIterator(); 1458 while (schemesIterator.hasNext()) { 1459 final String scheme = schemesIterator.next(); 1460 final boolean isWebScheme = "http".equals(scheme) || "https".equals(scheme); 1461 if (isWebScheme) { 1462 return true; 1463 } 1464 } 1465 return false; 1466 } 1467 getResult()1468 private TestResult getResult() { 1469 final TestResult result; 1470 try { 1471 result = mResultQueue.poll(25, TimeUnit.SECONDS); 1472 } catch (InterruptedException e) { 1473 throw new RuntimeException(e); 1474 } 1475 if (result == null) { 1476 throw new IllegalStateException("Activity didn't receive a Result in 25 seconds"); 1477 } 1478 return result; 1479 } 1480 grantInstantAppForegroundServicePermission()1481 private static void grantInstantAppForegroundServicePermission() throws IOException { 1482 InstrumentationRegistry.getInstrumentation().getUiAutomation().grantRuntimePermission( 1483 InstrumentationRegistry.getContext().getPackageName(), 1484 android.Manifest.permission.INSTANT_APP_FOREGROUND_SERVICE); 1485 } 1486 makeIntent(String action, String category, String mimeType)1487 private static Intent makeIntent(String action, String category, String mimeType) { 1488 Intent intent = new Intent(action); 1489 if (category != null) { 1490 intent.addCategory(category); 1491 } 1492 if (mimeType != null) { 1493 intent.setType(mimeType); 1494 } 1495 return intent; 1496 } 1497 1498 private static class ActivityBroadcastReceiver extends BroadcastReceiver { 1499 private final SynchronousQueue<TestResult> mQueue; ActivityBroadcastReceiver(SynchronousQueue<TestResult> queue)1500 public ActivityBroadcastReceiver(SynchronousQueue<TestResult> queue) { 1501 mQueue = queue; 1502 } 1503 1504 @Override onReceive(Context context, Intent intent)1505 public void onReceive(Context context, Intent intent) { 1506 try { 1507 mQueue.offer(intent.getParcelableExtra(TestResult.EXTRA_TEST_RESULT), 1508 5, TimeUnit.SECONDS); 1509 } catch (InterruptedException e) { 1510 throw new RuntimeException(e); 1511 } 1512 } 1513 } 1514 1515 private static class TestServiceConnection implements ServiceConnection { 1516 @Override onServiceConnected(ComponentName name, IBinder service)1517 public void onServiceConnected(ComponentName name, IBinder service) { 1518 } 1519 @Override onServiceDisconnected(ComponentName name)1520 public void onServiceDisconnected(ComponentName name) { 1521 } 1522 } 1523 } 1524