1 /* 2 * Copyright (C) 2011 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.cellbroadcastreceiver; 18 19 import android.content.Context; 20 import android.database.Cursor; 21 import android.provider.Telephony; 22 import android.telephony.SmsCbCmasInfo; 23 import android.telephony.SmsCbEtwsInfo; 24 import android.telephony.SmsCbLocation; 25 import android.telephony.SmsCbMessage; 26 import android.telephony.SubscriptionManager; 27 import android.util.ArrayMap; 28 import android.view.LayoutInflater; 29 import android.view.View; 30 import android.view.ViewGroup; 31 import android.widget.CheckedTextView; 32 import android.widget.CursorAdapter; 33 34 /** 35 * The back-end data adapter for {@link CellBroadcastListActivity}. 36 */ 37 public class CellBroadcastCursorAdapter extends CursorAdapter { 38 39 private static boolean sIsActionMode = false; 40 private CheckedTextView mCheckedTextView; 41 private ArrayMap<Integer, Long> mSelectedMessages; 42 CellBroadcastCursorAdapter(Context context, ArrayMap<Integer, Long> selectedMessages)43 public CellBroadcastCursorAdapter(Context context, ArrayMap<Integer, Long> selectedMessages) { 44 // don't set FLAG_AUTO_REQUERY or FLAG_REGISTER_CONTENT_OBSERVER 45 super(context, null, 0); 46 mSelectedMessages = selectedMessages; 47 } 48 49 /** 50 * Makes a new view to hold the data pointed to by cursor. 51 * @param context Interface to application's global information 52 * @param cursor The cursor from which to get the data. The cursor is already 53 * moved to the correct position. 54 * @param parent The parent to which the new view is attached to 55 * @return the newly created view. 56 */ 57 @Override newView(Context context, Cursor cursor, ViewGroup parent)58 public View newView(Context context, Cursor cursor, ViewGroup parent) { 59 SmsCbMessage message = createFromCursor(context, cursor); 60 61 LayoutInflater factory = LayoutInflater.from(context); 62 CellBroadcastListItem listItem = (CellBroadcastListItem) factory.inflate( 63 R.layout.cell_broadcast_list_item, parent, false); 64 65 listItem.bind(message); 66 return listItem; 67 } 68 createFromCursor(Context context, Cursor cursor)69 static SmsCbMessage createFromCursor(Context context, Cursor cursor) { 70 int geoScope = cursor.getInt( 71 cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.GEOGRAPHICAL_SCOPE)); 72 int serialNum = cursor.getInt( 73 cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.SERIAL_NUMBER)); 74 int category = cursor.getInt( 75 cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.SERVICE_CATEGORY)); 76 String language = cursor.getString( 77 cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.LANGUAGE_CODE)); 78 String body = cursor.getString( 79 cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.MESSAGE_BODY)); 80 int format = cursor.getInt( 81 cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.MESSAGE_FORMAT)); 82 int priority = cursor.getInt( 83 cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.MESSAGE_PRIORITY)); 84 int slotIndex = cursor.getInt( 85 cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.SLOT_INDEX)); 86 87 String plmn; 88 int plmnColumn = cursor.getColumnIndex(Telephony.CellBroadcasts.PLMN); 89 if (plmnColumn != -1 && !cursor.isNull(plmnColumn)) { 90 plmn = cursor.getString(plmnColumn); 91 } else { 92 plmn = null; 93 } 94 95 int lac; 96 int lacColumn = cursor.getColumnIndex(Telephony.CellBroadcasts.LAC); 97 if (lacColumn != -1 && !cursor.isNull(lacColumn)) { 98 lac = cursor.getInt(lacColumn); 99 } else { 100 lac = -1; 101 } 102 103 int cid; 104 int cidColumn = cursor.getColumnIndex(Telephony.CellBroadcasts.CID); 105 if (cidColumn != -1 && !cursor.isNull(cidColumn)) { 106 cid = cursor.getInt(cidColumn); 107 } else { 108 cid = -1; 109 } 110 111 SmsCbLocation location = new SmsCbLocation(plmn, lac, cid); 112 113 SmsCbEtwsInfo etwsInfo; 114 int etwsWarningTypeColumn = cursor.getColumnIndex( 115 Telephony.CellBroadcasts.ETWS_WARNING_TYPE); 116 if (etwsWarningTypeColumn != -1 && !cursor.isNull(etwsWarningTypeColumn)) { 117 int warningType = cursor.getInt(etwsWarningTypeColumn); 118 etwsInfo = new SmsCbEtwsInfo(warningType, false, false, false, null); 119 } else { 120 etwsInfo = null; 121 } 122 123 SmsCbCmasInfo cmasInfo; 124 int cmasMessageClassColumn = cursor.getColumnIndex( 125 Telephony.CellBroadcasts.CMAS_MESSAGE_CLASS); 126 if (cmasMessageClassColumn != -1 && !cursor.isNull(cmasMessageClassColumn)) { 127 int messageClass = cursor.getInt(cmasMessageClassColumn); 128 129 int cmasCategory; 130 int cmasCategoryColumn = cursor.getColumnIndex( 131 Telephony.CellBroadcasts.CMAS_CATEGORY); 132 if (cmasCategoryColumn != -1 && !cursor.isNull(cmasCategoryColumn)) { 133 cmasCategory = cursor.getInt(cmasCategoryColumn); 134 } else { 135 cmasCategory = SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN; 136 } 137 138 int responseType; 139 int cmasResponseTypeColumn = cursor.getColumnIndex( 140 Telephony.CellBroadcasts.CMAS_RESPONSE_TYPE); 141 if (cmasResponseTypeColumn != -1 && !cursor.isNull(cmasResponseTypeColumn)) { 142 responseType = cursor.getInt(cmasResponseTypeColumn); 143 } else { 144 responseType = SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN; 145 } 146 147 int severity; 148 int cmasSeverityColumn = cursor.getColumnIndex( 149 Telephony.CellBroadcasts.CMAS_SEVERITY); 150 if (cmasSeverityColumn != -1 && !cursor.isNull(cmasSeverityColumn)) { 151 severity = cursor.getInt(cmasSeverityColumn); 152 } else { 153 severity = SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN; 154 } 155 156 int urgency; 157 int cmasUrgencyColumn = cursor.getColumnIndex( 158 Telephony.CellBroadcasts.CMAS_URGENCY); 159 if (cmasUrgencyColumn != -1 && !cursor.isNull(cmasUrgencyColumn)) { 160 urgency = cursor.getInt(cmasUrgencyColumn); 161 } else { 162 urgency = SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN; 163 } 164 165 int certainty; 166 int cmasCertaintyColumn = cursor.getColumnIndex( 167 Telephony.CellBroadcasts.CMAS_CERTAINTY); 168 if (cmasCertaintyColumn != -1 && !cursor.isNull(cmasCertaintyColumn)) { 169 certainty = cursor.getInt(cmasCertaintyColumn); 170 } else { 171 certainty = SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN; 172 } 173 174 cmasInfo = new SmsCbCmasInfo(messageClass, cmasCategory, responseType, severity, 175 urgency, certainty); 176 } else { 177 cmasInfo = null; 178 } 179 180 String timeColumn = null; 181 if (cursor.getColumnIndex(Telephony.CellBroadcasts.DELIVERY_TIME) >= 0) { 182 timeColumn = Telephony.CellBroadcasts.DELIVERY_TIME; 183 } else if (cursor.getColumnIndex(Telephony.CellBroadcasts.RECEIVED_TIME) >= 0) { 184 timeColumn = Telephony.CellBroadcasts.RECEIVED_TIME; 185 } 186 187 long time = cursor.getLong(cursor.getColumnIndexOrThrow(timeColumn)); 188 189 int dcs = 0; 190 if (cursor.getColumnIndex(Telephony.CellBroadcasts.DATA_CODING_SCHEME) >= 0) { 191 dcs = cursor.getInt(cursor.getColumnIndexOrThrow( 192 Telephony.CellBroadcasts.DATA_CODING_SCHEME)); 193 } 194 195 SubscriptionManager sm = (SubscriptionManager) context.getSystemService( 196 Context.TELEPHONY_SUBSCRIPTION_SERVICE); 197 int subId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID; 198 int[] subIds = sm.getSubscriptionIds(slotIndex); 199 if (subIds != null && subIds.length > 0) { 200 subId = subIds[0]; 201 } 202 203 int maximumWaitTimeSec = 0; 204 if (cursor.getColumnIndex(Telephony.CellBroadcasts.MAXIMUM_WAIT_TIME) >= 0) { 205 maximumWaitTimeSec = cursor.getInt(cursor.getColumnIndexOrThrow( 206 Telephony.CellBroadcasts.MAXIMUM_WAIT_TIME)); 207 } 208 209 return new SmsCbMessage(format, geoScope, serialNum, location, category, language, dcs, 210 body, priority, etwsInfo, cmasInfo, maximumWaitTimeSec, null, time, 211 slotIndex, subId); 212 } 213 214 /** 215 * Bind an existing view to the data pointed to by cursor 216 * @param view Existing view, returned earlier by newView 217 * @param context Interface to application's global information 218 * @param cursor The cursor from which to get the data. The cursor is already 219 * moved to the correct position. 220 */ 221 @Override bindView(View view, Context context, Cursor cursor)222 public void bindView(View view, Context context, Cursor cursor) { 223 SmsCbMessage message = createFromCursor(context, cursor); 224 CellBroadcastListItem listItem = (CellBroadcastListItem) view; 225 mCheckedTextView = view.findViewById(R.id.checkBox); 226 updateCheckTextViewVisibility(); 227 checkIsSelected(cursor.getPosition()); 228 listItem.bind(message); 229 } 230 setIsActionMode(boolean value)231 static void setIsActionMode(boolean value) { 232 sIsActionMode = value; 233 } 234 updateCheckTextViewVisibility()235 void updateCheckTextViewVisibility() { 236 if (sIsActionMode) { 237 mCheckedTextView.setVisibility(View.VISIBLE); 238 } else { 239 mCheckedTextView.setVisibility(View.GONE); 240 } 241 } 242 checkIsSelected(int position)243 void checkIsSelected(int position) { 244 if (mSelectedMessages.containsKey(position)) { 245 mCheckedTextView.setChecked(true); 246 } else { 247 mCheckedTextView.setChecked(false); 248 } 249 } 250 } 251