• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.phone.vvm;
18 
19 import android.content.BroadcastReceiver;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.IntentFilter;
23 import android.os.PersistableBundle;
24 import android.os.UserHandle;
25 import android.telecom.PhoneAccountHandle;
26 import android.telecom.TelecomManager;
27 import android.telephony.CarrierConfigManager;
28 import android.telephony.TelephonyManager;
29 import android.telephony.VisualVoicemailService;
30 import android.text.TextUtils;
31 import android.util.ArraySet;
32 
33 import com.android.internal.telephony.flags.Flags;
34 
35 import java.util.Collections;
36 import java.util.Set;
37 
38 /**
39  * Receives {@link Intent#ACTION_PACKAGE_ADDED} for the system dialer to inform it a carrier visual
40  * voicemail app has been installed. ACTION_PACKAGE_ADDED requires the receiver process to be
41  * running so the system dialer cannot receive it itself.
42  *
43  * Carrier VVM apps are usually regular apps, not a
44  * {@link VisualVoicemailService} nor {@link android.service.carrier.CarrierMessagingService} so it
45  * will not take precedence over the system dialer. The system dialer should disable VVM it self
46  * to let the carrier app take over since the installation is an explicit user interaction. Carrier
47  * customer support might also ask the user to switch to their app if they believe there's any
48  * issue in the system dialer so this transition should not require more user interaction.
49  *
50  * @see CarrierConfigManager#KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY
51  */
52 public class CarrierVvmPackageInstalledReceiver extends BroadcastReceiver {
53 
54     private static final String TAG = "VvmPkgInstalledRcvr";
55 
56     /**
57      * Hidden broadcast to the system dialer
58      */
59     private static final String ACTION_CARRIER_VVM_PACKAGE_INSTALLED =
60             "com.android.internal.telephony.CARRIER_VVM_PACKAGE_INSTALLED";
61 
register(Context context)62     public void register(Context context) {
63         IntentFilter intentFilter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
64         intentFilter.addDataScheme("package");
65         context.registerReceiver(this, intentFilter);
66     }
67 
68     @Override
onReceive(Context context, Intent intent)69     public void onReceive(Context context, Intent intent) {
70         if (intent.getData() == null) {
71             return;
72         }
73         String packageName = intent.getData().getSchemeSpecificPart();
74         if (packageName == null) {
75             return;
76         }
77 
78         TelecomManager telecomManager = context.getSystemService(TelecomManager.class);
79         String systemDialer = telecomManager.getSystemDialerPackage();
80         TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class);
81         for (PhoneAccountHandle phoneAccountHandle : telecomManager.getCallCapablePhoneAccounts()) {
82             TelephonyManager pinnedTelephonyManager = telephonyManager
83                     .createForPhoneAccountHandle(phoneAccountHandle);
84 
85             if (pinnedTelephonyManager == null) {
86                 VvmLog.e(TAG, "carrierVvmPkgAdded: cannot create TelephonyManager from "
87                         + phoneAccountHandle);
88                 continue;
89             }
90 
91             if (!getCarrierVvmPackages(telephonyManager).contains(packageName)) {
92                 VvmLog.w(TAG, "carrierVvmPkgAdded: carrier vvm packages doesn't contain "
93                         + packageName);
94                 continue;
95             }
96 
97             VvmLog.i(TAG, "carrierVvmPkgAdded: Carrier VVM app " + packageName + " installed");
98 
99             String vvmPackage = pinnedTelephonyManager.getVisualVoicemailPackageName();
100             if (!TextUtils.equals(vvmPackage, systemDialer)) {
101                 // Non system dialer do not need to prioritize carrier vvm app.
102                 VvmLog.i(TAG, "carrierVvmPkgAdded: non system dialer "
103                         + vvmPackage + " ignored");
104                 continue;
105             }
106 
107             VvmLog.i(TAG, "carrierVvmPkgAdded: sending vvm package installed broadcast to "
108                     + vvmPackage);
109             Intent broadcast = new Intent(ACTION_CARRIER_VVM_PACKAGE_INSTALLED);
110             broadcast.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
111             broadcast.setPackage(vvmPackage);
112             if (Flags.hsumBroadcast()) {
113                 context.sendBroadcastAsUser(broadcast, UserHandle.ALL);
114             } else {
115                 context.sendBroadcast(broadcast);
116             }
117         }
118     }
119 
getCarrierVvmPackages(TelephonyManager pinnedTelephonyManager)120     private static Set<String> getCarrierVvmPackages(TelephonyManager pinnedTelephonyManager) {
121         Set<String> carrierPackages = new ArraySet<>();
122 
123         PersistableBundle config = pinnedTelephonyManager.getCarrierConfig();
124         String singlePackage = config
125                 .getString(CarrierConfigManager.KEY_CARRIER_VVM_PACKAGE_NAME_STRING);
126         if (!TextUtils.isEmpty(singlePackage)) {
127             carrierPackages.add(singlePackage);
128         }
129         String[] arrayPackages = config
130                 .getStringArray(CarrierConfigManager.KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY);
131         if (arrayPackages != null) {
132             Collections.addAll(carrierPackages, arrayPackages);
133         }
134 
135         return carrierPackages;
136     }
137 }
138