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.voicemail.impl;
18 
19 import android.content.BroadcastReceiver;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.SharedPreferences;
23 import android.database.Cursor;
24 import android.net.Uri;
25 import android.preference.PreferenceManager;
26 import android.provider.CallLog.Calls;
27 import android.provider.VoicemailContract.Voicemails;
28 import android.telecom.PhoneAccountHandle;
29 import android.telecom.TelecomManager;
30 import com.android.dialer.common.LogUtil;
31 import com.android.dialer.common.concurrent.DialerExecutor.Worker;
32 import com.android.dialer.common.concurrent.DialerExecutorComponent;
33 import com.android.voicemail.VoicemailComponent;
34 import com.android.voicemail.VoicemailVersionConstants;
35 
36 /**
37  * Receives MY_PACKAGE_REPLACED to trigger VVM activation and to check for legacy voicemail users.
38  */
39 public class PackageReplacedReceiver extends BroadcastReceiver {
40 
41   @Override
onReceive(Context context, Intent intent)42   public void onReceive(Context context, Intent intent) {
43     VvmLog.i("PackageReplacedReceiver.onReceive", "package replaced, starting activation");
44 
45     if (!VoicemailComponent.get(context).getVoicemailClient().isVoicemailModuleEnabled()) {
46       VvmLog.e("PackageReplacedReceiver.onReceive", "module disabled");
47       return;
48     }
49 
50     for (PhoneAccountHandle phoneAccountHandle :
51         context.getSystemService(TelecomManager.class).getCallCapablePhoneAccounts()) {
52       ActivationTask.start(context, phoneAccountHandle, null);
53     }
54 
55     SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
56     if (!prefs.contains(VoicemailVersionConstants.PREF_DIALER_FEATURE_VERSION_ACKNOWLEDGED_KEY)) {
57       setVoicemailFeatureVersionAsync(context);
58     }
59   }
60 
setVoicemailFeatureVersionAsync(Context context)61   private void setVoicemailFeatureVersionAsync(Context context) {
62     LogUtil.enterBlock("PackageReplacedReceiver.setVoicemailFeatureVersionAsync");
63 
64     // Check if user is already using voicemail (ie do they have any voicemails), and set the
65     // acknowledged feature value accordingly.
66     PendingResult pendingResult = goAsync();
67     DialerExecutorComponent.get(context)
68         .dialerExecutorFactory()
69         .createNonUiTaskBuilder(new ExistingVoicemailCheck(context))
70         .onSuccess(
71             output -> {
72               LogUtil.i("PackageReplacedReceiver.setVoicemailFeatureVersionAsync", "success");
73               pendingResult.finish();
74             })
75         .onFailure(
76             throwable -> {
77               LogUtil.i("PackageReplacedReceiver.setVoicemailFeatureVersionAsync", "failure");
78               pendingResult.finish();
79             })
80         .build()
81         .executeParallel(null);
82   }
83 
84   private static class ExistingVoicemailCheck implements Worker<Void, Void> {
85     private static final String[] PROJECTION = new String[] {Voicemails._ID};
86 
87     private final Context context;
88 
ExistingVoicemailCheck(Context context)89     ExistingVoicemailCheck(Context context) {
90       this.context = context;
91     }
92 
93     @Override
doInBackground(Void arg)94     public Void doInBackground(Void arg) throws Throwable {
95       LogUtil.i("PackageReplacedReceiver.ExistingVoicemailCheck.doInBackground", "");
96 
97       // Check the database for existing voicemails.
98       boolean hasVoicemails = false;
99       Uri uri = Voicemails.buildSourceUri(context.getPackageName());
100       String whereClause = Calls.TYPE + " = " + Calls.VOICEMAIL_TYPE;
101       try (Cursor cursor =
102           context.getContentResolver().query(uri, PROJECTION, whereClause, null, null)) {
103         if (cursor == null) {
104           LogUtil.e(
105               "PackageReplacedReceiver.ExistingVoicemailCheck.doInBackground",
106               "failed to check for existing voicemails");
107         } else if (cursor.moveToFirst()) {
108           hasVoicemails = true;
109         }
110       }
111 
112       LogUtil.i(
113           "PackageReplacedReceiver.ExistingVoicemailCheck.doInBackground",
114           "has voicemails: " + hasVoicemails);
115       int version = hasVoicemails ? VoicemailVersionConstants.LEGACY_VOICEMAIL_FEATURE_VERSION : 0;
116       PreferenceManager.getDefaultSharedPreferences(context)
117           .edit()
118           .putInt(VoicemailVersionConstants.PREF_DIALER_FEATURE_VERSION_ACKNOWLEDGED_KEY, version)
119           .apply();
120       return null;
121     }
122   }
123 }
124