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 package com.android.documentsui.testing;
17 
18 import android.os.Process;
19 import android.os.UserHandle;
20 import android.provider.DocumentsContract.Root;
21 
22 import com.android.documentsui.InspectorProvider;
23 import com.android.documentsui.base.Providers;
24 import com.android.documentsui.base.RootInfo;
25 import com.android.documentsui.base.State;
26 import com.android.documentsui.base.UserId;
27 import com.android.documentsui.roots.ProvidersAccess;
28 
29 import java.util.ArrayList;
30 import java.util.Collection;
31 import java.util.HashMap;
32 import java.util.List;
33 import java.util.Map;
34 
35 import javax.annotation.Nullable;
36 
37 public class TestProvidersAccess implements ProvidersAccess {
38 
39     public static final UserHandle USER_HANDLE = Process.myUserHandle();
40     public static final UserId USER_ID = UserId.of(USER_HANDLE);
41 
42     public static final RootInfo DOWNLOADS;
43     public static final RootInfo HOME;
44     public static final RootInfo HAMMY;
45     public static final RootInfo PICKLES;
46     public static final RootInfo RECENTS;
47     public static final RootInfo INSPECTOR;
48     public static final RootInfo IMAGE;
49     public static final RootInfo AUDIO;
50     public static final RootInfo VIDEO;
51     public static final RootInfo DOCUMENT;
52     public static final RootInfo EXTERNALSTORAGE;
53     public static final RootInfo NO_TREE_ROOT;
54     public static final RootInfo SD_CARD;
55 
56     static {
57         UserId userId = TestProvidersAccess.USER_ID;
58 
59         DOWNLOADS = new RootInfo() {{
60             flags = Root.FLAG_SUPPORTS_CREATE;
61         }};
62         DOWNLOADS.userId = userId;
63         DOWNLOADS.authority = Providers.AUTHORITY_DOWNLOADS;
64         DOWNLOADS.rootId = Providers.ROOT_ID_DOWNLOADS;
65         DOWNLOADS.title = "Downloads";
66         DOWNLOADS.derivedType = RootInfo.TYPE_DOWNLOADS;
67         DOWNLOADS.flags = Root.FLAG_LOCAL_ONLY
68                 | Root.FLAG_SUPPORTS_CREATE
69                 | Root.FLAG_SUPPORTS_RECENTS;
70 
71         HOME = new RootInfo();
72         HOME.userId = userId;
73         HOME.authority = Providers.AUTHORITY_STORAGE;
74         HOME.rootId = Providers.ROOT_ID_HOME;
75         HOME.title = "Home";
76         HOME.derivedType = RootInfo.TYPE_LOCAL;
77         HOME.flags = Root.FLAG_LOCAL_ONLY
78                 | Root.FLAG_SUPPORTS_CREATE
79                 | Root.FLAG_SUPPORTS_IS_CHILD
80                 | Root.FLAG_SUPPORTS_RECENTS;
81 
82         HAMMY = new RootInfo();
83         HAMMY.userId = userId;
84         HAMMY.authority = "yummies";
85         HAMMY.rootId = "hamsandwich";
86         HAMMY.title = "Ham Sandwich";
87         HAMMY.derivedType = RootInfo.TYPE_LOCAL;
88         HAMMY.flags = Root.FLAG_LOCAL_ONLY;
89 
90         PICKLES = new RootInfo();
91         PICKLES.userId = userId;
92         PICKLES.authority = "yummies";
93         PICKLES.rootId = "pickles";
94         PICKLES.title = "Pickles";
95         PICKLES.summary = "Yummy pickles";
96 
97         RECENTS = new RootInfo() {
98             {
99                 // Special root for recents
100                 derivedType = RootInfo.TYPE_RECENTS;
101                 flags = Root.FLAG_LOCAL_ONLY;
102                 availableBytes = -1;
103             }
104         };
105         RECENTS.userId = userId;
106         RECENTS.title = "Recents";
107 
108         INSPECTOR = new RootInfo();
109         INSPECTOR.userId = userId;
110         INSPECTOR.authority = InspectorProvider.AUTHORITY;
111         INSPECTOR.rootId = InspectorProvider.ROOT_ID;
112         INSPECTOR.title = "Inspector";
113         INSPECTOR.flags = Root.FLAG_LOCAL_ONLY
114                 | Root.FLAG_SUPPORTS_CREATE;
115 
116         IMAGE = new RootInfo();
117         IMAGE.userId = userId;
118         IMAGE.authority = Providers.AUTHORITY_MEDIA;
119         IMAGE.rootId = Providers.ROOT_ID_IMAGES;
120         IMAGE.title = "Images";
121         IMAGE.derivedType = RootInfo.TYPE_IMAGES;
122 
123         AUDIO = new RootInfo();
124         AUDIO.userId = userId;
125         AUDIO.authority = Providers.AUTHORITY_MEDIA;
126         AUDIO.rootId = Providers.ROOT_ID_AUDIO;
127         AUDIO.title = "Audio";
128         AUDIO.derivedType = RootInfo.TYPE_AUDIO;
129 
130         VIDEO = new RootInfo();
131         VIDEO.userId = userId;
132         VIDEO.authority = Providers.AUTHORITY_MEDIA;
133         VIDEO.rootId = Providers.ROOT_ID_VIDEOS;
134         VIDEO.title = "Videos";
135         VIDEO.derivedType = RootInfo.TYPE_VIDEO;
136 
137         DOCUMENT = new RootInfo();
138         DOCUMENT.userId = userId;
139         DOCUMENT.authority = Providers.AUTHORITY_MEDIA;
140         DOCUMENT.rootId = Providers.ROOT_ID_DOCUMENTS;
141         DOCUMENT.title = "Documents";
142         DOCUMENT.derivedType = RootInfo.TYPE_DOCUMENTS;
143 
144         EXTERNALSTORAGE = new RootInfo();
145         EXTERNALSTORAGE.userId = userId;
146         EXTERNALSTORAGE.authority = Providers.AUTHORITY_STORAGE;
147         EXTERNALSTORAGE.rootId = Providers.ROOT_ID_DEVICE;
148         EXTERNALSTORAGE.title = "Device";
149         EXTERNALSTORAGE.derivedType = RootInfo.TYPE_LOCAL;
150         EXTERNALSTORAGE.flags = Root.FLAG_LOCAL_ONLY
151                 | Root.FLAG_SUPPORTS_IS_CHILD;
152 
153         NO_TREE_ROOT = new RootInfo();
154         NO_TREE_ROOT.userId = userId;
155         NO_TREE_ROOT.authority = "no.tree.authority";
156         NO_TREE_ROOT.rootId = "1";
157         NO_TREE_ROOT.title = "No Tree Title";
158         NO_TREE_ROOT.derivedType = RootInfo.TYPE_LOCAL;
159         NO_TREE_ROOT.flags = Root.FLAG_LOCAL_ONLY;
160 
161         SD_CARD = new RootInfo();
162         SD_CARD.userId = userId;
163         SD_CARD.authority = Providers.AUTHORITY_STORAGE;
164         SD_CARD.rootId = Providers.ROOT_ID_DOCUMENTS;
165         SD_CARD.title = "SD card";
166         SD_CARD.derivedType = RootInfo.TYPE_SD;
167         SD_CARD.flags = Root.FLAG_LOCAL_ONLY
168                 | Root.FLAG_SUPPORTS_IS_CHILD;
169     }
170 
171     public static class OtherUser {
172         public static final UserHandle USER_HANDLE = UserHandle.of(
173                 TestProvidersAccess.USER_ID.getIdentifier() + 1);
174         public static final UserId USER_ID = UserId.of(OtherUser.USER_HANDLE);
175 
176         public static final RootInfo DOWNLOADS;
177         public static final RootInfo HOME;
178         public static final RootInfo IMAGE;
179         public static final RootInfo PICKLES;
180         public static final RootInfo MTP_ROOT;
181 
182         static {
183             UserId userId = OtherUser.USER_ID;
184 
185             DOWNLOADS = new RootInfo();
186             DOWNLOADS.userId = userId;
187             DOWNLOADS.authority = Providers.AUTHORITY_DOWNLOADS;
188             DOWNLOADS.rootId = Providers.ROOT_ID_DOWNLOADS;
189             DOWNLOADS.title = "Downloads";
190             DOWNLOADS.derivedType = RootInfo.TYPE_DOWNLOADS;
191             DOWNLOADS.flags = Root.FLAG_LOCAL_ONLY
192                     | Root.FLAG_SUPPORTS_CREATE
193                     | Root.FLAG_SUPPORTS_RECENTS;
194 
195             HOME = new RootInfo();
196             HOME.userId = userId;
197             HOME.authority = Providers.AUTHORITY_STORAGE;
198             HOME.rootId = Providers.ROOT_ID_HOME;
199             HOME.title = "Home";
200             HOME.derivedType = RootInfo.TYPE_LOCAL;
201             HOME.flags = Root.FLAG_LOCAL_ONLY
202                     | Root.FLAG_SUPPORTS_CREATE
203                     | Root.FLAG_SUPPORTS_IS_CHILD
204                     | Root.FLAG_SUPPORTS_RECENTS;
205 
206             IMAGE = new RootInfo();
207             IMAGE.userId = userId;
208             IMAGE.authority = Providers.AUTHORITY_MEDIA;
209             IMAGE.rootId = Providers.ROOT_ID_IMAGES;
210             IMAGE.title = "Images";
211             IMAGE.derivedType = RootInfo.TYPE_IMAGES;
212 
213             PICKLES = new RootInfo();
214             PICKLES.userId = userId;
215             PICKLES.authority = "yummies";
216             PICKLES.rootId = "pickles";
217             PICKLES.title = "Pickles";
218             PICKLES.summary = "Yummy pickles";
219 
220             MTP_ROOT = new RootInfo();
221             MTP_ROOT.userId = userId;
222             MTP_ROOT.authority = Providers.AUTHORITY_MTP;
223             MTP_ROOT.rootId = Providers.ROOT_ID_DOCUMENTS;
224             MTP_ROOT.title = "MTP";
225             MTP_ROOT.derivedType = RootInfo.TYPE_MTP;
226             MTP_ROOT.flags = Root.FLAG_SUPPORTS_CREATE
227                     | Root.FLAG_LOCAL_ONLY
228                     | Root.FLAG_SUPPORTS_IS_CHILD;
229         }
230     }
231 
232     public static class AnotherUser {
233         public static final UserHandle USER_HANDLE = UserHandle.of(
234                 TestProvidersAccess.USER_ID.getIdentifier() + 2);
235         public static final UserId USER_ID = UserId.of(AnotherUser.USER_HANDLE);
236 
237         public static final RootInfo DOWNLOADS;
238         public static final RootInfo HOME;
239         public static final RootInfo IMAGE;
240         public static final RootInfo PICKLES;
241         public static final RootInfo MTP_ROOT;
242 
243         static {
244             UserId userId = AnotherUser.USER_ID;
245 
246             DOWNLOADS = new RootInfo();
247             DOWNLOADS.userId = userId;
248             DOWNLOADS.authority = Providers.AUTHORITY_DOWNLOADS;
249             DOWNLOADS.rootId = Providers.ROOT_ID_DOWNLOADS;
250             DOWNLOADS.title = "Downloads";
251             DOWNLOADS.derivedType = RootInfo.TYPE_DOWNLOADS;
252             DOWNLOADS.flags = Root.FLAG_LOCAL_ONLY
253                     | Root.FLAG_SUPPORTS_CREATE
254                     | Root.FLAG_SUPPORTS_RECENTS;
255 
256             HOME = new RootInfo();
257             HOME.userId = userId;
258             HOME.authority = Providers.AUTHORITY_STORAGE;
259             HOME.rootId = Providers.ROOT_ID_HOME;
260             HOME.title = "Home";
261             HOME.derivedType = RootInfo.TYPE_LOCAL;
262             HOME.flags = Root.FLAG_LOCAL_ONLY
263                     | Root.FLAG_SUPPORTS_CREATE
264                     | Root.FLAG_SUPPORTS_IS_CHILD
265                     | Root.FLAG_SUPPORTS_RECENTS;
266 
267             IMAGE = new RootInfo();
268             IMAGE.userId = userId;
269             IMAGE.authority = Providers.AUTHORITY_MEDIA;
270             IMAGE.rootId = Providers.ROOT_ID_IMAGES;
271             IMAGE.title = "Images";
272             IMAGE.derivedType = RootInfo.TYPE_IMAGES;
273 
274             PICKLES = new RootInfo();
275             PICKLES.userId = userId;
276             PICKLES.authority = "yummies";
277             PICKLES.rootId = "pickles";
278             PICKLES.title = "Pickles";
279             PICKLES.summary = "Yummy pickles";
280 
281             MTP_ROOT = new RootInfo();
282             MTP_ROOT.userId = userId;
283             MTP_ROOT.authority = Providers.AUTHORITY_MTP;
284             MTP_ROOT.rootId = Providers.ROOT_ID_DOCUMENTS;
285             MTP_ROOT.title = "MTP";
286             MTP_ROOT.derivedType = RootInfo.TYPE_MTP;
287             MTP_ROOT.flags = Root.FLAG_SUPPORTS_CREATE
288                     | Root.FLAG_LOCAL_ONLY
289                     | Root.FLAG_SUPPORTS_IS_CHILD;
290         }
291     }
292 
293     public final Map<String, Collection<RootInfo>> roots = new HashMap<>();
294     private @Nullable RootInfo nextRoot;
295 
TestProvidersAccess()296     public TestProvidersAccess() {
297         add(DOWNLOADS);
298         add(HOME);
299         add(HAMMY);
300         add(PICKLES);
301         add(EXTERNALSTORAGE);
302         add(NO_TREE_ROOT);
303     }
304 
add(RootInfo root)305     private void add(RootInfo root) {
306         if (!roots.containsKey(root.authority)) {
307             roots.put(root.authority, new ArrayList<>());
308         }
309         roots.get(root.authority).add(root);
310     }
311 
configurePm(TestPackageManager pm)312     public void configurePm(TestPackageManager pm) {
313         pm.addStubContentProviderForRoot(TestProvidersAccess.DOWNLOADS);
314         pm.addStubContentProviderForRoot(TestProvidersAccess.HOME);
315         pm.addStubContentProviderForRoot(TestProvidersAccess.HAMMY);
316         pm.addStubContentProviderForRoot(TestProvidersAccess.PICKLES);
317         pm.addStubContentProviderForRoot(TestProvidersAccess.NO_TREE_ROOT);
318     }
319 
320     @Override
getRootOneshot(UserId userId, String authority, String rootId)321     public RootInfo getRootOneshot(UserId userId, String authority, String rootId) {
322         if (roots.containsKey(authority)) {
323             for (RootInfo root : roots.get(authority)) {
324                 if (rootId.equals(root.rootId) && root.userId.equals(userId)) {
325                     return root;
326                 }
327             }
328         }
329         return null;
330     }
331 
332     @Override
getMatchingRootsBlocking(State state)333     public Collection<RootInfo> getMatchingRootsBlocking(State state) {
334         List<RootInfo> allRoots = new ArrayList<>();
335         for (String authority : roots.keySet()) {
336             allRoots.addAll(roots.get(authority));
337         }
338         return ProvidersAccess.getMatchingRoots(allRoots, state);
339     }
340 
341     @Override
getRootsForAuthorityBlocking(UserId userId, String authority)342     public Collection<RootInfo> getRootsForAuthorityBlocking(UserId userId, String authority) {
343         return roots.get(authority);
344     }
345 
346     @Override
getRootsBlocking()347     public Collection<RootInfo> getRootsBlocking() {
348         List<RootInfo> result = new ArrayList<>();
349         for (Collection<RootInfo> vals : roots.values()) {
350             result.addAll(vals);
351         }
352         return result;
353     }
354 
355     @Override
getDefaultRootBlocking(State state)356     public RootInfo getDefaultRootBlocking(State state) {
357         return DOWNLOADS;
358     }
359 
360     @Override
getRecentsRoot(UserId userId)361     public RootInfo getRecentsRoot(UserId userId) {
362         return RECENTS;
363     }
364 
365     @Override
getApplicationName(UserId userId, String authority)366     public String getApplicationName(UserId userId, String authority) {
367         return "Test Application";
368     }
369 
370     @Override
getPackageName(UserId userId, String authority)371     public String getPackageName(UserId userId, String authority) {
372         return "com.android.documentsui";
373     }
374 }
375