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