/* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.cellbroadcastreceiver; import android.content.Context; import android.database.Cursor; import android.provider.Telephony; import android.telephony.SmsCbCmasInfo; import android.telephony.SmsCbEtwsInfo; import android.telephony.SmsCbLocation; import android.telephony.SmsCbMessage; import android.telephony.SubscriptionManager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.CheckedTextView; import android.widget.CursorAdapter; import android.widget.ListView; import com.android.internal.annotations.VisibleForTesting; import com.android.modules.utils.build.SdkLevel; /** * The back-end data adapter for {@link CellBroadcastListActivity}. */ public class CellBroadcastCursorAdapter extends CursorAdapter { private boolean mIsActionMode = false; private CheckedTextView mCheckedTextView; private ListView mListView; public CellBroadcastCursorAdapter(Context context, ListView listview) { // don't set FLAG_AUTO_REQUERY or FLAG_REGISTER_CONTENT_OBSERVER super(context, null, 0); mListView = listview; } /** * Makes a new view to hold the data pointed to by cursor. * @param context Interface to application's global information * @param cursor The cursor from which to get the data. The cursor is already * moved to the correct position. * @param parent The parent to which the new view is attached to * @return the newly created view. */ @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { SmsCbMessage message = createFromCursor(context, cursor); LayoutInflater factory = LayoutInflater.from(context); CellBroadcastListItem listItem = (CellBroadcastListItem) factory.inflate( R.layout.cell_broadcast_list_item, parent, false); listItem.bind(message); return listItem; } static SmsCbMessage createFromCursor(Context context, Cursor cursor) { int geoScope = cursor.getInt( cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.GEOGRAPHICAL_SCOPE)); int serialNum = cursor.getInt( cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.SERIAL_NUMBER)); int category = cursor.getInt( cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.SERVICE_CATEGORY)); String language = cursor.getString( cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.LANGUAGE_CODE)); String body = cursor.getString( cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.MESSAGE_BODY)); int format = cursor.getInt( cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.MESSAGE_FORMAT)); int priority = cursor.getInt( cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.MESSAGE_PRIORITY)); int slotIndex = cursor.getInt( cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.SLOT_INDEX)); String plmn; int plmnColumn = cursor.getColumnIndex(Telephony.CellBroadcasts.PLMN); if (plmnColumn != -1 && !cursor.isNull(plmnColumn)) { plmn = cursor.getString(plmnColumn); } else { plmn = null; } int lac; int lacColumn = cursor.getColumnIndex(Telephony.CellBroadcasts.LAC); if (lacColumn != -1 && !cursor.isNull(lacColumn)) { lac = cursor.getInt(lacColumn); } else { lac = -1; } int cid; int cidColumn = cursor.getColumnIndex(Telephony.CellBroadcasts.CID); if (cidColumn != -1 && !cursor.isNull(cidColumn)) { cid = cursor.getInt(cidColumn); } else { cid = -1; } SmsCbLocation location = new SmsCbLocation(plmn, lac, cid); SmsCbEtwsInfo etwsInfo; int etwsWarningTypeColumn = cursor.getColumnIndex( Telephony.CellBroadcasts.ETWS_WARNING_TYPE); if (etwsWarningTypeColumn != -1 && !cursor.isNull(etwsWarningTypeColumn)) { int warningType = cursor.getInt(etwsWarningTypeColumn); etwsInfo = new SmsCbEtwsInfo(warningType, false, false, false, null); } else { etwsInfo = null; } SmsCbCmasInfo cmasInfo; int cmasMessageClassColumn = cursor.getColumnIndex( Telephony.CellBroadcasts.CMAS_MESSAGE_CLASS); if (cmasMessageClassColumn != -1 && !cursor.isNull(cmasMessageClassColumn)) { int messageClass = cursor.getInt(cmasMessageClassColumn); int cmasCategory; int cmasCategoryColumn = cursor.getColumnIndex( Telephony.CellBroadcasts.CMAS_CATEGORY); if (cmasCategoryColumn != -1 && !cursor.isNull(cmasCategoryColumn)) { cmasCategory = cursor.getInt(cmasCategoryColumn); } else { cmasCategory = SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN; } int responseType; int cmasResponseTypeColumn = cursor.getColumnIndex( Telephony.CellBroadcasts.CMAS_RESPONSE_TYPE); if (cmasResponseTypeColumn != -1 && !cursor.isNull(cmasResponseTypeColumn)) { responseType = cursor.getInt(cmasResponseTypeColumn); } else { responseType = SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN; } int severity; int cmasSeverityColumn = cursor.getColumnIndex( Telephony.CellBroadcasts.CMAS_SEVERITY); if (cmasSeverityColumn != -1 && !cursor.isNull(cmasSeverityColumn)) { severity = cursor.getInt(cmasSeverityColumn); } else { severity = SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN; } int urgency; int cmasUrgencyColumn = cursor.getColumnIndex( Telephony.CellBroadcasts.CMAS_URGENCY); if (cmasUrgencyColumn != -1 && !cursor.isNull(cmasUrgencyColumn)) { urgency = cursor.getInt(cmasUrgencyColumn); } else { urgency = SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN; } int certainty; int cmasCertaintyColumn = cursor.getColumnIndex( Telephony.CellBroadcasts.CMAS_CERTAINTY); if (cmasCertaintyColumn != -1 && !cursor.isNull(cmasCertaintyColumn)) { certainty = cursor.getInt(cmasCertaintyColumn); } else { certainty = SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN; } cmasInfo = new SmsCbCmasInfo(messageClass, cmasCategory, responseType, severity, urgency, certainty); } else { cmasInfo = null; } String timeColumn = null; if (cursor.getColumnIndex(Telephony.CellBroadcasts.DELIVERY_TIME) >= 0) { timeColumn = Telephony.CellBroadcasts.DELIVERY_TIME; } else if (cursor.getColumnIndex(Telephony.CellBroadcasts.RECEIVED_TIME) >= 0) { timeColumn = Telephony.CellBroadcasts.RECEIVED_TIME; } long time = cursor.getLong(cursor.getColumnIndexOrThrow(timeColumn)); int dcs = 0; if (cursor.getColumnIndex(Telephony.CellBroadcasts.DATA_CODING_SCHEME) >= 0) { dcs = cursor.getInt(cursor.getColumnIndexOrThrow( Telephony.CellBroadcasts.DATA_CODING_SCHEME)); } int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; if (SdkLevel.isAtLeastU()) { subId = SubscriptionManager.getSubscriptionId(slotIndex); } else { SubscriptionManager sm = context.getSystemService(SubscriptionManager.class); int[] subIds = sm.getSubscriptionIds(slotIndex); if (subIds != null && subIds.length > 0) { subId = subIds[0]; } } if (!SubscriptionManager.isValidSubscriptionId(subId)) { subId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID; } int maximumWaitTimeSec = 0; if (cursor.getColumnIndex(Telephony.CellBroadcasts.MAXIMUM_WAIT_TIME) >= 0) { maximumWaitTimeSec = cursor.getInt(cursor.getColumnIndexOrThrow( Telephony.CellBroadcasts.MAXIMUM_WAIT_TIME)); } return new SmsCbMessage(format, geoScope, serialNum, location, category, language, dcs, body, priority, etwsInfo, cmasInfo, maximumWaitTimeSec, null, time, slotIndex, subId); } /** * Bind an existing view to the data pointed to by cursor * @param view Existing view, returned earlier by newView * @param context Interface to application's global information * @param cursor The cursor from which to get the data. The cursor is already * moved to the correct position. */ @Override public void bindView(View view, Context context, Cursor cursor) { SmsCbMessage message = createFromCursor(context, cursor); CellBroadcastListItem listItem = (CellBroadcastListItem) view; mCheckedTextView = view.findViewById(R.id.checkBox); if (mCheckedTextView != null) { updateCheckTextViewVisibility(); checkIsSelected(cursor.getPosition()); } listItem.bind(message); } public void setIsActionMode(boolean value) { mIsActionMode = value; } @VisibleForTesting public boolean getIsActionMode() { return mIsActionMode; } void updateCheckTextViewVisibility() { if (mIsActionMode) { mCheckedTextView.setVisibility(View.VISIBLE); } else { mCheckedTextView.setVisibility(View.GONE); } } void checkIsSelected(int position) { boolean isChecked = mListView.isItemChecked(position); mCheckedTextView.setChecked(isChecked); } }