14c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu/* 24c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu * Copyright (C) 2016 The Android Open Source Project 34c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu * 44c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu * Licensed under the Apache License, Version 2.0 (the "License"); 54c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu * you may not use this file except in compliance with the License. 64c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu * You may obtain a copy of the License at 74c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu * 84c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu * http://www.apache.org/licenses/LICENSE-2.0 94c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu * 104c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu * Unless required by applicable law or agreed to in writing, software 114c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu * distributed under the License is distributed on an "AS IS" BASIS, 124c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu * See the License for the specific language governing permissions and 144c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu * limitations under the License. 154c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu */ 164c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxupackage com.android.internal.telephony; 174c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu 184c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport android.content.ActivityNotFoundException; 196a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxuimport android.content.BroadcastReceiver; 204c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport android.content.ComponentName; 214c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport android.content.Context; 224c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport android.content.Intent; 236a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxuimport android.content.IntentFilter; 244c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport android.content.pm.PackageManager; 254c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport android.os.PersistableBundle; 264c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport android.telephony.CarrierConfigManager; 274c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport android.telephony.Rlog; 286a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxuimport android.text.TextUtils; 296a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxuimport android.util.LocalLog; 306a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxuimport android.util.Log; 314c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu 324c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport com.android.internal.util.ArrayUtils; 336a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxuimport com.android.internal.util.IndentingPrintWriter; 344c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu 356a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxuimport java.io.FileDescriptor; 366a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxuimport java.io.PrintWriter; 376a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxuimport java.util.ArrayList; 386a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxuimport java.util.Arrays; 394c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport java.util.HashMap; 406a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxuimport java.util.HashSet; 416a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxuimport java.util.List; 424c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxuimport java.util.Map; 436a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxuimport java.util.Set; 446a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu 456a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxuimport static android.telephony.CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY; 466a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxuimport static android.telephony.CarrierConfigManager.KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY; 474c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu 484c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu/** 494c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu * This class act as an CarrierSignalling Agent. 506a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * it load registered carrier signalling receivers from carrier config, cache the result to avoid 514c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu * repeated polling and send the intent to the interested receivers. 526a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * Each CarrierSignalAgent is associated with a phone object. 534c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu */ 544c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxupublic class CarrierSignalAgent { 554c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu 566a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu private static final String LOG_TAG = CarrierSignalAgent.class.getSimpleName(); 574c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu private static final boolean DBG = true; 586a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu private static final boolean VDBG = Rlog.isLoggable(LOG_TAG, Log.VERBOSE); 596a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu private static final boolean WAKE = true; 606a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu private static final boolean NO_WAKE = false; 616a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu 626a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu /** delimiters for parsing config of the form: pakName./receiverName : signal1, signal2,..*/ 636a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu private static final String COMPONENT_NAME_DELIMITER = "\\s*:\\s*"; 646a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu private static final String CARRIER_SIGNAL_DELIMITER = "\\s*,\\s*"; 654c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu 664c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu /** Member variables */ 674c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu private final Phone mPhone; 686a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu 694c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu /** 706a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * This is a map of intent action -> array list of component name of statically registered 716a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * carrier signal receivers(wakeup receivers). 726a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * Those intents are declared in the Manifest files, aiming to wakeup broadcast receivers. 736a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * Carrier apps should be careful when configuring the wake signal list to avoid unnecessary 746a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * wakeup. 756a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * @see CarrierConfigManager#KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY 764c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu */ 776a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu private final Map<String, List<ComponentName>> mCachedWakeSignalConfigs = new HashMap<>(); 786a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu 794c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu /** 806a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * This is a map of intent action -> array list of component name of dynamically registered 816a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * carrier signal receivers(non-wakeup receivers). Those intents will not wake up the apps. 826a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * Note Carrier apps should avoid configuring no wake signals in there Manifest files. 836a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * @see CarrierConfigManager#KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY 844c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu */ 856a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu private final Map<String, List<ComponentName>> mCachedNoWakeSignalConfigs = new HashMap<>(); 866a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu 876a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu /** 886a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * This is a list of supported signals from CarrierSignalAgent 896a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu */ 906a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu private final Set<String> mCarrierSignalList = new HashSet<>(Arrays.asList( 914c9ca958d2ecb645d643d08c65f931e255138d71fionaxu TelephonyIntents.ACTION_CARRIER_SIGNAL_PCO_VALUE, 924c9ca958d2ecb645d643d08c65f931e255138d71fionaxu TelephonyIntents.ACTION_CARRIER_SIGNAL_REDIRECTED, 934c9ca958d2ecb645d643d08c65f931e255138d71fionaxu TelephonyIntents.ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED, 944c9ca958d2ecb645d643d08c65f931e255138d71fionaxu TelephonyIntents.ACTION_CARRIER_SIGNAL_RESET)); 956a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu 966a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu private final LocalLog mErrorLocalLog = new LocalLog(20); 976a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu 986a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 996a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu public void onReceive(Context context, Intent intent) { 1006a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu String action = intent.getAction(); 1016a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu if (DBG) log("CarrierSignalAgent receiver action: " + action); 1026a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu if (action.equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) { 1034c9ca958d2ecb645d643d08c65f931e255138d71fionaxu // notify carrier apps before cache get purged 104d2569726c9c5a93c852ec6ddd5ca80c760845061fionaxu if (mPhone.getIccCard() != null 105d2569726c9c5a93c852ec6ddd5ca80c760845061fionaxu && IccCardConstants.State.ABSENT == mPhone.getIccCard().getState()) { 1064c9ca958d2ecb645d643d08c65f931e255138d71fionaxu notifyCarrierSignalReceivers( 1074c9ca958d2ecb645d643d08c65f931e255138d71fionaxu new Intent(TelephonyIntents.ACTION_CARRIER_SIGNAL_RESET)); 1084c9ca958d2ecb645d643d08c65f931e255138d71fionaxu } 1096a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu loadCarrierConfig(); 1106a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu } 1116a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu } 1126a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu }; 1134c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu 1144c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu /** Constructor */ 1154c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu public CarrierSignalAgent(Phone phone) { 1164c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu mPhone = phone; 1176a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu loadCarrierConfig(); 1186a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu // reload configurations on CARRIER_CONFIG_CHANGED 1196a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu mPhone.getContext().registerReceiver(mReceiver, 1206a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)); 1214c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu } 1224c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu 1234c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu /** 1246a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * load carrier config and cached the results into a hashMap action -> array list of components. 1254c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu */ 1266a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu private void loadCarrierConfig() { 1276a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu CarrierConfigManager configManager = (CarrierConfigManager) mPhone.getContext() 1286a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu .getSystemService(Context.CARRIER_CONFIG_SERVICE); 1296a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu PersistableBundle b = null; 1306a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu if (configManager != null) { 1316a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu b = configManager.getConfig(); 1324c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu } 1336a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu if (b != null) { 1346a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu synchronized (mCachedWakeSignalConfigs) { 1356a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu mCachedWakeSignalConfigs.clear(); 1366a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu log("Loading carrier config: " + KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY); 1376a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu parseAndCache(b.getStringArray(KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY), 1386a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu mCachedWakeSignalConfigs); 1394c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu } 1406a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu 1416a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu synchronized (mCachedNoWakeSignalConfigs) { 1426a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu mCachedNoWakeSignalConfigs.clear(); 1436a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu log("Loading carrier config: " 1446a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu + KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY); 1456a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu parseAndCache(b.getStringArray(KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY), 1466a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu mCachedNoWakeSignalConfigs); 1474c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu } 1484c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu } 1494c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu } 1504c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu 1514c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu /** 1526a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * Parse each config with the form {pakName./receiverName : signal1, signal2,.} and cached the 1536a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * result internally to avoid repeated polling 1546a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * @see #CARRIER_SIGNAL_DELIMITER 1556a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * @see #COMPONENT_NAME_DELIMITER 1566a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * @param configs raw information from carrier config 1574c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu */ 1586a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu private void parseAndCache(String[] configs, 1596a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu Map<String, List<ComponentName>> cachedConfigs) { 1606a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu if (!ArrayUtils.isEmpty(configs)) { 1616a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu for (String config : configs) { 1626a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu if (!TextUtils.isEmpty(config)) { 1636a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu String[] splitStr = config.trim().split(COMPONENT_NAME_DELIMITER, 2); 1646a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu if (splitStr.length == 2) { 1656a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu ComponentName componentName = ComponentName 1666a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu .unflattenFromString(splitStr[0]); 1676a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu if (componentName == null) { 1686a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu loge("Invalid component name: " + splitStr[0]); 1696a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu continue; 1706a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu } 1716a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu String[] signals = splitStr[1].split(CARRIER_SIGNAL_DELIMITER); 1726a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu for (String s : signals) { 1736a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu if (!mCarrierSignalList.contains(s)) { 1746a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu loge("Invalid signal name: " + s); 1756a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu continue; 1766a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu } 1776a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu List<ComponentName> componentList = cachedConfigs.get(s); 1786a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu if (componentList == null) { 1796a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu componentList = new ArrayList<>(); 1806a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu cachedConfigs.put(s, componentList); 1816a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu } 1826a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu componentList.add(componentName); 1836a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu if (VDBG) { 1846a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu logv("Add config " + "{signal: " + s 1856a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu + " componentName: " + componentName + "}"); 1866a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu } 1876a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu } 1886a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu } else { 1896a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu loge("invalid config format: " + config); 1906a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu } 1916a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu } 1924c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu } 1934c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu } 1944c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu } 1954c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu 1966a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu /** 1976a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * Check if there are registered carrier broadcast receivers to handle the passing intent 1986a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu */ 1996a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu public boolean hasRegisteredReceivers(String action) { 2004c9ca958d2ecb645d643d08c65f931e255138d71fionaxu return mCachedWakeSignalConfigs.containsKey(action) 2014c9ca958d2ecb645d643d08c65f931e255138d71fionaxu || mCachedNoWakeSignalConfigs.containsKey(action); 2026a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu } 2036a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu 2046a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu /** 2056a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * Broadcast the intents explicitly. 2066a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * Some sanity check will be applied before broadcasting. 2076a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * - for non-wakeup(runtime) receivers, make sure the intent is not declared in their manifests 2086a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * and apply FLAG_EXCLUDE_STOPPED_PACKAGES to avoid wake-up 2096a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * - for wakeup(manifest) receivers, make sure there are matched receivers with registered 2106a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * intents. 2116a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * 2126a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * @param intent intent which signals carrier apps 2136a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * @param receivers a list of component name for broadcast receivers. 2146a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * Those receivers could either be statically declared in Manifest or 2156a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * registered during run-time. 2166a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * @param wakeup true indicate wakeup receivers otherwise non-wakeup receivers 2176a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu */ 2186a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu private void broadcast(Intent intent, List<ComponentName> receivers, boolean wakeup) { 2194c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu final PackageManager packageManager = mPhone.getContext().getPackageManager(); 2206a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu for (ComponentName name : receivers) { 2216a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu Intent signal = new Intent(intent); 2226a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu signal.setComponent(name); 2234c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu 2246a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu if (wakeup && packageManager.queryBroadcastReceivers(signal, 2256a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 2266a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu loge("Carrier signal receivers are configured but unavailable: " 2276a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu + signal.getComponent()); 2286a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu return; 2294c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu } 2306a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu if (!wakeup && !packageManager.queryBroadcastReceivers(signal, 2314c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 2326a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu loge("Runtime signals shouldn't be configured in Manifest: " 2336a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu + signal.getComponent()); 2346a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu return; 2354c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu } 2364c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu 2376a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu signal.putExtra(PhoneConstants.SUBSCRIPTION_KEY, mPhone.getSubId()); 2386a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu signal.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 2396a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu if (!wakeup) signal.setFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 2404c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu 2414c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu try { 2426a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu mPhone.getContext().sendBroadcast(signal); 2436a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu if (DBG) { 2446a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu log("Sending signal " + signal.getAction() + ((signal.getComponent() != null) 2456a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu ? " to the carrier signal receiver: " + signal.getComponent() : "")); 2466a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu } 2474c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu } catch (ActivityNotFoundException e) { 2486a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu loge("Send broadcast failed: " + e); 2494c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu } 2504c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu } 2514c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu } 2524c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu 2536a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu /** 2546a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * Match the intent against cached tables to find a list of registered carrier signal 2556a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * receivers and broadcast the intent. 2566a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * @param intent broadcasting intent, it could belong to wakeup, non-wakeup signal list or both 2576a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu * 2586a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu */ 2596a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu public void notifyCarrierSignalReceivers(Intent intent) { 2606a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu List<ComponentName> receiverList; 2616a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu 2626a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu synchronized (mCachedWakeSignalConfigs) { 2634c9ca958d2ecb645d643d08c65f931e255138d71fionaxu receiverList = mCachedWakeSignalConfigs.get(intent.getAction()); 2646a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu if (!ArrayUtils.isEmpty(receiverList)) { 2656a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu broadcast(intent, receiverList, WAKE); 2666a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu } 2676a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu } 2686a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu 2696a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu synchronized (mCachedNoWakeSignalConfigs) { 2704c9ca958d2ecb645d643d08c65f931e255138d71fionaxu receiverList = mCachedNoWakeSignalConfigs.get(intent.getAction()); 2716a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu if (!ArrayUtils.isEmpty(receiverList)) { 2726a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu broadcast(intent, receiverList, NO_WAKE); 2736a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu } 2746a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu } 2754c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu } 2764c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu 2774c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu private void log(String s) { 2784c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu Rlog.d(LOG_TAG, "[" + mPhone.getPhoneId() + "]" + s); 2794c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu } 2804c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu 2814c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu private void loge(String s) { 2826a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu mErrorLocalLog.log(s); 2834c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu Rlog.e(LOG_TAG, "[" + mPhone.getPhoneId() + "]" + s); 2844c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu } 2856a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu 2866a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu private void logv(String s) { 2876a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu Rlog.v(LOG_TAG, "[" + mPhone.getPhoneId() + "]" + s); 2886a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu } 2896a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu 2906a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2916a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); 2926a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu pw.println("mCachedWakeSignalConfigs:"); 2936a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu ipw.increaseIndent(); 2946a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu for (Map.Entry<String, List<ComponentName>> entry : mCachedWakeSignalConfigs.entrySet()) { 2956a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu pw.println("signal: " + entry.getKey() + " componentName list: " + entry.getValue()); 2966a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu } 2976a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu ipw.decreaseIndent(); 2986a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu 2996a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu pw.println("mCachedNoWakeSignalConfigs:"); 3006a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu ipw.increaseIndent(); 3016a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu for (Map.Entry<String, List<ComponentName>> entry : mCachedNoWakeSignalConfigs.entrySet()) { 3026a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu pw.println("signal: " + entry.getKey() + " componentName list: " + entry.getValue()); 3036a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu } 3046a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu ipw.decreaseIndent(); 3056a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu 3066a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu pw.println("error log:"); 3076a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu ipw.increaseIndent(); 3086a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu mErrorLocalLog.dump(fd, pw, args); 3096a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu ipw.decreaseIndent(); 3106a7fb078d1cacba7cf2e83b71242bb5c4c27c975fionaxu } 3114c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu} 312