1 /* 2 * Copyright (C) 2015 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.messaging; 18 19 import android.content.Context; 20 import android.os.Process; 21 import android.telephony.SmsManager; 22 import android.util.SparseArray; 23 24 import com.android.messaging.datamodel.DataModel; 25 import com.android.messaging.datamodel.DataModelImpl; 26 import com.android.messaging.datamodel.MemoryCacheManager; 27 import com.android.messaging.datamodel.ParticipantRefresh.ContactContentObserver; 28 import com.android.messaging.datamodel.data.ParticipantData; 29 import com.android.messaging.datamodel.media.BugleMediaCacheManager; 30 import com.android.messaging.datamodel.media.MediaCacheManager; 31 import com.android.messaging.datamodel.media.MediaResourceManager; 32 import com.android.messaging.sms.BugleCarrierConfigValuesLoader; 33 import com.android.messaging.ui.UIIntents; 34 import com.android.messaging.ui.UIIntentsImpl; 35 import com.android.messaging.util.Assert; 36 import com.android.messaging.util.BugleApplicationPrefs; 37 import com.android.messaging.util.BugleGservices; 38 import com.android.messaging.util.BugleGservicesImpl; 39 import com.android.messaging.util.BuglePrefs; 40 import com.android.messaging.util.BugleSubscriptionPrefs; 41 import com.android.messaging.util.BugleWidgetPrefs; 42 import com.android.messaging.util.LogUtil; 43 import com.android.messaging.util.MediaUtil; 44 import com.android.messaging.util.MediaUtilImpl; 45 import com.android.messaging.util.OsUtil; 46 import com.android.messaging.util.PhoneUtils; 47 48 import java.util.concurrent.ConcurrentHashMap; 49 50 class FactoryImpl extends Factory { 51 private BugleApplication mApplication; 52 private DataModel mDataModel; 53 private BugleGservices mBugleGservices; 54 private BugleApplicationPrefs mBugleApplicationPrefs; 55 private BugleWidgetPrefs mBugleWidgetPrefs; 56 private Context mApplicationContext; 57 private UIIntents mUIIntents; 58 private MemoryCacheManager mMemoryCacheManager; 59 private MediaResourceManager mMediaResourceManager; 60 private MediaCacheManager mMediaCacheManager; 61 private ContactContentObserver mContactContentObserver; 62 private PhoneUtils mPhoneUtils; 63 private MediaUtil mMediaUtil; 64 private SparseArray<BugleSubscriptionPrefs> mSubscriptionPrefs; 65 private BugleCarrierConfigValuesLoader mCarrierConfigValuesLoader; 66 67 // Cached instance for Pre-L_MR1 68 private static final Object PHONEUTILS_INSTANCE_LOCK = new Object(); 69 private static PhoneUtils sPhoneUtilsInstancePreLMR1 = null; 70 // Cached subId->instance for L_MR1 and beyond 71 private static final ConcurrentHashMap<Integer, PhoneUtils> sPhoneUtilsInstanceCacheLMR1 = 72 new ConcurrentHashMap<>(); 73 74 private FactoryImpl() { 75 } 76 77 public static Factory register(final Context applicationContext, 78 final BugleApplication application) { 79 // This only gets called once (from BugleApplication.onCreate), but its not called in tests. 80 Assert.isTrue(!sRegistered); 81 Assert.isNull(Factory.get()); 82 83 final FactoryImpl factory = new FactoryImpl(); 84 Factory.setInstance(factory); 85 sRegistered = true; 86 87 // At this point Factory is published. Services can now get initialized and depend on 88 // Factory.get(). 89 factory.mApplication = application; 90 factory.mApplicationContext = applicationContext; 91 factory.mMemoryCacheManager = new MemoryCacheManager(); 92 factory.mMediaCacheManager = new BugleMediaCacheManager(); 93 factory.mMediaResourceManager = new MediaResourceManager(); 94 factory.mBugleGservices = new BugleGservicesImpl(applicationContext); 95 factory.mBugleApplicationPrefs = new BugleApplicationPrefs(applicationContext); 96 factory.mDataModel = new DataModelImpl(applicationContext); 97 factory.mBugleWidgetPrefs = new BugleWidgetPrefs(applicationContext); 98 factory.mUIIntents = new UIIntentsImpl(); 99 factory.mContactContentObserver = new ContactContentObserver(); 100 factory.mMediaUtil = new MediaUtilImpl(); 101 factory.mSubscriptionPrefs = new SparseArray<BugleSubscriptionPrefs>(); 102 factory.mCarrierConfigValuesLoader = new BugleCarrierConfigValuesLoader(applicationContext); 103 104 Assert.initializeGservices(factory.mBugleGservices); 105 LogUtil.initializeGservices(factory.mBugleGservices); 106 107 if (OsUtil.hasRequiredPermissions()) { 108 factory.onRequiredPermissionsAcquired(); 109 } 110 111 return factory; 112 } 113 114 @Override 115 public void onRequiredPermissionsAcquired() { 116 if (sInitialized) { 117 return; 118 } 119 sInitialized = true; 120 121 mApplication.initializeSync(this); 122 123 final Thread asyncInitialization = new Thread() { 124 @Override 125 public void run() { 126 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 127 mApplication.initializeAsync(FactoryImpl.this); 128 } 129 }; 130 asyncInitialization.start(); 131 } 132 133 @Override 134 public Context getApplicationContext() { 135 return mApplicationContext; 136 } 137 138 @Override 139 public DataModel getDataModel() { 140 return mDataModel; 141 } 142 143 @Override 144 public BugleGservices getBugleGservices() { 145 return mBugleGservices; 146 } 147 148 @Override 149 public BuglePrefs getApplicationPrefs() { 150 return mBugleApplicationPrefs; 151 } 152 153 @Override 154 public BuglePrefs getWidgetPrefs() { 155 return mBugleWidgetPrefs; 156 } 157 158 @Override 159 public BuglePrefs getSubscriptionPrefs(int subId) { 160 subId = PhoneUtils.getDefault().getEffectiveSubId(subId); 161 BugleSubscriptionPrefs pref = mSubscriptionPrefs.get(subId); 162 if (pref == null) { 163 synchronized (this) { 164 if ((pref = mSubscriptionPrefs.get(subId)) == null) { 165 pref = new BugleSubscriptionPrefs(getApplicationContext(), subId); 166 mSubscriptionPrefs.put(subId, pref); 167 } 168 } 169 } 170 return pref; 171 } 172 173 @Override 174 public UIIntents getUIIntents() { 175 return mUIIntents; 176 } 177 178 @Override 179 public MemoryCacheManager getMemoryCacheManager() { 180 return mMemoryCacheManager; 181 } 182 183 @Override 184 public MediaResourceManager getMediaResourceManager() { 185 return mMediaResourceManager; 186 } 187 188 @Override 189 public MediaCacheManager getMediaCacheManager() { 190 return mMediaCacheManager; 191 } 192 193 @Override 194 public ContactContentObserver getContactContentObserver() { 195 return mContactContentObserver; 196 } 197 198 @Override 199 public PhoneUtils getPhoneUtils(int subId) { 200 if (OsUtil.isAtLeastL_MR1()) { 201 if (subId == ParticipantData.DEFAULT_SELF_SUB_ID) { 202 subId = SmsManager.getDefaultSmsSubscriptionId(); 203 } 204 if (subId < 0) { 205 LogUtil.w(LogUtil.BUGLE_TAG, "PhoneUtils.getForLMR1(): invalid subId = " + subId); 206 subId = ParticipantData.DEFAULT_SELF_SUB_ID; 207 } 208 PhoneUtils instance = sPhoneUtilsInstanceCacheLMR1.get(subId); 209 if (instance == null) { 210 instance = new PhoneUtils.PhoneUtilsLMR1(subId); 211 sPhoneUtilsInstanceCacheLMR1.putIfAbsent(subId, instance); 212 } 213 return instance; 214 } else { 215 Assert.isTrue(subId == ParticipantData.DEFAULT_SELF_SUB_ID); 216 if (sPhoneUtilsInstancePreLMR1 == null) { 217 synchronized (PHONEUTILS_INSTANCE_LOCK) { 218 if (sPhoneUtilsInstancePreLMR1 == null) { 219 sPhoneUtilsInstancePreLMR1 = new PhoneUtils.PhoneUtilsPreLMR1(); 220 } 221 } 222 } 223 return sPhoneUtilsInstancePreLMR1; 224 } 225 } 226 227 @Override 228 public void reclaimMemory() { 229 mMemoryCacheManager.reclaimMemory(); 230 } 231 232 @Override 233 public void onActivityResume() { 234 } 235 236 @Override 237 public MediaUtil getMediaUtil() { 238 return mMediaUtil; 239 } 240 241 @Override 242 public BugleCarrierConfigValuesLoader getCarrierConfigValuesLoader() { 243 return mCarrierConfigValuesLoader; 244 } 245 } 246