• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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.util.Log;
21 
22 import com.android.cellbroadcastreceiver.CellBroadcastAlertService.AlertType;
23 
24 import java.util.ArrayList;
25 
26 /**
27  * CellBroadcastChannelManager handles the additional cell broadcast channels that
28  * carriers might enable through resources.
29  * Syntax: "<channel id range>:[type=<alert type>], [emergency=true/false]"
30  * For example,
31  * <string-array name="additional_cbs_channels_strings" translatable="false">
32  *     <item>"43008:type=earthquake, emergency=true"</item>
33  *     <item>"0xAFEE:type=tsunami, emergency=true"</item>
34  *     <item>"0xAC00-0xAFED:type=other"</item>
35  *     <item>"1234-5678"</item>
36  * </string-array>
37  * If no tones are specified, the alert type will be set to CMAS_DEFAULT. If emergency is not set,
38  * by default it's not emergency.
39  */
40 public class CellBroadcastChannelManager {
41 
42     private static final String TAG = "CellBroadcastChannelManager";
43 
44     private static CellBroadcastChannelManager sInstance = null;
45 
46     /**
47      * Cell broadcast channel range
48      * A range is consisted by starting channel id, ending channel id, and the alert type
49      */
50     public static class CellBroadcastChannelRange {
51 
52         private static final String KEY_TYPE = "type";
53         private static final String KEY_EMERGENCY = "emergency";
54 
55         public int mStartId;
56         public int mEndId;
57         public AlertType mAlertType;
58         public boolean mIsEmergency;
59 
CellBroadcastChannelRange(String channelRange)60         public CellBroadcastChannelRange(String channelRange) throws Exception {
61 
62             mAlertType = AlertType.CMAS_DEFAULT;
63             mIsEmergency = false;
64 
65             int colonIndex = channelRange.indexOf(':');
66             if (colonIndex != -1) {
67                 // Parse the alert type and emergency flag
68                 String[] pairs = channelRange.substring(colonIndex + 1).trim().split(",");
69                 for (String pair : pairs) {
70                     pair = pair.trim();
71                     String[] tokens = pair.split("=");
72                     if (tokens.length == 2) {
73                         String key = tokens[0].trim();
74                         String value = tokens[1].trim();
75                         switch (key) {
76                             case KEY_TYPE:
77                                 mAlertType = AlertType.valueOf(value.toUpperCase());
78                                 break;
79                             case KEY_EMERGENCY:
80                                 mIsEmergency = value.equalsIgnoreCase("true");
81                                 break;
82                         }
83                     }
84                 }
85                 channelRange = channelRange.substring(0, colonIndex).trim();
86             }
87 
88             // Parse the channel range
89             int dashIndex = channelRange.indexOf('-');
90             if (dashIndex != -1) {
91                 // range that has start id and end id
92                 mStartId = Integer.decode(channelRange.substring(0, dashIndex).trim());
93                 mEndId = Integer.decode(channelRange.substring(dashIndex + 1).trim());
94             } else {
95                 // Not a range, only a single id
96                 mStartId = mEndId = Integer.decode(channelRange);
97             }
98         }
99     }
100 
101     /**
102      * Get the instance of the cell broadcast other channel manager
103      * @return The singleton instance
104      */
getInstance()105     public static CellBroadcastChannelManager getInstance() {
106         if (sInstance == null) {
107             sInstance = new CellBroadcastChannelManager();
108         }
109         return sInstance;
110     }
111 
112     /**
113      * Get cell broadcast channels enabled by the carriers.
114      * @param context Application context
115      * @return The list of channel ranges enabled by the carriers.
116      */
getCellBroadcastChannelRanges(Context context)117     public ArrayList<CellBroadcastChannelRange> getCellBroadcastChannelRanges(Context context) {
118 
119         ArrayList<CellBroadcastChannelRange> result = new ArrayList<>();
120         String[] ranges = context.getResources().getStringArray(
121                 R.array.additional_cbs_channels_strings);
122 
123         if (ranges != null) {
124             for (String range : ranges) {
125                 try {
126                     result.add(new CellBroadcastChannelRange(range));
127                 } catch (Exception e) {
128                     loge("Failed to parse \"" + range + "\". e=" + e);
129                 }
130             }
131         }
132 
133         return result;
134     }
135 
log(String msg)136     private static void log(String msg) {
137         Log.d(TAG, msg);
138     }
139 
loge(String msg)140     private static void loge(String msg) {
141         Log.e(TAG, msg);
142     }
143 }
144