• 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.os.PersistableBundle;
21 import android.telephony.CarrierConfigManager;
22 import android.util.Log;
23 import android.util.SparseArray;
24 
25 import com.android.cellbroadcastreceiver.CellBroadcastAlertAudio.ToneType;
26 
27 import java.util.ArrayList;
28 
29 /**
30  * CellBroadcastOtherChannelsManager handles the additional cell broadcast channels that
31  * carriers might enable through carrier config app.
32  * Syntax: "<channel id range>:type=<tone type>"
33  * For example,
34  * <string-array name="carrier_additional_cbs_channels_strings" num="3">
35  *     <item value="43008:type=earthquake" />
36  *     <item value="0xAFEE:type=tsunami" />
37  *     <item value="0xAC00-0xAFED:type=other" />
38  *     <item value="1234-5678" />
39  * </string-array>
40  * If no tones are specified, the tone type will be set to CMAS_DEFAULT.
41  */
42 public class CellBroadcastOtherChannelsManager {
43 
44     private static final String TAG = "CellBroadcastChannelsManager";
45 
46     private static CellBroadcastOtherChannelsManager sInstance = null;
47 
48     /**
49      * Channel range caches with sub id as the key.
50      */
51     private static SparseArray<ArrayList<CellBroadcastChannelRange>> sChannelRanges =
52             new SparseArray<>();
53 
54     /**
55      * Cell broadcast channel range
56      * A range is consisted by starting channel id, ending channel id, and the tone type
57      */
58     public static class CellBroadcastChannelRange {
59         public int mStartId;
60         public int mEndId;
61         public ToneType mToneType;
62 
CellBroadcastChannelRange(String channelRange)63         public CellBroadcastChannelRange(String channelRange) throws Exception {
64 
65             mToneType = ToneType.CMAS_DEFAULT;
66 
67             int colonIndex = channelRange.indexOf(':');
68             if (colonIndex != -1){
69                 // Parse the tone type
70                 String[] tokens = channelRange.substring(colonIndex + 1).trim().split("=");
71                 if (tokens.length == 2 && tokens[0].trim().equalsIgnoreCase("type")) {
72                     mToneType = ToneType.valueOf(tokens[1].trim().toUpperCase());
73                 }
74                 channelRange = channelRange.substring(0, colonIndex).trim();
75             }
76 
77             // Parse the channel range
78             int dashIndex = channelRange.indexOf('-');
79             if (dashIndex != -1) {
80                 // range that has start id and end id
81                 mStartId = Integer.decode(channelRange.substring(0, dashIndex).trim());
82                 mEndId = Integer.decode(channelRange.substring(dashIndex + 1).trim());
83             } else {
84                 // Not a range, only a single id
85                 mStartId = mEndId = Integer.decode(channelRange);
86             }
87         }
88     }
89 
90     /**
91      * Get the instance of the cell broadcast other channel manager
92      * @return The singleton instance
93      */
getInstance()94     public static CellBroadcastOtherChannelsManager getInstance() {
95         if (sInstance == null) {
96             sInstance = new CellBroadcastOtherChannelsManager();
97         }
98         return sInstance;
99     }
100 
101     /**
102      * Get cell broadcast channels enabled by the carriers.
103      * @param context Application context
104      * @param subId Subscription id
105      * @return The list of channel ranges enabled by the carriers.
106      */
getCellBroadcastChannelRanges( Context context, int subId)107      public ArrayList<CellBroadcastChannelRange> getCellBroadcastChannelRanges(
108             Context context, int subId) {
109 
110         // Check if the cache already had it.
111         if (sChannelRanges.get(subId) == null) {
112 
113             ArrayList<CellBroadcastChannelRange> result = new ArrayList<>();
114             String[] ranges;
115             CarrierConfigManager configManager =
116                     (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
117 
118             if (configManager != null) {
119                 PersistableBundle carrierConfig = configManager.getConfigForSubId(subId);
120 
121                 if (carrierConfig != null) {
122                     ranges = carrierConfig.getStringArray(
123                             CarrierConfigManager.KEY_CARRIER_ADDITIONAL_CBS_CHANNELS_STRINGS);
124 
125                     if (ranges == null || ranges.length == 0) {
126                         log("No additional channels configured.");
127 
128                         // If there is nothing configured, store an empty list in the cache
129                         // so we won't look up again next time.
130                         sChannelRanges.put(subId, result);
131                         return result;
132                     }
133 
134                     for (String range : ranges) {
135                         try {
136                             result.add(new CellBroadcastChannelRange(range));
137                         } catch (Exception e) {
138                             loge("Failed to parse \"" + range + "\". e=" + e);
139                         }
140                     }
141 
142                     sChannelRanges.put(subId, result);
143 
144                 } else {
145                     loge("Can't get carrier config. subId=" + subId);
146                     return null;
147                 }
148             } else {
149                 loge("Carrier config manager is not available");
150                 return null;
151             }
152         }
153 
154         return sChannelRanges.get(subId);
155     }
156 
log(String msg)157     private static void log(String msg) {
158         Log.d(TAG, msg);
159     }
160 
loge(String msg)161     private static void loge(String msg) {
162         Log.e(TAG, msg);
163     }
164 }
165