1 /*
2  * Copyright (C) 2011 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.contacts;
18 
19 import android.content.ContentProvider;
20 import android.content.ContentValues;
21 import android.content.Context;
22 import android.content.ContextWrapper;
23 import android.content.Intent;
24 import android.content.pm.PackageManager;
25 import android.os.Process;
26 import android.provider.CallLog.Calls;
27 import android.provider.VoicemailContract;
28 
29 import java.io.File;
30 import java.util.ArrayList;
31 import java.util.Collections;
32 import java.util.List;
33 
34 /**
35  * Base class for all tests that require interacting with the voicemail content provider.
36  */
37 public abstract class BaseVoicemailProviderTest extends BaseContactsProvider2Test {
38 
39     protected boolean mUseSourceUri = false;
40     private File mTestDirectory;
41     ContactsMockPackageManager mPackageManager;
42 
43     @Override
setUp()44     protected void setUp() throws Exception {
45         super.setUp();
46         TestVoicemailProvider.setVvmProviderCallDelegate(createMockProviderCalls());
47 
48         mPackageManager = (ContactsMockPackageManager) getProvider()
49                 .getContext().getPackageManager();
50         mPackageManager.addPackage(Process.myUid(), mActor.packageName);
51     }
52 
53     @Override
tearDown()54     protected void tearDown() throws Exception {
55         removeTestDirectory();
56         super.tearDown();
57     }
58 
59     @Override
getProviderClass()60     protected Class<? extends ContentProvider> getProviderClass() {
61        return TestVoicemailProvider.class;
62     }
63 
64     @Override
getAuthority()65     protected String getAuthority() {
66         return VoicemailContract.AUTHORITY;
67     }
68 
setUpForOwnPermission()69     protected void setUpForOwnPermission() {
70         mActor.removePermissions(READ_VOICEMAIL_PERMISSION);
71         mActor.removePermissions(WRITE_VOICEMAIL_PERMISSION);
72         mActor.addPermissions(ADD_VOICEMAIL_PERMISSION);
73         mActor.revokeCarrierPrivileges();
74         mUseSourceUri = true;
75     }
76 
setUpForOwnPermissionViaCarrierPrivileges()77     protected void setUpForOwnPermissionViaCarrierPrivileges() {
78         mActor.removePermissions(READ_VOICEMAIL_PERMISSION);
79         mActor.removePermissions(WRITE_VOICEMAIL_PERMISSION);
80         mActor.removePermissions(ADD_VOICEMAIL_PERMISSION);
81         mActor.grantCarrierPrivileges();
82         mUseSourceUri = true;
83     }
84 
setUpForFullPermission()85     protected void setUpForFullPermission() {
86         mActor.addPermissions(ADD_VOICEMAIL_PERMISSION);
87         mActor.addPermissions(READ_VOICEMAIL_PERMISSION);
88         mActor.addPermissions(WRITE_VOICEMAIL_PERMISSION);
89         mActor.revokeCarrierPrivileges();
90         mUseSourceUri = false;
91     }
92 
setUpForNoPermission()93     protected void setUpForNoPermission() {
94         mActor.removePermissions(ADD_VOICEMAIL_PERMISSION);
95         mActor.removePermissions(READ_VOICEMAIL_PERMISSION);
96         mActor.removePermissions(WRITE_VOICEMAIL_PERMISSION);
97         mActor.revokeCarrierPrivileges();
98         mUseSourceUri = true;
99     }
100 
countFilesInTestDirectory()101     protected int countFilesInTestDirectory() {
102         return findAllFiles(mTestDirectory).size();
103     }
104 
105     // TODO: Use a mocking framework to mock these calls.
createMockProviderCalls()106     private VvmProviderCalls createMockProviderCalls() {
107         return new VvmProviderCalls() {
108             @Override
109             public void sendOrderedBroadcast(Intent intent, String receiverPermission) {
110                 // Do nothing for now.
111             }
112 
113             @Override
114             public File getDir(String name, int mode) {
115                 return getTestDirectory();
116             }
117 
118             @Override
119             public PackageManager getPackageManager() {
120                 return mActor.getProviderContext().getPackageManager();
121             }
122         };
123     }
124 
125     /** Lazily construct the test directory when required. */
126     private synchronized File getTestDirectory() {
127         if (mTestDirectory == null) {
128             File baseDirectory = getContext().getCacheDir();
129             mTestDirectory = new File(baseDirectory, Long.toString(System.currentTimeMillis()));
130             assertFalse(mTestDirectory.exists());
131             assertTrue(mTestDirectory.mkdirs());
132         }
133         return mTestDirectory;
134     }
135 
136     private void removeTestDirectory() {
137         if (mTestDirectory != null) {
138             recursiveDeleteAll(mTestDirectory);
139         }
140     }
141 
142     private static void recursiveDeleteAll(File input) {
143         if (input.isDirectory()) {
144             for (File file : input.listFiles()) {
145                 recursiveDeleteAll(file);
146             }
147         }
148         assertTrue("error deleting " + input.getAbsolutePath(), input.delete());
149     }
150 
151     private List<File> findAllFiles(File input) {
152         if (input == null) {
153             return Collections.emptyList();
154         }
155         if (!input.isDirectory()) {
156             return Collections.singletonList(input);
157         }
158         List<File> results = new ArrayList<File>();
159         for (File file : input.listFiles()) {
160             results.addAll(findAllFiles(file));
161         }
162         return results;
163     }
164 
165     /** The calls that we need to mock out for our VvmProvider, used by TestVoicemailProvider. */
166     private interface VvmProviderCalls {
167         public void sendOrderedBroadcast(Intent intent, String receiverPermission);
168         public File getDir(String name, int mode);
169         public PackageManager getPackageManager();
170     }
171 
172     public static class TestVoicemailProvider extends VoicemailContentProvider {
173         private static VvmProviderCalls mDelegate;
174         public static synchronized void setVvmProviderCallDelegate(VvmProviderCalls delegate) {
175             mDelegate = delegate;
176         }
177 
178         // Run the tasks synchronously.
179         @Override
180         void scheduleTask(int taskId, Object arg) {
181             performBackgroundTask(taskId, arg);
182         }
183 
184         @Override
185         protected CallLogDatabaseHelper getDatabaseHelper(Context context) {
186             return new CallLogDatabaseHelperTestable(context, /* contactsDbForMigration = */ null);
187         }
188 
189         @Override
190         protected Context context() {
191             return new ContextWrapper(getContext()) {
192                 @Override
193                 public File getDir(String name, int mode) {
194                     return mDelegate.getDir(name, mode);
195                 }
196                 @Override
197                 public void sendBroadcast(Intent intent, String receiverPermission) {
198                     mDelegate.sendOrderedBroadcast(intent, receiverPermission);
199                 }
200                 @Override
201                 public PackageManager getPackageManager() {
202                     return mDelegate.getPackageManager();
203                 }
204             };
205         }
206 
207         @Override
208         protected String getInjectedCallingPackage() {
209             return getContext().getPackageName();
210         }
211 
212         @Override
213         CallLogInsertionHelper createCallLogInsertionHelper(Context context) {
214             return new CallLogInsertionHelper() {
215                 @Override
216                 public String getGeocodedLocationFor(String number, String countryIso) {
217                     return "usa";
218                 }
219 
220                 @Override
221                 public void addComputedValues(ContentValues values) {
222                     values.put(Calls.COUNTRY_ISO, "us");
223                     values.put(Calls.GEOCODED_LOCATION, "usa");
224                 }
225             };
226         }
227     }
228 }
229