Home | History | Annotate | Download | only in telephony
      1 /*
      2  * Copyright (C) 2017 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.internal.telephony;
     18 
     19 import android.app.ActivityManager;
     20 import android.content.BroadcastReceiver;
     21 import android.content.Context;
     22 import android.content.Intent;
     23 import android.content.IntentFilter;
     24 import android.os.UserHandle;
     25 import android.util.Log;
     26 
     27 import java.util.HashMap;
     28 import java.util.Iterator;
     29 import java.util.Map;
     30 
     31 /**
     32  * This class is used to broadcast intents that need to be rebroadcast after the device is unlocked.
     33  * NOTE: Currently this is used only for SIM_STATE_CHANGED so logic is hardcoded for that;
     34  * for example broadcasts are always sticky, only the last intent for the slotId is rebroadcast,
     35  * etc.
     36  */
     37 public class IntentBroadcaster {
     38     private static final String TAG = "IntentBroadcaster";
     39 
     40     private Map<Integer, Intent> mRebroadcastIntents = new HashMap<>();
     41     private static IntentBroadcaster sIntentBroadcaster;
     42 
     43     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
     44         @Override
     45         public void onReceive(Context context, Intent intent) {
     46             String action = intent.getAction();
     47             if (action.equals(Intent.ACTION_USER_UNLOCKED)) {
     48                 synchronized (mRebroadcastIntents) {
     49                     // rebroadcast intents
     50                     Iterator iterator = mRebroadcastIntents.entrySet().iterator();
     51                     while (iterator.hasNext()) {
     52                         Map.Entry pair = (Map.Entry) iterator.next();
     53                         Intent i = (Intent) pair.getValue();
     54                         i.putExtra(TelephonyIntents.EXTRA_REBROADCAST_ON_UNLOCK, true);
     55                         iterator.remove();
     56                         logd("Rebroadcasting intent " + i.getAction() + " "
     57                                 + i.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)
     58                                 + " for slotId " + pair.getKey());
     59                         ActivityManager.broadcastStickyIntent(i, UserHandle.USER_ALL);
     60                     }
     61                 }
     62             }
     63         }
     64     };
     65 
     66     private IntentBroadcaster(Context context) {
     67         context.registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_USER_UNLOCKED));
     68     }
     69 
     70     /**
     71      * Method to get an instance of IntentBroadcaster after creating one if needed.
     72      * @return IntentBroadcaster instance
     73      */
     74     public static IntentBroadcaster getInstance(Context context) {
     75         if (sIntentBroadcaster == null) {
     76             sIntentBroadcaster = new IntentBroadcaster(context);
     77         }
     78         return sIntentBroadcaster;
     79     }
     80 
     81     public static IntentBroadcaster getInstance() {
     82         return sIntentBroadcaster;
     83     }
     84 
     85     /**
     86      * Wrapper for ActivityManager.broadcastStickyIntent() that also stores intent to be rebroadcast
     87      * on USER_UNLOCKED
     88      */
     89     public void broadcastStickyIntent(Intent intent, int slotId) {
     90         logd("Broadcasting and adding intent for rebroadcast: " + intent.getAction() + " "
     91                 + intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)
     92                 + " for slotId " + slotId);
     93         synchronized (mRebroadcastIntents) {
     94             ActivityManager.broadcastStickyIntent(intent, UserHandle.USER_ALL);
     95             mRebroadcastIntents.put(slotId, intent);
     96         }
     97     }
     98 
     99     private void logd(String s) {
    100         Log.d(TAG, s);
    101     }
    102 }
    103