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.data; 18 19 import android.app.LoaderManager; 20 import android.content.Context; 21 import android.content.Loader; 22 import android.database.Cursor; 23 import android.os.Bundle; 24 import android.text.TextUtils; 25 26 import com.android.messaging.R; 27 import com.android.messaging.datamodel.BoundCursorLoader; 28 import com.android.messaging.datamodel.DatabaseHelper.ParticipantColumns; 29 import com.android.messaging.datamodel.MessagingContentProvider; 30 import com.android.messaging.datamodel.binding.BindableData; 31 import com.android.messaging.datamodel.binding.BindingBase; 32 import com.android.messaging.util.Assert; 33 import com.android.messaging.util.LogUtil; 34 import com.android.messaging.util.OsUtil; 35 36 import java.util.ArrayList; 37 import java.util.List; 38 39 /** 40 * Services SettingsFragment's data needs for loading active self participants to display 41 * the list of active subscriptions. 42 */ 43 public class SettingsData extends BindableData implements 44 LoaderManager.LoaderCallbacks<Cursor> { 45 public interface SettingsDataListener { onSelfParticipantDataLoaded(SettingsData data)46 void onSelfParticipantDataLoaded(SettingsData data); 47 } 48 49 public static class SettingsItem { 50 public static final int TYPE_GENERAL_SETTINGS = 1; 51 public static final int TYPE_PER_SUBSCRIPTION_SETTINGS = 2; 52 53 private final String mDisplayName; 54 private final String mDisplayDetail; 55 private final String mActivityTitle; 56 private final int mType; 57 private final int mSubId; 58 SettingsItem(final String displayName, final String displayDetail, final String activityTitle, final int type, final int subId)59 private SettingsItem(final String displayName, final String displayDetail, 60 final String activityTitle, final int type, final int subId) { 61 mDisplayName = displayName; 62 mDisplayDetail = displayDetail; 63 mActivityTitle = activityTitle; 64 mType = type; 65 mSubId = subId; 66 } 67 getDisplayName()68 public String getDisplayName() { 69 return mDisplayName; 70 } 71 getDisplayDetail()72 public String getDisplayDetail() { 73 return mDisplayDetail; 74 } 75 getType()76 public int getType() { 77 return mType; 78 } 79 getSubId()80 public int getSubId() { 81 return mSubId; 82 } 83 getActivityTitle()84 public String getActivityTitle() { 85 return mActivityTitle; 86 } 87 fromSelfParticipant(final Context context, final ParticipantData self)88 public static SettingsItem fromSelfParticipant(final Context context, 89 final ParticipantData self) { 90 Assert.isTrue(self.isSelf()); 91 Assert.isTrue(self.isActiveSubscription()); 92 final String displayDetail = TextUtils.isEmpty(self.getDisplayDestination()) ? 93 context.getString(R.string.sim_settings_unknown_number) : 94 self.getDisplayDestination(); 95 final String displayName = context.getString(R.string.sim_specific_settings, 96 self.getSubscriptionName()); 97 return new SettingsItem(displayName, displayDetail, displayName, 98 TYPE_PER_SUBSCRIPTION_SETTINGS, self.getSubId()); 99 } 100 createGeneralSettingsItem(final Context context)101 public static SettingsItem createGeneralSettingsItem(final Context context) { 102 return new SettingsItem(context.getString(R.string.general_settings), 103 null, context.getString(R.string.general_settings_activity_title), 104 TYPE_GENERAL_SETTINGS, -1); 105 } 106 createDefaultMmsSettingsItem(final Context context, final int subId)107 public static SettingsItem createDefaultMmsSettingsItem(final Context context, 108 final int subId) { 109 return new SettingsItem(context.getString(R.string.advanced_settings), 110 null, context.getString(R.string.advanced_settings_activity_title), 111 TYPE_PER_SUBSCRIPTION_SETTINGS, subId); 112 } 113 } 114 115 private static final String BINDING_ID = "bindingId"; 116 private final Context mContext; 117 private final SelfParticipantsData mSelfParticipantsData; 118 private LoaderManager mLoaderManager; 119 private SettingsDataListener mListener; 120 SettingsData(final Context context, final SettingsDataListener listener)121 public SettingsData(final Context context, 122 final SettingsDataListener listener) { 123 mListener = listener; 124 mContext = context; 125 mSelfParticipantsData = new SelfParticipantsData(); 126 } 127 128 private static final int SELF_PARTICIPANT_LOADER = 1; 129 130 @Override onCreateLoader(final int id, final Bundle args)131 public Loader<Cursor> onCreateLoader(final int id, final Bundle args) { 132 Assert.equals(SELF_PARTICIPANT_LOADER, id); 133 Loader<Cursor> loader = null; 134 135 final String bindingId = args.getString(BINDING_ID); 136 // Check if data still bound to the requesting ui element 137 if (isBound(bindingId)) { 138 loader = new BoundCursorLoader(bindingId, mContext, 139 MessagingContentProvider.PARTICIPANTS_URI, 140 ParticipantData.ParticipantsQuery.PROJECTION, 141 ParticipantColumns.SUB_ID + " <> ?", 142 new String[] { String.valueOf(ParticipantData.OTHER_THAN_SELF_SUB_ID) }, 143 null); 144 } else { 145 LogUtil.w(LogUtil.BUGLE_TAG, "Creating self loader after unbinding"); 146 } 147 return loader; 148 } 149 150 @Override onLoadFinished(final Loader<Cursor> generic, final Cursor data)151 public void onLoadFinished(final Loader<Cursor> generic, final Cursor data) { 152 final BoundCursorLoader loader = (BoundCursorLoader) generic; 153 154 // Check if data still bound to the requesting ui element 155 if (isBound(loader.getBindingId())) { 156 mSelfParticipantsData.bind(data); 157 mListener.onSelfParticipantDataLoaded(this); 158 } else { 159 LogUtil.w(LogUtil.BUGLE_TAG, "Self loader finished after unbinding"); 160 } 161 } 162 163 @Override onLoaderReset(final Loader<Cursor> generic)164 public void onLoaderReset(final Loader<Cursor> generic) { 165 final BoundCursorLoader loader = (BoundCursorLoader) generic; 166 167 // Check if data still bound to the requesting ui element 168 if (isBound(loader.getBindingId())) { 169 mSelfParticipantsData.bind(null); 170 } else { 171 LogUtil.w(LogUtil.BUGLE_TAG, "Self loader reset after unbinding"); 172 } 173 } 174 init(final LoaderManager loaderManager, final BindingBase<SettingsData> binding)175 public void init(final LoaderManager loaderManager, 176 final BindingBase<SettingsData> binding) { 177 final Bundle args = new Bundle(); 178 args.putString(BINDING_ID, binding.getBindingId()); 179 mLoaderManager = loaderManager; 180 mLoaderManager.initLoader(SELF_PARTICIPANT_LOADER, args, this); 181 } 182 183 @Override unregisterListeners()184 protected void unregisterListeners() { 185 mListener = null; 186 187 // This could be null if we bind but the caller doesn't init the BindableData 188 if (mLoaderManager != null) { 189 mLoaderManager.destroyLoader(SELF_PARTICIPANT_LOADER); 190 mLoaderManager = null; 191 } 192 } 193 getSettingsItems()194 public List<SettingsItem> getSettingsItems() { 195 final List<ParticipantData> selfs = mSelfParticipantsData.getSelfParticipants(true); 196 final List<SettingsItem> settingsItems = new ArrayList<SettingsItem>(); 197 // First goes the general settings, followed by per-subscription settings. 198 settingsItems.add(SettingsItem.createGeneralSettingsItem(mContext)); 199 // For per-subscription settings, show the actual SIM name with phone number if the 200 // platorm is at least L-MR1 and there are multiple active SIMs. 201 final int activeSubCountExcludingDefault = 202 mSelfParticipantsData.getSelfParticipantsCountExcludingDefault(true); 203 if (OsUtil.isAtLeastL_MR1() && activeSubCountExcludingDefault > 0) { 204 for (ParticipantData self : selfs) { 205 if (!self.isDefaultSelf()) { 206 if (activeSubCountExcludingDefault > 1) { 207 settingsItems.add(SettingsItem.fromSelfParticipant(mContext, self)); 208 } else { 209 // This is the only active non-default SIM. 210 settingsItems.add(SettingsItem.createDefaultMmsSettingsItem(mContext, 211 self.getSubId())); 212 break; 213 } 214 } 215 } 216 } else { 217 // Either pre-L-MR1, or there's no active SIM, so show the default MMS settings. 218 settingsItems.add(SettingsItem.createDefaultMmsSettingsItem(mContext, 219 ParticipantData.DEFAULT_SELF_SUB_ID)); 220 } 221 return settingsItems; 222 } 223 } 224