blob: 1efa4153073a02c3147d09b59488437a83813a6a [file] [log] [blame]
Jason Monkbf3eedc2018-04-05 20:56:42 -04001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 * except in compliance with the License. You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the
10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11 * KIND, either express or implied. See the License for the specific language governing
12 * permissions and limitations under the License.
13 */
14
15package com.android.server.slice;
16
17import static org.junit.Assert.assertEquals;
18import static org.junit.Assert.assertFalse;
19import static org.junit.Assert.assertTrue;
20import static org.mockito.ArgumentMatchers.eq;
21import static org.mockito.Mockito.clearInvocations;
22import static org.mockito.Mockito.mock;
23import static org.mockito.Mockito.verify;
24
25import android.content.ContentResolver;
26import android.net.Uri;
27import android.support.test.filters.SmallTest;
28import android.testing.AndroidTestingRunner;
29import android.testing.TestableLooper.RunWithLooper;
30import android.util.Xml.Encoding;
31
32import com.android.server.UiServiceTestCase;
33import com.android.server.slice.SlicePermissionManager.PkgUser;
34import com.android.server.slice.SliceClientPermissions.SliceAuthority;
35
36import org.junit.Test;
37import org.junit.runner.RunWith;
38import org.xmlpull.v1.XmlPullParser;
39import org.xmlpull.v1.XmlPullParserException;
40import org.xmlpull.v1.XmlPullParserFactory;
41import org.xmlpull.v1.XmlSerializer;
42
43import java.io.ByteArrayInputStream;
44import java.io.ByteArrayOutputStream;
45import java.io.IOException;
46import java.util.ArrayList;
47import java.util.Arrays;
48import java.util.Comparator;
49
50@SmallTest
51@RunWith(AndroidTestingRunner.class)
52@RunWithLooper
53public class SliceClientPermissionsTest extends UiServiceTestCase {
54
55 @Test
56 public void testRemoveBasic() {
57 PkgUser pkg = new PkgUser("com.android.pkg", 0);
58 DirtyTracker tracker = mock(DirtyTracker.class);
59 SliceClientPermissions client = new SliceClientPermissions(pkg, tracker);
60 Uri base = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
61 .authority("com.android.pkg.slices").build();
62
63 PkgUser testPkg = new PkgUser("other", 2);
64
65 client.grantUri(base.buildUpon()
66 .appendPath("first")
67 .build(), testPkg);
68 client.revokeUri(base.buildUpon()
69 .appendPath("first")
70 .build(), testPkg);
71
72 assertFalse(client.hasPermission(base.buildUpon()
73 .appendPath("first")
74 .appendPath("third")
75 .build(), testPkg.getUserId()));
76
77 ArrayList<SliceAuthority> authorities = new ArrayList<>(client.getAuthorities());
78 assertEquals(0, authorities.get(0).getPaths().size());
79 }
80
81 @Test
82 public void testRemoveSubtrees() {
83 PkgUser pkg = new PkgUser("com.android.pkg", 0);
84 DirtyTracker tracker = mock(DirtyTracker.class);
85 SliceClientPermissions client = new SliceClientPermissions(pkg, tracker);
86 Uri base = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
87 .authority("com.android.pkg.slices").build();
88
89 PkgUser testPkg = new PkgUser("other", 2);
90
91 client.grantUri(base.buildUpon()
92 .appendPath("first")
93 .appendPath("second")
94 .build(), testPkg);
95 client.grantUri(base.buildUpon()
96 .appendPath("first")
97 .appendPath("third")
98 .build(), testPkg);
99 client.revokeUri(base.buildUpon()
100 .appendPath("first")
101 .build(), testPkg);
102
103 assertFalse(client.hasPermission(base.buildUpon()
104 .appendPath("first")
105 .appendPath("fourth")
106 .build(), testPkg.getUserId()));
107
108 ArrayList<SliceAuthority> authorities = new ArrayList<>(client.getAuthorities());
109 assertEquals(0, authorities.get(0).getPaths().size());
110 }
111
112 @Test
113 public void testAddConsolidate_addFirst() {
114 PkgUser pkg = new PkgUser("com.android.pkg", 0);
115 DirtyTracker tracker = mock(DirtyTracker.class);
116 SliceClientPermissions client = new SliceClientPermissions(pkg, tracker);
117 Uri base = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
118 .authority("com.android.pkg.slices").build();
119
120 PkgUser testPkg = new PkgUser("other", 2);
121
122 client.grantUri(base.buildUpon()
123 .appendPath("first")
124 .build(), testPkg);
125 client.grantUri(base.buildUpon()
126 .appendPath("first")
127 .appendPath("second")
128 .build(), testPkg);
129
130 assertTrue(client.hasPermission(base.buildUpon()
131 .appendPath("first")
132 .appendPath("third")
133 .build(), testPkg.getUserId()));
134
135 ArrayList<SliceAuthority> authorities = new ArrayList<>(client.getAuthorities());
136 assertEquals(1, authorities.get(0).getPaths().size());
137 }
138
139 @Test
140 public void testAddConsolidate_addSecond() {
141 PkgUser pkg = new PkgUser("com.android.pkg", 0);
142 DirtyTracker tracker = mock(DirtyTracker.class);
143 SliceClientPermissions client = new SliceClientPermissions(pkg, tracker);
144 Uri base = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
145 .authority("com.android.pkg.slices").build();
146
147 PkgUser testPkg = new PkgUser("other", 2);
148
149 client.grantUri(base.buildUpon()
150 .appendPath("first")
151 .appendPath("second")
152 .build(), testPkg);
153 client.grantUri(base.buildUpon()
154 .appendPath("first")
155 .build(), testPkg);
156
157 assertTrue(client.hasPermission(base.buildUpon()
158 .appendPath("first")
159 .appendPath("third")
160 .build(), testPkg.getUserId()));
161
162 ArrayList<SliceAuthority> authorities = new ArrayList<>(client.getAuthorities());
163 assertEquals(1, authorities.get(0).getPaths().size());
164 }
165
166 @Test
167 public void testDirty_addAuthority() {
168 PkgUser pkg = new PkgUser("com.android.pkg", 0);
169 DirtyTracker tracker = mock(DirtyTracker.class);
170 SliceClientPermissions client = new SliceClientPermissions(pkg, tracker);
171
172 client.getOrCreateAuthority(new PkgUser("some_auth", 2), new PkgUser("com.pkg", 2));
173
174 verify(tracker).onPersistableDirty(eq(client));
175 }
176
177 @Test
178 public void testDirty_addPkg() {
179 PkgUser pkg = new PkgUser("com.android.pkg", 0);
180 DirtyTracker tracker = mock(DirtyTracker.class);
181 SliceClientPermissions client = new SliceClientPermissions(pkg, tracker);
182
183 SliceAuthority auth = client.getOrCreateAuthority(
184 new PkgUser("some_auth", 2),
185 new PkgUser("com.pkg", 2));
186 clearInvocations(tracker);
187
188 auth.addPath(Arrays.asList("/something/"));
189
190 verify(tracker).onPersistableDirty(eq(client));
191 }
192
193 @Test
194 public void testCreation() {
195 SliceClientPermissions client = createClient();
196 ArrayList<SliceAuthority> authorities = new ArrayList<>(client.getAuthorities());
197 authorities.sort(Comparator.comparing(SliceAuthority::getAuthority));
198
199 assertEquals(2, authorities.size());
200 assertEquals("com.android.pkg", authorities.get(0).getAuthority());
201 assertEquals("com.android.pkg.slices", authorities.get(1).getAuthority());
202
203 assertEquals(1, authorities.get(0).getPaths().size());
204 assertEquals(2, authorities.get(1).getPaths().size());
205 }
206
207 @Test
208 public void testSerialization() throws XmlPullParserException, IOException {
209 SliceClientPermissions client = createClient();
210 client.setHasFullAccess(true);
211
212 ByteArrayOutputStream output = new ByteArrayOutputStream();
213 XmlSerializer serializer = XmlPullParserFactory.newInstance().newSerializer();
214 serializer.setOutput(output, Encoding.UTF_8.name());
215
216 client.writeTo(serializer);
217 serializer.flush();
218
219 ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray());
220 XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
221 parser.setInput(input, Encoding.UTF_8.name());
222
223 SliceClientPermissions deser = SliceClientPermissions.createFrom(parser,
224 mock(DirtyTracker.class));
225
226 assertEquivalent(client, deser);
227 }
228
229 private void assertEquivalent(SliceClientPermissions o1, SliceClientPermissions o2) {
230 assertEquals(o1.getPkg(), o2.getPkg());
231 ArrayList<SliceAuthority> a1 = new ArrayList<>(o1.getAuthorities());
232 ArrayList<SliceAuthority> a2 = new ArrayList<>(o2.getAuthorities());
233 a1.sort(Comparator.comparing(SliceAuthority::getAuthority));
234 a2.sort(Comparator.comparing(SliceAuthority::getAuthority));
235 assertEquals(a1, a2);
236 }
237
238 private static SliceClientPermissions createClient() {
239 PkgUser pkg = new PkgUser("com.android.pkg", 2);
240 DirtyTracker tracker = mock(DirtyTracker.class);
241 SliceClientPermissions client = new SliceClientPermissions(pkg, tracker);
242
243 SliceAuthority auth = client.getOrCreateAuthority(
244 new PkgUser("com.android.pkg.slices", 3),
245 new PkgUser("com.android.pkg", 3));
246 auth.addPath(Arrays.asList("/something/"));
247 auth.addPath(Arrays.asList("/something/else"));
248
249 auth = client.getOrCreateAuthority(
250 new PkgUser("com.android.pkg", 3),
251 new PkgUser("com.pkg", 1));
252 auth.addPath(Arrays.asList("/somewhere"));
253 return client;
254 }
255
256}