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