1 /* 2 * Copyright (C) 2010 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.email; 18 19 import android.content.ContentProvider; 20 import android.content.ContentResolver; 21 import android.content.ContentValues; 22 import android.content.Context; 23 import android.content.SharedPreferences; 24 import android.content.res.Resources; 25 import android.content.res.Resources.Theme; 26 import android.database.Cursor; 27 import android.net.Uri; 28 import android.test.IsolatedContext; 29 import android.test.RenamingDelegatingContext; 30 import android.test.mock.MockContentResolver; 31 import android.test.mock.MockContext; 32 import android.test.mock.MockCursor; 33 34 import com.android.email.provider.AttachmentProvider; 35 import com.android.email.provider.ContentCache; 36 import com.android.email.provider.EmailProvider; 37 import com.android.emailcommon.provider.EmailContent; 38 import com.android.emailcommon.provider.EmailContent.Attachment; 39 40 import java.io.File; 41 42 /** 43 * Helper classes (and possibly methods) for database related tests. 44 */ 45 public final class DBTestHelper { DBTestHelper()46 private DBTestHelper() { // Utility class. No instantiation. 47 } 48 49 /** 50 * A simple {@link Context} that returns {@link MyProvider} as the email content provider. 51 */ 52 public static class MyContext extends MockContext { 53 private final MockContentResolver mContentResolver; 54 private final MyProvider mProvider; 55 MyContext()56 public MyContext() { 57 mProvider = new MyProvider(); 58 mContentResolver = new MockContentResolver(); 59 mContentResolver.addProvider(EmailContent.AUTHORITY, mProvider); 60 } 61 62 @Override getContentResolver()63 public ContentResolver getContentResolver() { 64 return mContentResolver; 65 } 66 getMyProvider()67 public MyProvider getMyProvider() { 68 return mProvider; 69 } 70 } 71 72 /** 73 * A simply {@link ContentProvider} to mock out {@link ContentProvider#query}. 74 */ 75 public static class MyProvider extends ContentProvider { 76 public Cursor mQueryPresetResult; 77 public Uri mPassedUri; 78 public String[] mPassedProjection; 79 public String mPassedSelection; 80 public String[] mPassedSelectionArgs; 81 public String mPassedSortOrder; 82 reset()83 public void reset() { 84 mQueryPresetResult = null; 85 mPassedUri = null; 86 mPassedProjection = null; 87 mPassedSelection = null; 88 mPassedSelectionArgs = null; 89 mPassedSortOrder = null; 90 } 91 92 @Override query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)93 public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, 94 String sortOrder) { 95 mPassedUri = uri; 96 mPassedProjection = projection; 97 mPassedSelection = selection; 98 mPassedSelectionArgs = selectionArgs; 99 mPassedSortOrder = sortOrder; 100 return mQueryPresetResult; 101 } 102 103 @Override delete(Uri uri, String selection, String[] selectionArgs)104 public int delete(Uri uri, String selection, String[] selectionArgs) { 105 throw new UnsupportedOperationException(); 106 } 107 108 @Override getType(Uri uri)109 public String getType(Uri uri) { 110 throw new UnsupportedOperationException(); 111 } 112 113 @Override insert(Uri uri, ContentValues values)114 public Uri insert(Uri uri, ContentValues values) { 115 throw new UnsupportedOperationException(); 116 } 117 118 @Override onCreate()119 public boolean onCreate() { 120 throw new UnsupportedOperationException(); 121 } 122 123 @Override update(Uri uri, ContentValues values, String selection, String[] selectionArgs)124 public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 125 throw new UnsupportedOperationException(); 126 } 127 } 128 129 /** 130 * Simple {@link MockCursor} subclass that implements common methods. 131 */ 132 public static class EasyMockCursor extends MockCursor { 133 public int mCount; 134 public boolean mClosed; 135 EasyMockCursor(int count)136 public EasyMockCursor(int count) { 137 mCount = count; 138 } 139 140 @Override getCount()141 public int getCount() { 142 return mCount; 143 } 144 145 @Override close()146 public void close() { 147 mClosed = true; 148 } 149 } 150 151 /** 152 * This class has only one method, that creats an isolated {@link Context} similar to what 153 * {@link android.test.ProviderTestCase2} provides. 154 * 155 * The method also creates a {@link ContentProvider} of {@code providerClass}, and add it to 156 * the context. See the javadoc on android.test.ProviderTestCase2 for the details. 157 */ 158 public static class ProviderContextSetupHelper { 159 // Based on ProviderTestCase2.MockContext2. 160 private static class MockContext2 extends MockContext { 161 private final Context mBaseContext; 162 MockContext2(Context baseContext)163 public MockContext2(Context baseContext) { 164 mBaseContext = baseContext; 165 } 166 167 @Override getResources()168 public Resources getResources() { 169 return mBaseContext.getResources(); 170 } 171 172 @Override getDir(String name, int mode)173 public File getDir(String name, int mode) { 174 return mBaseContext.getDir("mockcontext2_" + name, mode); 175 } 176 } 177 178 /** {@link IsolatedContext} + getApplicationContext() */ 179 private static class MyIsolatedContext extends IsolatedContext { 180 private final Context mRealContext; 181 MyIsolatedContext(ContentResolver resolver, Context targetContext, Context realContext)182 public MyIsolatedContext(ContentResolver resolver, Context targetContext, 183 Context realContext) { 184 super(resolver, targetContext); 185 mRealContext = realContext; 186 } 187 188 @Override getApplicationContext()189 public Context getApplicationContext() { 190 return this; 191 } 192 193 // Following methods are not supported by the mock context. 194 // Redirect to the actual context. 195 @Override getPackageName()196 public String getPackageName() { 197 return mRealContext.getPackageName(); 198 } 199 200 @Override getTheme()201 public Theme getTheme() { 202 return mRealContext.getTheme(); 203 } 204 205 @Override getSharedPreferences(String name, int mode)206 public SharedPreferences getSharedPreferences(String name, int mode) { 207 return new MockSharedPreferences(); 208 } 209 210 @Override getSystemService(String name)211 public Object getSystemService(String name) { 212 if (Context.LAYOUT_INFLATER_SERVICE.equals(name)) { 213 return mRealContext.getSystemService(name); 214 } 215 return super.getSystemService(name); 216 } 217 } 218 219 /** 220 * Return {@link Context} with isolated EmailProvider and AttachmentProvider. This method 221 * also invalidates the DB cache. 222 */ getProviderContext(Context context)223 public static Context getProviderContext(Context context) throws Exception { 224 MockContentResolver resolver = new MockContentResolver(); 225 final String filenamePrefix = "test."; 226 RenamingDelegatingContext targetContextWrapper = new RenamingDelegatingContext( 227 new MockContext2(context), // The context that most methods are delegated to 228 context, // The context that file methods are delegated to 229 filenamePrefix); 230 final Context providerContext = new MyIsolatedContext(resolver, targetContextWrapper, 231 context); 232 providerContext.getContentResolver(); 233 234 // register EmailProvider and AttachmentProvider. 235 final EmailProvider ep = new EmailProvider(); 236 ep.attachInfo(providerContext, null); 237 resolver.addProvider(EmailContent.AUTHORITY, ep); 238 239 final AttachmentProvider ap = new AttachmentProvider(); 240 ap.attachInfo(providerContext, null); 241 resolver.addProvider(Attachment.ATTACHMENT_PROVIDER_LEGACY_URI_PREFIX, ap); 242 243 ContentCache.invalidateAllCaches(); 244 245 return providerContext; 246 } 247 } 248 } 249