blob: 0b1062b367444dd53f05a0d40a239f4cb8173f69 [file] [log] [blame]
/*
* Copyright (C) 2016 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.os.PersistableBundle;
import android.telephony.CarrierConfigManager;
import android.util.Log;
import android.util.SparseArray;
import com.android.cellbroadcastreceiver.CellBroadcastAlertAudio.ToneType;
import java.util.ArrayList;
/**
* CellBroadcastOtherChannelsManager handles the additional cell broadcast channels that
* carriers might enable through carrier config app.
* Syntax: "<channel id range>:type=<tone type>"
* For example,
* <string-array name="carrier_additional_cbs_channels_strings" num="3">
* <item value="43008:type=earthquake" />
* <item value="0xAFEE:type=tsunami" />
* <item value="0xAC00-0xAFED:type=other" />
* <item value="1234-5678" />
* </string-array>
* If no tones are specified, the tone type will be set to CMAS_DEFAULT.
*/
public class CellBroadcastOtherChannelsManager {
private static final String TAG = "CellBroadcastChannelsManager";
private static CellBroadcastOtherChannelsManager sInstance = null;
/**
* Channel range caches with sub id as the key.
*/
private static SparseArray<ArrayList<CellBroadcastChannelRange>> sChannelRanges =
new SparseArray<>();
/**
* Cell broadcast channel range
* A range is consisted by starting channel id, ending channel id, and the tone type
*/
public static class CellBroadcastChannelRange {
public int mStartId;
public int mEndId;
public ToneType mToneType;
public CellBroadcastChannelRange(String channelRange) throws Exception {
mToneType = ToneType.CMAS_DEFAULT;
int colonIndex = channelRange.indexOf(':');
if (colonIndex != -1){
// Parse the tone type
String[] tokens = channelRange.substring(colonIndex + 1).trim().split("=");
if (tokens.length == 2 && tokens[0].trim().equalsIgnoreCase("type")) {
mToneType = ToneType.valueOf(tokens[1].trim().toUpperCase());
}
channelRange = channelRange.substring(0, colonIndex).trim();
}
// Parse the channel range
int dashIndex = channelRange.indexOf('-');
if (dashIndex != -1) {
// range that has start id and end id
mStartId = Integer.decode(channelRange.substring(0, dashIndex).trim());
mEndId = Integer.decode(channelRange.substring(dashIndex + 1).trim());
} else {
// Not a range, only a single id
mStartId = mEndId = Integer.decode(channelRange);
}
}
}
/**
* Get the instance of the cell broadcast other channel manager
* @return The singleton instance
*/
public static CellBroadcastOtherChannelsManager getInstance() {
if (sInstance == null) {
sInstance = new CellBroadcastOtherChannelsManager();
}
return sInstance;
}
/**
* Get cell broadcast channels enabled by the carriers.
* @param context Application context
* @param subId Subscription id
* @return The list of channel ranges enabled by the carriers.
*/
public ArrayList<CellBroadcastChannelRange> getCellBroadcastChannelRanges(
Context context, int subId) {
// Check if the cache already had it.
if (sChannelRanges.get(subId) == null) {
ArrayList<CellBroadcastChannelRange> result = new ArrayList<>();
String[] ranges;
CarrierConfigManager configManager =
(CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
if (configManager != null) {
PersistableBundle carrierConfig = configManager.getConfigForSubId(subId);
if (carrierConfig != null) {
ranges = carrierConfig.getStringArray(
CarrierConfigManager.KEY_CARRIER_ADDITIONAL_CBS_CHANNELS_STRINGS);
if (ranges == null || ranges.length == 0) {
log("No additional channels configured.");
// If there is nothing configured, store an empty list in the cache
// so we won't look up again next time.
sChannelRanges.put(subId, result);
return result;
}
for (String range : ranges) {
try {
result.add(new CellBroadcastChannelRange(range));
} catch (Exception e) {
loge("Failed to parse \"" + range + "\". e=" + e);
}
}
sChannelRanges.put(subId, result);
} else {
loge("Can't get carrier config. subId=" + subId);
return null;
}
} else {
loge("Carrier config manager is not available");
return null;
}
}
return sChannelRanges.get(subId);
}
private static void log(String msg) {
Log.d(TAG, msg);
}
private static void loge(String msg) {
Log.e(TAG, msg);
}
}