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.datamodel; 18 19 import android.content.Context; 20 import android.database.sqlite.SQLiteDatabase; 21 import android.net.Uri; 22 import android.telephony.SubscriptionManager; 23 24 import com.android.messaging.datamodel.action.ActionService; 25 import com.android.messaging.datamodel.action.BackgroundWorker; 26 import com.android.messaging.datamodel.action.FixupMessageStatusOnStartupAction; 27 import com.android.messaging.datamodel.action.ProcessPendingMessagesAction; 28 import com.android.messaging.datamodel.data.BlockedParticipantsData; 29 import com.android.messaging.datamodel.data.BlockedParticipantsData.BlockedParticipantsDataListener; 30 import com.android.messaging.datamodel.data.ContactListItemData; 31 import com.android.messaging.datamodel.data.ContactPickerData; 32 import com.android.messaging.datamodel.data.ContactPickerData.ContactPickerDataListener; 33 import com.android.messaging.datamodel.data.ConversationData; 34 import com.android.messaging.datamodel.data.ConversationData.ConversationDataListener; 35 import com.android.messaging.datamodel.data.ConversationListData; 36 import com.android.messaging.datamodel.data.ConversationListData.ConversationListDataListener; 37 import com.android.messaging.datamodel.data.DraftMessageData; 38 import com.android.messaging.datamodel.data.GalleryGridItemData; 39 import com.android.messaging.datamodel.data.LaunchConversationData; 40 import com.android.messaging.datamodel.data.LaunchConversationData.LaunchConversationDataListener; 41 import com.android.messaging.datamodel.data.MediaPickerData; 42 import com.android.messaging.datamodel.data.MessagePartData; 43 import com.android.messaging.datamodel.data.ParticipantData; 44 import com.android.messaging.datamodel.data.ParticipantListItemData; 45 import com.android.messaging.datamodel.data.PeopleAndOptionsData; 46 import com.android.messaging.datamodel.data.PeopleAndOptionsData.PeopleAndOptionsDataListener; 47 import com.android.messaging.datamodel.data.PeopleOptionsItemData; 48 import com.android.messaging.datamodel.data.SettingsData; 49 import com.android.messaging.datamodel.data.SettingsData.SettingsDataListener; 50 import com.android.messaging.datamodel.data.SubscriptionListData; 51 import com.android.messaging.datamodel.data.VCardContactItemData; 52 import com.android.messaging.sms.MmsConfig; 53 import com.android.messaging.util.Assert; 54 import com.android.messaging.util.Assert.DoesNotRunOnMainThread; 55 import com.android.messaging.util.ConnectivityUtil; 56 import com.android.messaging.util.LogUtil; 57 import com.android.messaging.util.OsUtil; 58 import com.android.messaging.util.PhoneUtils; 59 60 public class DataModelImpl extends DataModel { 61 private final Context mContext; 62 private final ActionService mActionService; 63 private final BackgroundWorker mDataModelWorker; 64 private final DatabaseHelper mDatabaseHelper; 65 private final ConnectivityUtil mConnectivityUtil; 66 private final SyncManager mSyncManager; 67 68 public DataModelImpl(final Context context) { 69 super(); 70 mContext = context; 71 mActionService = new ActionService(); 72 mDataModelWorker = new BackgroundWorker(); 73 mDatabaseHelper = DatabaseHelper.getInstance(context); 74 mConnectivityUtil = new ConnectivityUtil(context); 75 mSyncManager = new SyncManager(); 76 } 77 78 @Override 79 public ConversationListData createConversationListData(final Context context, 80 final ConversationListDataListener listener, final boolean archivedMode) { 81 return new ConversationListData(context, listener, archivedMode); 82 } 83 84 @Override 85 public ConversationData createConversationData(final Context context, 86 final ConversationDataListener listener, final String conversationId) { 87 return new ConversationData(context, listener, conversationId); 88 } 89 90 @Override 91 public ContactListItemData createContactListItemData() { 92 return new ContactListItemData(); 93 } 94 95 @Override 96 public ContactPickerData createContactPickerData(final Context context, 97 final ContactPickerDataListener listener) { 98 return new ContactPickerData(context, listener); 99 } 100 101 @Override 102 public BlockedParticipantsData createBlockedParticipantsData( 103 final Context context, final BlockedParticipantsDataListener listener) { 104 return new BlockedParticipantsData(context, listener); 105 } 106 107 @Override 108 public MediaPickerData createMediaPickerData(final Context context) { 109 return new MediaPickerData(context); 110 } 111 112 @Override 113 public GalleryGridItemData createGalleryGridItemData() { 114 return new GalleryGridItemData(); 115 } 116 117 @Override 118 public LaunchConversationData createLaunchConversationData( 119 final LaunchConversationDataListener listener) { 120 return new LaunchConversationData(listener); 121 } 122 123 @Override 124 public PeopleOptionsItemData createPeopleOptionsItemData(final Context context) { 125 return new PeopleOptionsItemData(context); 126 } 127 128 @Override 129 public PeopleAndOptionsData createPeopleAndOptionsData(final String conversationId, 130 final Context context, final PeopleAndOptionsDataListener listener) { 131 return new PeopleAndOptionsData(conversationId, context, listener); 132 } 133 134 @Override 135 public VCardContactItemData createVCardContactItemData(final Context context, 136 final MessagePartData data) { 137 return new VCardContactItemData(context, data); 138 } 139 140 @Override 141 public VCardContactItemData createVCardContactItemData(final Context context, 142 final Uri vCardUri) { 143 return new VCardContactItemData(context, vCardUri); 144 } 145 146 @Override 147 public ParticipantListItemData createParticipantListItemData( 148 final ParticipantData participant) { 149 return new ParticipantListItemData(participant); 150 } 151 152 @Override 153 public SubscriptionListData createSubscriptonListData(Context context) { 154 return new SubscriptionListData(context); 155 } 156 157 @Override 158 public SettingsData createSettingsData(Context context, SettingsDataListener listener) { 159 return new SettingsData(context, listener); 160 } 161 162 @Override 163 public DraftMessageData createDraftMessageData(String conversationId) { 164 return new DraftMessageData(conversationId); 165 } 166 167 @Override 168 public ActionService getActionService() { 169 // We need to allow access to this on the UI thread since it's used to start actions. 170 return mActionService; 171 } 172 173 @Override 174 public BackgroundWorker getBackgroundWorkerForActionService() { 175 return mDataModelWorker; 176 } 177 178 @Override 179 @DoesNotRunOnMainThread 180 public DatabaseWrapper getDatabase() { 181 // We prevent the main UI thread from accessing the database since we have to allow 182 // public access to this class to enable sub-packages to access data. 183 Assert.isNotMainThread(); 184 return mDatabaseHelper.getDatabase(); 185 } 186 187 @Override 188 public ConnectivityUtil getConnectivityUtil() { 189 return mConnectivityUtil; 190 } 191 192 @Override 193 public SyncManager getSyncManager() { 194 return mSyncManager; 195 } 196 197 @Override 198 void onCreateTables(final SQLiteDatabase db) { 199 LogUtil.w(LogUtil.BUGLE_TAG, "Rebuilt databases: reseting related state"); 200 // Clear other things that implicitly reference the DB 201 SyncManager.resetLastSyncTimestamps(); 202 } 203 204 @Override 205 public void onActivityResume() { 206 // Perform an incremental sync and register for changes if necessary 207 mSyncManager.updateSyncObserver(mContext); 208 209 // Trigger a participant refresh if needed, we should only need to refresh if there is 210 // contact change while the activity was paused. 211 ParticipantRefresh.refreshParticipantsIfNeeded(); 212 } 213 214 @Override 215 public void onApplicationCreated() { 216 FixupMessageStatusOnStartupAction.fixupMessageStatus(); 217 ProcessPendingMessagesAction.processFirstPendingMessage(); 218 SyncManager.immediateSync(); 219 220 if (OsUtil.isAtLeastL_MR1()) { 221 // Start listening for subscription change events for refreshing self participants. 222 PhoneUtils.getDefault().toLMr1().registerOnSubscriptionsChangedListener( 223 new SubscriptionManager.OnSubscriptionsChangedListener() { 224 @Override 225 public void onSubscriptionsChanged() { 226 // TODO: This dynamically changes the mms config that app is 227 // currently using. It may cause inconsistency in some cases. We need 228 // to check the usage of mms config and handle the dynamic change 229 // gracefully 230 MmsConfig.loadAsync(); 231 ParticipantRefresh.refreshSelfParticipants(); 232 } 233 }); 234 } 235 } 236 } 237