• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 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 android.test;
18 
19 import com.google.android.collect.Sets;
20 
21 import android.content.Context;
22 import android.content.ContextWrapper;
23 import android.content.ContentProvider;
24 import android.database.DatabaseErrorHandler;
25 import android.database.sqlite.SQLiteDatabase;
26 import android.os.FileUtils;
27 import android.util.Log;
28 
29 import java.io.File;
30 import java.io.FileInputStream;
31 import java.io.FileNotFoundException;
32 import java.io.FileOutputStream;
33 import java.util.Set;
34 
35 /**
36  * This is a class which delegates to the given context, but performs database
37  * and file operations with a renamed database/file name (prefixes default
38  * names with a given prefix).
39  *
40  * @deprecated New tests should be written using the
41  * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
42  */
43 @Deprecated
44 public class RenamingDelegatingContext extends ContextWrapper {
45 
46     private Context mFileContext;
47     private String mFilePrefix = null;
48     private File mCacheDir;
49     private final Object mSync = new Object();
50 
51     private Set<String> mDatabaseNames = Sets.newHashSet();
52     private Set<String> mFileNames = Sets.newHashSet();
53 
providerWithRenamedContext( Class<T> contentProvider, Context c, String filePrefix)54     public static <T extends ContentProvider> T providerWithRenamedContext(
55             Class<T> contentProvider, Context c, String filePrefix)
56             throws IllegalAccessException, InstantiationException {
57         return providerWithRenamedContext(contentProvider, c, filePrefix, false);
58     }
59 
providerWithRenamedContext( Class<T> contentProvider, Context c, String filePrefix, boolean allowAccessToExistingFilesAndDbs)60     public static <T extends ContentProvider> T providerWithRenamedContext(
61             Class<T> contentProvider, Context c, String filePrefix,
62             boolean allowAccessToExistingFilesAndDbs)
63             throws IllegalAccessException, InstantiationException {
64         Class<T> mProviderClass = contentProvider;
65         T mProvider = mProviderClass.newInstance();
66         RenamingDelegatingContext mContext = new RenamingDelegatingContext(c, filePrefix);
67         if (allowAccessToExistingFilesAndDbs) {
68             mContext.makeExistingFilesAndDbsAccessible();
69         }
70         mProvider.attachInfoForTesting(mContext, null);
71         return mProvider;
72     }
73 
74     /**
75      * Makes accessible all files and databases whose names match the filePrefix that was passed to
76      * the constructor. Normally only files and databases that were created through this context are
77      * accessible.
78      */
makeExistingFilesAndDbsAccessible()79     public void makeExistingFilesAndDbsAccessible() {
80         String[] databaseList = mFileContext.databaseList();
81         for (String diskName : databaseList) {
82             if (shouldDiskNameBeVisible(diskName)) {
83                 mDatabaseNames.add(publicNameFromDiskName(diskName));
84             }
85         }
86         String[] fileList = mFileContext.fileList();
87         for (String diskName : fileList) {
88             if (shouldDiskNameBeVisible(diskName)) {
89                 mFileNames.add(publicNameFromDiskName(diskName));
90             }
91         }
92     }
93 
94     /**
95      * Returns if the given diskName starts with the given prefix or not.
96      * @param diskName name of the database/file.
97      */
shouldDiskNameBeVisible(String diskName)98     boolean shouldDiskNameBeVisible(String diskName) {
99         return diskName.startsWith(mFilePrefix);
100     }
101 
102     /**
103      * Returns the public name (everything following the prefix) of the given diskName.
104      * @param diskName name of the database/file.
105      */
publicNameFromDiskName(String diskName)106     String publicNameFromDiskName(String diskName) {
107         if (!shouldDiskNameBeVisible(diskName)) {
108             throw new IllegalArgumentException("disk file should not be visible: " + diskName);
109         }
110         return diskName.substring(mFilePrefix.length(), diskName.length());
111     }
112 
113     /**
114      * @param context : the context that will be delegated.
115      * @param filePrefix : a prefix with which database and file names will be
116      * prefixed.
117      */
RenamingDelegatingContext(Context context, String filePrefix)118     public RenamingDelegatingContext(Context context, String filePrefix) {
119         super(context);
120         mFileContext = context;
121         mFilePrefix = filePrefix;
122     }
123 
124     /**
125      * @param context : the context that will be delegated.
126      * @param fileContext : the context that file and db methods will be delegated to
127      * @param filePrefix : a prefix with which database and file names will be
128      * prefixed.
129      */
RenamingDelegatingContext(Context context, Context fileContext, String filePrefix)130     public RenamingDelegatingContext(Context context, Context fileContext, String filePrefix) {
131         super(context);
132         mFileContext = fileContext;
133         mFilePrefix = filePrefix;
134     }
135 
getDatabasePrefix()136     public String getDatabasePrefix() {
137         return mFilePrefix;
138     }
139 
renamedFileName(String name)140     private String renamedFileName(String name) {
141         return mFilePrefix + name;
142     }
143 
144     @Override
openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory)145     public SQLiteDatabase openOrCreateDatabase(String name,
146             int mode, SQLiteDatabase.CursorFactory factory) {
147         final String internalName = renamedFileName(name);
148         if (!mDatabaseNames.contains(name)) {
149             mDatabaseNames.add(name);
150             mFileContext.deleteDatabase(internalName);
151         }
152         return mFileContext.openOrCreateDatabase(internalName, mode, factory);
153     }
154 
155     @Override
openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler)156     public SQLiteDatabase openOrCreateDatabase(String name,
157             int mode, SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler) {
158         final String internalName = renamedFileName(name);
159         if (!mDatabaseNames.contains(name)) {
160             mDatabaseNames.add(name);
161             mFileContext.deleteDatabase(internalName);
162         }
163         return mFileContext.openOrCreateDatabase(internalName, mode, factory, errorHandler);
164     }
165 
166     @Override
deleteDatabase(String name)167     public boolean deleteDatabase(String name) {
168         if (mDatabaseNames.contains(name)) {
169             mDatabaseNames.remove(name);
170             return mFileContext.deleteDatabase(renamedFileName(name));
171         } else {
172             return false;
173         }
174     }
175 
176     @Override
getDatabasePath(String name)177     public File getDatabasePath(String name) {
178         return mFileContext.getDatabasePath(renamedFileName(name));
179     }
180 
181     @Override
databaseList()182     public String[] databaseList() {
183         return mDatabaseNames.toArray(new String[]{});
184     }
185 
186     @Override
openFileInput(String name)187     public FileInputStream openFileInput(String name)
188             throws FileNotFoundException {
189         final String internalName = renamedFileName(name);
190         if (mFileNames.contains(name)) {
191             return mFileContext.openFileInput(internalName);
192         } else {
193             throw new FileNotFoundException(internalName);
194         }
195     }
196 
197     @Override
openFileOutput(String name, int mode)198     public FileOutputStream openFileOutput(String name, int mode)
199             throws FileNotFoundException {
200         mFileNames.add(name);
201         return mFileContext.openFileOutput(renamedFileName(name), mode);
202     }
203 
204     @Override
getFileStreamPath(String name)205     public File getFileStreamPath(String name) {
206         return mFileContext.getFileStreamPath(renamedFileName(name));
207     }
208 
209     @Override
deleteFile(String name)210     public boolean deleteFile(String name) {
211         if (mFileNames.contains(name)) {
212             mFileNames.remove(name);
213             return mFileContext.deleteFile(renamedFileName(name));
214         } else {
215             return false;
216         }
217     }
218 
219     @Override
fileList()220     public String[] fileList() {
221         return mFileNames.toArray(new String[]{});
222     }
223 
224     /**
225      * In order to support calls to getCacheDir(), we create a temp cache dir (inside the real
226      * one) and return it instead.  This code is basically getCacheDir(), except it uses the real
227      * cache dir as the parent directory and creates a test cache dir inside that.
228      */
229     @Override
getCacheDir()230     public File getCacheDir() {
231         synchronized (mSync) {
232             if (mCacheDir == null) {
233                 mCacheDir = new File(mFileContext.getCacheDir(), renamedFileName("cache"));
234             }
235             if (!mCacheDir.exists()) {
236                 if(!mCacheDir.mkdirs()) {
237                     Log.w("RenamingDelegatingContext", "Unable to create cache directory");
238                     return null;
239                 }
240                 FileUtils.setPermissions(
241                         mCacheDir.getPath(),
242                         FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
243                         -1, -1);
244             }
245         }
246         return mCacheDir;
247     }
248 }
249