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.phone.vvm.omtp; 18 19 import android.content.BroadcastReceiver; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.SharedPreferences; 23 import android.preference.PreferenceManager; 24 import android.util.ArraySet; 25 import android.util.Log; 26 27 import com.android.internal.annotations.VisibleForTesting; 28 29 import java.util.Set; 30 31 /** 32 * Stores subscription ID of SIMs while the device is locked to process them after the device is 33 * unlocked. This class is only intended to be used within {@link SimChangeReceiver}. subId is used 34 * for Visual voicemail activation/deactivation, which need to be done when the device is unlocked. 35 * But the enumeration of subIds happen on boot, when the device could be locked. This class is used 36 * to defer all activation/deactivation until the device is unlocked. 37 * 38 * The subIds are stored in device encrypted {@link SharedPreferences} (readable/writable even 39 * locked). after the device is unlocked the list is read and deleted. 40 */ 41 public class OmtpBootCompletedReceiver extends BroadcastReceiver { 42 43 private static final String TAG = "OmtpBootCompletedRcvr"; 44 45 private static final String DEFERRED_SUBID_LIST_KEY = "deferred_sub_id_key"; 46 47 @VisibleForTesting 48 interface SubIdProcessor{ 49 void process(Context context,int subId); 50 } 51 52 private SubIdProcessor mSubIdProcessor = new SubIdProcessor() { 53 @Override 54 public void process(Context context, int subId) { 55 SimChangeReceiver.processSubId(context,subId); 56 } 57 }; 58 59 /** 60 * Write the subId to the the list. 61 */ 62 public static void addDeferredSubId(Context context, int subId) { 63 SharedPreferences sharedPreferences = getSubIdSharedPreference(context); 64 Set<String> subIds = 65 new ArraySet<>(sharedPreferences.getStringSet(DEFERRED_SUBID_LIST_KEY, null)); 66 subIds.add(String.valueOf(subId)); 67 sharedPreferences.edit().putStringSet(DEFERRED_SUBID_LIST_KEY, subIds).apply(); 68 } 69 70 @Override 71 public void onReceive(Context context, Intent intent) { 72 // Listens to android.intent.action.BOOT_COMPLETED 73 if(!intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) { 74 return; 75 } 76 77 Log.v(TAG, "processing deferred subId list"); 78 Set<Integer> subIds = readAndDeleteSubIds(context); 79 for (Integer subId : subIds) { 80 Log.v(TAG, "processing subId " + subId); 81 mSubIdProcessor.process(context, subId); 82 } 83 } 84 85 /** 86 * Read all subId from the list to a unique integer set, and delete the preference. 87 */ 88 private static Set<Integer> readAndDeleteSubIds(Context context) { 89 SharedPreferences sharedPreferences = getSubIdSharedPreference(context); 90 Set<String> subIdStrings = sharedPreferences.getStringSet(DEFERRED_SUBID_LIST_KEY, null); 91 Set<Integer> subIds = new ArraySet<>(); 92 if(subIdStrings == null) { 93 return subIds; 94 } 95 for(String string : subIdStrings){ 96 subIds.add(Integer.valueOf(string)); 97 } 98 getSubIdSharedPreference(context).edit().remove(DEFERRED_SUBID_LIST_KEY).apply(); 99 return subIds; 100 } 101 102 @VisibleForTesting 103 void setSubIdProcessorForTest(SubIdProcessor processor){ 104 mSubIdProcessor = processor; 105 } 106 107 private static SharedPreferences getSubIdSharedPreference(Context context) { 108 return PreferenceManager 109 .getDefaultSharedPreferences(context.createDeviceProtectedStorageContext()); 110 } 111 } 112