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