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.contacts; 18 19 import com.android.contacts.list.ContactListFilterController; 20 import com.android.contacts.model.AccountTypeManager; 21 import com.android.contacts.test.InjectedServices; 22 import com.android.contacts.util.Constants; 23 import com.google.common.annotations.VisibleForTesting; 24 25 import android.app.Application; 26 import android.app.FragmentManager; 27 import android.app.LoaderManager; 28 import android.content.ContentResolver; 29 import android.content.ContentUris; 30 import android.content.Context; 31 import android.content.SharedPreferences; 32 import android.os.AsyncTask; 33 import android.os.StrictMode; 34 import android.preference.PreferenceManager; 35 import android.provider.ContactsContract.Contacts; 36 import android.util.Log; 37 38 public final class ContactsApplication extends Application { 39 private static final boolean ENABLE_LOADER_LOG = false; // Don't submit with true 40 private static final boolean ENABLE_FRAGMENT_LOG = false; // Don't submit with true 41 42 private static InjectedServices sInjectedServices; 43 private AccountTypeManager mAccountTypeManager; 44 private ContactPhotoManager mContactPhotoManager; 45 private ContactListFilterController mContactListFilterController; 46 47 /** 48 * Overrides the system services with mocks for testing. 49 */ 50 @VisibleForTesting injectServices(InjectedServices services)51 public static void injectServices(InjectedServices services) { 52 sInjectedServices = services; 53 } 54 getInjectedServices()55 public static InjectedServices getInjectedServices() { 56 return sInjectedServices; 57 } 58 59 @Override getContentResolver()60 public ContentResolver getContentResolver() { 61 if (sInjectedServices != null) { 62 ContentResolver resolver = sInjectedServices.getContentResolver(); 63 if (resolver != null) { 64 return resolver; 65 } 66 } 67 return super.getContentResolver(); 68 } 69 70 @Override getSharedPreferences(String name, int mode)71 public SharedPreferences getSharedPreferences(String name, int mode) { 72 if (sInjectedServices != null) { 73 SharedPreferences prefs = sInjectedServices.getSharedPreferences(); 74 if (prefs != null) { 75 return prefs; 76 } 77 } 78 79 return super.getSharedPreferences(name, mode); 80 } 81 82 @Override getSystemService(String name)83 public Object getSystemService(String name) { 84 if (sInjectedServices != null) { 85 Object service = sInjectedServices.getSystemService(name); 86 if (service != null) { 87 return service; 88 } 89 } 90 91 if (AccountTypeManager.ACCOUNT_TYPE_SERVICE.equals(name)) { 92 if (mAccountTypeManager == null) { 93 mAccountTypeManager = AccountTypeManager.createAccountTypeManager(this); 94 } 95 return mAccountTypeManager; 96 } 97 98 if (ContactPhotoManager.CONTACT_PHOTO_SERVICE.equals(name)) { 99 if (mContactPhotoManager == null) { 100 mContactPhotoManager = ContactPhotoManager.createContactPhotoManager(this); 101 registerComponentCallbacks(mContactPhotoManager); 102 mContactPhotoManager.preloadPhotosInBackground(); 103 } 104 return mContactPhotoManager; 105 } 106 107 if (ContactListFilterController.CONTACT_LIST_FILTER_SERVICE.equals(name)) { 108 if (mContactListFilterController == null) { 109 mContactListFilterController = 110 ContactListFilterController.createContactListFilterController(this); 111 } 112 return mContactListFilterController; 113 } 114 115 return super.getSystemService(name); 116 } 117 118 @Override onCreate()119 public void onCreate() { 120 super.onCreate(); 121 122 if (Log.isLoggable(Constants.PERFORMANCE_TAG, Log.DEBUG)) { 123 Log.d(Constants.PERFORMANCE_TAG, "ContactsApplication.onCreate start"); 124 } 125 126 if (ENABLE_FRAGMENT_LOG) FragmentManager.enableDebugLogging(true); 127 if (ENABLE_LOADER_LOG) LoaderManager.enableDebugLogging(true); 128 129 if (Log.isLoggable(Constants.STRICT_MODE_TAG, Log.DEBUG)) { 130 StrictMode.setThreadPolicy( 131 new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build()); 132 } 133 134 // Perform the initialization that doesn't have to finish immediately. 135 // We use an async task here just to avoid creating a new thread. 136 (new DelayedInitializer()).execute(); 137 138 if (Log.isLoggable(Constants.PERFORMANCE_TAG, Log.DEBUG)) { 139 Log.d(Constants.PERFORMANCE_TAG, "ContactsApplication.onCreate finish"); 140 } 141 } 142 143 private class DelayedInitializer extends AsyncTask<Void, Void, Void> { 144 @Override doInBackground(Void... params)145 protected Void doInBackground(Void... params) { 146 final Context context = ContactsApplication.this; 147 148 // Warm up the preferences, the account type manager and the contacts provider. 149 PreferenceManager.getDefaultSharedPreferences(context); 150 AccountTypeManager.getInstance(context); 151 getContentResolver().getType(ContentUris.withAppendedId(Contacts.CONTENT_URI, 1)); 152 return null; 153 } 154 execute()155 public void execute() { 156 executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, 157 (Void[]) null); 158 } 159 } 160 } 161