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