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 
     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