Home | History | Annotate | Download | only in ephemeralapp1
      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