• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.providers.media;
18 
19 import android.content.ContentProvider;
20 import android.content.ContentResolver;
21 import android.content.Context;
22 import android.content.ContextWrapper;
23 import android.content.pm.ProviderInfo;
24 import android.os.Bundle;
25 import android.os.UserHandle;
26 import android.provider.CloudMediaProvider;
27 import android.provider.MediaStore;
28 import android.provider.Settings;
29 import android.test.mock.MockContentProvider;
30 import android.test.mock.MockContentResolver;
31 
32 import com.android.providers.media.cloudproviders.CloudProviderPrimary;
33 import com.android.providers.media.photopicker.PhotoPickerProvider;
34 import com.android.providers.media.photopicker.PickerSyncController;
35 import com.android.providers.media.util.FileUtils;
36 
37 import java.io.File;
38 import java.util.Optional;
39 
40 /**
41  * Class to support mocking Context class for tests.
42  */
43 public class IsolatedContext extends ContextWrapper {
44     private final File mDir;
45     private final MockContentResolver mResolver;
46     private final MediaProvider mMediaProvider;
47     private final UserHandle mUserHandle;
48 
IsolatedContext(Context base, String tag, boolean asFuseThread)49     public IsolatedContext(Context base, String tag, boolean asFuseThread) {
50         this(base, tag, asFuseThread, base.getUser());
51     }
52 
IsolatedContext(Context base, String tag, boolean asFuseThread, UserHandle userHandle)53     public IsolatedContext(Context base, String tag, boolean asFuseThread,
54             UserHandle userHandle) {
55         this(base, tag, asFuseThread, userHandle, new TestConfigStore());
56     }
57 
IsolatedContext(Context base, String tag, boolean asFuseThread, UserHandle userHandle, ConfigStore configStore)58     public IsolatedContext(Context base, String tag, boolean asFuseThread,
59             UserHandle userHandle, ConfigStore configStore) {
60         super(base);
61         mDir = new File(base.getFilesDir(), tag);
62         mDir.mkdirs();
63         FileUtils.deleteContents(mDir);
64 
65         mResolver = new MockContentResolver(this);
66         mUserHandle = userHandle;
67 
68         mMediaProvider = getMockedMediaProvider(asFuseThread, configStore);
69         attachInfoAndAddProvider(base, mMediaProvider, MediaStore.AUTHORITY);
70 
71         MediaDocumentsProvider documentsProvider = new MediaDocumentsProvider();
72         attachInfoAndAddProvider(base, documentsProvider, MediaDocumentsProvider.AUTHORITY);
73 
74         mResolver.addProvider(Settings.AUTHORITY, new MockContentProvider() {
75             @Override
76             public Bundle call(String method, String request, Bundle args) {
77                 return Bundle.EMPTY;
78             }
79         });
80 
81         PhotoPickerProvider photoPickerProvider = new PhotoPickerProvider();
82         attachInfoAndAddProvider(base, photoPickerProvider,
83                 PickerSyncController.LOCAL_PICKER_PROVIDER_AUTHORITY);
84 
85         final CloudMediaProvider cmp = new CloudProviderPrimary();
86         attachInfoAndAddProvider(base, cmp, CloudProviderPrimary.AUTHORITY);
87 
88         MediaStore.waitForIdle(mResolver);
89     }
90 
getMockedMediaProvider(boolean asFuseThread, ConfigStore configStore)91     private MediaProvider getMockedMediaProvider(boolean asFuseThread,
92             ConfigStore configStore) {
93         return new MediaProvider() {
94             @Override
95             public boolean isFuseThread() {
96                 return asFuseThread;
97             }
98 
99             @Override
100             protected ConfigStore provideConfigStore() {
101                 return configStore;
102             }
103 
104             @Override
105             protected DatabaseBackupAndRecovery createDatabaseBackupAndRecovery() {
106                 return new TestDatabaseBackupAndRecovery(configStore, getVolumeCache());
107             }
108 
109             @Override
110             protected void storageNativeBootPropertyChangeListener() {
111                 // Ignore this as test app cannot read device config
112             }
113         };
114     }
115 
116     @Override
117     public File getDatabasePath(String name) {
118         return new File(mDir, name);
119     }
120 
121     @Override
122     public ContentResolver getContentResolver() {
123         return mResolver;
124     }
125 
126     @Override
127     public UserHandle getUser() {
128         return mUserHandle;
129     }
130 
131     public void setPickerUriResolver(PickerUriResolver resolver) {
132         mMediaProvider.setUriResolver(resolver);
133     }
134 
135     private void attachInfoAndAddProvider(Context base, ContentProvider provider,
136             String authority) {
137         final ProviderInfo info = base.getPackageManager().resolveContentProvider(authority, 0);
138         provider.attachInfo(this, info);
139         mResolver.addProvider(authority, provider);
140     }
141 
142     /**
143      * @return {@link DatabaseHelper} The external database helper used by the test {@link
144      * IsolatedContext}
145      */
146     public DatabaseHelper getExternalDatabase() throws IllegalStateException {
147         Optional<DatabaseHelper> helper =
148                 mMediaProvider.getDatabaseHelper(DatabaseHelper.EXTERNAL_DATABASE_NAME);
149         if (helper.isPresent()) {
150             return helper.get();
151         } else {
152             throw new IllegalStateException("Failed to get Database helper");
153         }
154     }
155 
156 }
157