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