1 /*
2  * Copyright (C) 2019 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.usespermissiondiffcertapp;
18 
19 import static com.android.cts.usespermissiondiffcertapp.AccessPermissionWithDiffSigTest.GRANTABLE;
20 import static com.android.cts.usespermissiondiffcertapp.AccessPermissionWithDiffSigTest.GRANTABLE_MODES;
21 import static com.android.cts.usespermissiondiffcertapp.AccessPermissionWithDiffSigTest.NOT_GRANTABLE;
22 import static com.android.cts.usespermissiondiffcertapp.AccessPermissionWithDiffSigTest.NOT_GRANTABLE_MODES;
23 import static com.android.cts.usespermissiondiffcertapp.Asserts.assertAccess;
24 import static com.android.cts.usespermissiondiffcertapp.UriGrantsTest.TAG;
25 import static com.android.cts.usespermissiondiffcertapp.Utils.grantClipUriPermissionViaActivities;
26 import static com.android.cts.usespermissiondiffcertapp.Utils.grantClipUriPermissionViaActivity;
27 
28 import static junit.framework.Assert.fail;
29 
30 import android.content.ClipData;
31 import android.content.Context;
32 import android.content.Intent;
33 import android.net.Uri;
34 import android.os.SystemClock;
35 import android.util.Log;
36 
37 import androidx.test.InstrumentationRegistry;
38 import androidx.test.runner.AndroidJUnit4;
39 
40 import org.junit.After;
41 import org.junit.Test;
42 import org.junit.runner.RunWith;
43 
44 import java.util.function.Function;
45 
46 @RunWith(AndroidJUnit4.class)
47 public class UriGrantsActivityTest {
getContext()48     private static Context getContext() {
49         return InstrumentationRegistry.getTargetContext();
50     }
51 
52     @After
tearDown()53     public void tearDown() throws Exception {
54         // Always dispose, usually to clean up from failed tests
55         ReceiveUriActivity.finishCurInstanceSync();
56     }
57 
58     @Test
testGrantableToActivity()59     public void testGrantableToActivity() {
60         for (Uri uri : GRANTABLE) {
61             for (int mode : GRANTABLE_MODES) {
62                 Log.d(TAG, "Testing " + uri + " " + mode);
63                 assertGrantableToActivity(uri, mode, UriGrantsTest::makeSingleClipData);
64                 assertGrantableToActivity(uri, mode, UriGrantsTest::makeMultiClipData);
65             }
66         }
67     }
68 
assertGrantableToActivity(Uri uri, int mode, Function<Uri, ClipData> clipper)69     private void assertGrantableToActivity(Uri uri, int mode, Function<Uri, ClipData> clipper) {
70         final Uri subUri = Uri.withAppendedPath(uri, "foo");
71         final Uri subSubUri = Uri.withAppendedPath(subUri, "bar");
72         final Uri sub2Uri = Uri.withAppendedPath(uri, "yes");
73         final Uri sub2SubUri = Uri.withAppendedPath(sub2Uri, "no");
74 
75         final ClipData subClip = clipper.apply(subUri);
76         final ClipData sub2Clip = clipper.apply(sub2Uri);
77 
78         assertAccess(uri, 0);
79         assertAccess(subClip, 0);
80         assertAccess(subUri, 0);
81         assertAccess(subSubUri, 0);
82         assertAccess(sub2Clip, 0);
83         assertAccess(sub2Uri, 0);
84         assertAccess(sub2SubUri, 0);
85 
86         // --------------------------------
87 
88         ReceiveUriActivity.clearStarted();
89         grantClipUriPermissionViaActivities(subClip, mode);
90         ReceiveUriActivity.waitForStart();
91 
92         assertAccess(uri, 0);
93         assertAccess(subClip, mode);
94         assertAccess(subUri, mode);
95         assertAccess(subSubUri, 0);
96         assertAccess(sub2Clip, 0);
97         assertAccess(sub2Uri, 0);
98         assertAccess(sub2SubUri, 0);
99 
100         // --------------------------------
101 
102         ReceiveUriActivity.clearNewIntent();
103         grantClipUriPermissionViaActivity(sub2Clip, mode);
104         ReceiveUriActivity.waitForNewIntent();
105 
106         assertAccess(uri, 0);
107         assertAccess(subClip, mode);
108         assertAccess(subUri, mode);
109         assertAccess(subSubUri, 0);
110         assertAccess(sub2Clip, mode);
111         assertAccess(sub2Uri, mode);
112         assertAccess(sub2SubUri, 0);
113 
114         // And make sure we can't generate a permission to a running activity.
115         assertNotGrantableToActivity(Uri.withAppendedPath(uri, "hah"), mode, clipper);
116 
117         // --------------------------------
118 
119         // Dispose of activity.
120         ReceiveUriActivity.finishCurInstanceSync();
121         SystemClock.sleep(200);
122 
123         assertAccess(uri, 0);
124         assertAccess(subClip, 0);
125         assertAccess(subUri, 0);
126         assertAccess(subSubUri, 0);
127         assertAccess(sub2Clip, 0);
128         assertAccess(sub2Uri, 0);
129         assertAccess(sub2SubUri, 0);
130     }
131 
132     @Test
testNotGrantableToActivity()133     public void testNotGrantableToActivity() {
134         for (Uri uri : NOT_GRANTABLE) {
135             for (int mode : NOT_GRANTABLE_MODES) {
136                 Log.d(TAG, "Testing " + uri + " " + mode);
137                 assertNotGrantableToActivity(uri, mode, UriGrantsTest::makeSingleClipData);
138                 assertNotGrantableToActivity(uri, mode, UriGrantsTest::makeMultiClipData);
139             }
140         }
141     }
142 
assertNotGrantableToActivity(Uri uri, int mode, Function<Uri, ClipData> clipper)143     private void assertNotGrantableToActivity(Uri uri, int mode, Function<Uri, ClipData> clipper) {
144         final Uri subUri = Uri.withAppendedPath(uri, "foo");
145         final ClipData subClip = clipper.apply(subUri);
146 
147         Intent grantIntent = new Intent();
148         grantIntent.setClipData(subClip);
149         grantIntent.addFlags(mode | Intent.FLAG_ACTIVITY_NEW_TASK);
150         grantIntent.setClass(getContext(), ReceiveUriActivity.class);
151         try {
152             ReceiveUriActivity.clearStarted();
153             getContext().startActivity(grantIntent);
154             ReceiveUriActivity.waitForStart();
155             fail("expected SecurityException granting " + subClip + " to activity");
156         } catch (SecurityException e) {
157             // This is what we want.
158         }
159     }
160 }
161