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 
FactoryImpl()74     private FactoryImpl() {
75     }
76 
register(final Context applicationContext, final BugleApplication application)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
onRequiredPermissionsAcquired()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
getApplicationContext()134     public Context getApplicationContext() {
135         return mApplicationContext;
136     }
137 
138     @Override
getDataModel()139     public DataModel getDataModel() {
140         return mDataModel;
141     }
142 
143     @Override
getBugleGservices()144     public BugleGservices getBugleGservices() {
145         return mBugleGservices;
146     }
147 
148     @Override
getApplicationPrefs()149     public BuglePrefs getApplicationPrefs() {
150         return mBugleApplicationPrefs;
151     }
152 
153     @Override
getWidgetPrefs()154     public BuglePrefs getWidgetPrefs() {
155         return mBugleWidgetPrefs;
156     }
157 
158     @Override
getSubscriptionPrefs(int subId)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
getUIIntents()174     public UIIntents getUIIntents() {
175         return mUIIntents;
176     }
177 
178     @Override
getMemoryCacheManager()179     public MemoryCacheManager getMemoryCacheManager() {
180         return mMemoryCacheManager;
181     }
182 
183     @Override
getMediaResourceManager()184     public MediaResourceManager getMediaResourceManager() {
185         return mMediaResourceManager;
186     }
187 
188     @Override
getMediaCacheManager()189     public MediaCacheManager getMediaCacheManager() {
190         return mMediaCacheManager;
191     }
192 
193     @Override
getContactContentObserver()194     public ContactContentObserver getContactContentObserver() {
195         return mContactContentObserver;
196     }
197 
198     @Override
getPhoneUtils(int subId)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
reclaimMemory()228     public void reclaimMemory() {
229         mMemoryCacheManager.reclaimMemory();
230     }
231 
232     @Override
onActivityResume()233     public void onActivityResume() {
234     }
235 
236     @Override
getMediaUtil()237     public MediaUtil getMediaUtil() {
238         return mMediaUtil;
239     }
240 
241     @Override
getCarrierConfigValuesLoader()242     public BugleCarrierConfigValuesLoader getCarrierConfigValuesLoader() {
243         return mCarrierConfigValuesLoader;
244     }
245 }
246