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