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.voicemail.impl.sms;
18 
19 import android.annotation.TargetApi;
20 import android.app.PendingIntent;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.os.Build.VERSION_CODES;
24 import android.os.Bundle;
25 import android.support.annotation.Nullable;
26 import android.telecom.PhoneAccountHandle;
27 import android.telephony.TelephonyManager;
28 import android.telephony.VisualVoicemailSms;
29 import com.android.dialer.callintent.CallInitiationType;
30 import com.android.dialer.callintent.CallIntentBuilder;
31 import com.android.dialer.precall.PreCall;
32 import com.android.voicemail.VoicemailClient;
33 import com.android.voicemail.impl.OmtpConstants;
34 import com.android.voicemail.impl.OmtpVvmCarrierConfigHelper;
35 import com.android.voicemail.impl.VvmLog;
36 
37 /**
38  * Class ot handle voicemail SMS under legacy mode
39  *
40  * @see OmtpVvmCarrierConfigHelper#isLegacyModeEnabled()
41  */
42 @TargetApi(VERSION_CODES.O)
43 public class LegacyModeSmsHandler {
44 
45   private static final String TAG = "LegacyModeSmsHandler";
46 
47   private static final int CALL_VOICEMAIL_REQUEST_CODE = 1;
48   private static final int LAUNCH_VOICEMAIL_SETTINGS_REQUEST_CODE = 2;
49 
handle(Context context, VisualVoicemailSms sms)50   public static void handle(Context context, VisualVoicemailSms sms) {
51     VvmLog.i(TAG, "processing VVM SMS on legacy mode");
52     String eventType = sms.getPrefix();
53     Bundle data = sms.getFields();
54     PhoneAccountHandle handle = sms.getPhoneAccountHandle();
55 
56     if (eventType.equals(OmtpConstants.SYNC_SMS_PREFIX)) {
57       SyncMessage message = new SyncMessage(data);
58       VvmLog.i(
59           TAG, "Received SYNC sms for " + handle + " with event " + message.getSyncTriggerEvent());
60 
61       switch (message.getSyncTriggerEvent()) {
62         case OmtpConstants.NEW_MESSAGE:
63         case OmtpConstants.MAILBOX_UPDATE:
64           sendLegacyVoicemailNotification(context, handle, message.getNewMessageCount());
65           break;
66         default:
67           break;
68       }
69     } else if (OmtpConstants.ALTERNATIVE_MAILBOX_UPDATE.equals(eventType)) {
70       VvmLog.w(TAG, "receiving alternative VVM SMS on non-activated account");
71       int messageCount = 0;
72       try {
73         messageCount =
74             Integer.parseInt(
75                 sms.getFields().getString(OmtpConstants.ALTERNATIVE_NUM_MESSAGE_COUNT));
76       } catch (NumberFormatException e) {
77         VvmLog.e(TAG, "missing message count");
78       }
79       sendLegacyVoicemailNotification(context, handle, messageCount);
80     }
81   }
82 
sendLegacyVoicemailNotification( Context context, PhoneAccountHandle phoneAccountHandle, int messageCount)83   private static void sendLegacyVoicemailNotification(
84       Context context, PhoneAccountHandle phoneAccountHandle, int messageCount) {
85     // The user has called into the voicemail and the new message count could
86     // change.
87     // For some carriers new message count could be set to 0 even if there are still
88     // unread messages, to clear the message waiting indicator.
89 
90     VvmLog.i(TAG, "sending voicemail notification");
91     Intent intent = new Intent(VoicemailClient.ACTION_SHOW_LEGACY_VOICEMAIL);
92     intent.setPackage(context.getPackageName());
93     intent.putExtra(VoicemailClient.EXTRA_IS_LEGACY_MODE, true);
94     intent.putExtra(TelephonyManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
95     // Setting voicemail message count to non-zero will show the telephony voicemail
96     // notification, and zero will clear it.
97     intent.putExtra(TelephonyManager.EXTRA_NOTIFICATION_COUNT, messageCount);
98 
99     String voicemailNumber = getVoicemailNumber(context, phoneAccountHandle);
100     PendingIntent callVoicemailPendingIntent = null;
101     PendingIntent launchVoicemailSettingsPendingIntent = null;
102 
103     if (voicemailNumber != null) {
104       callVoicemailPendingIntent =
105           PendingIntent.getActivity(
106               context,
107               CALL_VOICEMAIL_REQUEST_CODE,
108               PreCall.getIntent(
109                   context,
110                   CallIntentBuilder.forVoicemail(
111                       phoneAccountHandle, CallInitiationType.Type.LEGACY_VOICEMAIL_NOTIFICATION)),
112               PendingIntent.FLAG_UPDATE_CURRENT);
113     } else {
114       Intent launchVoicemailSettingsIntent =
115           new Intent(TelephonyManager.ACTION_CONFIGURE_VOICEMAIL);
116       launchVoicemailSettingsIntent.putExtra(TelephonyManager.EXTRA_HIDE_PUBLIC_SETTINGS, true);
117       launchVoicemailSettingsIntent.putExtra(
118           TelephonyManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
119 
120       launchVoicemailSettingsPendingIntent =
121           PendingIntent.getActivity(
122               context,
123               LAUNCH_VOICEMAIL_SETTINGS_REQUEST_CODE,
124               launchVoicemailSettingsIntent,
125               PendingIntent.FLAG_UPDATE_CURRENT);
126     }
127 
128     intent.putExtra(TelephonyManager.EXTRA_VOICEMAIL_NUMBER, voicemailNumber);
129     intent.putExtra(TelephonyManager.EXTRA_CALL_VOICEMAIL_INTENT, callVoicemailPendingIntent);
130     intent.putExtra(
131         TelephonyManager.EXTRA_LAUNCH_VOICEMAIL_SETTINGS_INTENT,
132         launchVoicemailSettingsPendingIntent);
133 
134     context.sendBroadcast(intent);
135   }
136 
137   @Nullable
getVoicemailNumber(Context context, PhoneAccountHandle phoneAccountHandle)138   private static String getVoicemailNumber(Context context, PhoneAccountHandle phoneAccountHandle) {
139     TelephonyManager telephonyManager =
140         context
141             .getSystemService(TelephonyManager.class)
142             .createForPhoneAccountHandle(phoneAccountHandle);
143     if (telephonyManager == null) {
144       return null;
145     }
146     return telephonyManager.getVoiceMailNumber();
147   }
148 }
149