1 /** 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * <p>Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 * except in compliance with the License. You may obtain a copy of the License at 6 * 7 * <p>http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * <p>Unless required by applicable law or agreed to in writing, software distributed under the 10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 * express or implied. See the License for the specific language governing permissions and 12 * limitations under the License 13 */ 14 package com.android.voicemail.impl; 15 16 import android.annotation.TargetApi; 17 import android.content.Context; 18 import android.content.Intent; 19 import android.os.Build.VERSION_CODES; 20 import android.os.Bundle; 21 import android.telecom.PhoneAccountHandle; 22 import android.telephony.ServiceState; 23 import android.telephony.TelephonyManager; 24 import com.android.dialer.logging.DialerImpression; 25 import com.android.dialer.proguard.UsedByReflection; 26 import com.android.voicemail.impl.scheduling.BaseTask; 27 import com.android.voicemail.impl.sms.StatusMessage; 28 import com.android.voicemail.impl.sms.StatusSmsFetcher; 29 import com.android.voicemail.impl.sync.VvmAccountManager; 30 import com.android.voicemail.impl.utils.LoggerUtils; 31 import java.io.IOException; 32 import java.util.concurrent.CancellationException; 33 import java.util.concurrent.ExecutionException; 34 import java.util.concurrent.TimeoutException; 35 36 /** 37 * Task to verify the account status is still correct. This task is only for book keeping so any 38 * error is ignored and will not retry. If the provision status sent by the carrier is "ready" the 39 * access credentials will be updated (although it is not expected to change without the carrier 40 * actively sending out an STATUS SMS which will be handled by {@link 41 * com.android.voicemail.impl.sms.OmtpMessageReceiver}). If the provisioning status is not ready an 42 * {@link ActivationTask} will be launched to attempt to correct it. 43 */ 44 @TargetApi(VERSION_CODES.O) 45 @UsedByReflection(value = "Tasks.java") 46 public class StatusCheckTask extends BaseTask { 47 StatusCheckTask()48 public StatusCheckTask() { 49 super(TASK_STATUS_CHECK); 50 } 51 start(Context context, PhoneAccountHandle phoneAccountHandle)52 public static void start(Context context, PhoneAccountHandle phoneAccountHandle) { 53 Intent intent = BaseTask.createIntent(context, StatusCheckTask.class, phoneAccountHandle); 54 context.sendBroadcast(intent); 55 } 56 57 @Override onExecuteInBackgroundThread()58 public void onExecuteInBackgroundThread() { 59 TelephonyManager telephonyManager = 60 getContext() 61 .getSystemService(TelephonyManager.class) 62 .createForPhoneAccountHandle(getPhoneAccountHandle()); 63 64 if (telephonyManager == null) { 65 VvmLog.w( 66 "StatusCheckTask.onExecuteInBackgroundThread", 67 getPhoneAccountHandle() + " no longer valid"); 68 return; 69 } 70 if (telephonyManager.getServiceState().getState() != ServiceState.STATE_IN_SERVICE) { 71 VvmLog.i( 72 "StatusCheckTask.onExecuteInBackgroundThread", 73 getPhoneAccountHandle() + " not in service"); 74 return; 75 } 76 OmtpVvmCarrierConfigHelper config = 77 new OmtpVvmCarrierConfigHelper(getContext(), getPhoneAccountHandle()); 78 if (!config.isValid()) { 79 VvmLog.e( 80 "StatusCheckTask.onExecuteInBackgroundThread", 81 "config no longer valid for " + getPhoneAccountHandle()); 82 VvmAccountManager.removeAccount(getContext(), getPhoneAccountHandle()); 83 return; 84 } 85 86 Bundle data; 87 try (StatusSmsFetcher fetcher = new StatusSmsFetcher(getContext(), getPhoneAccountHandle())) { 88 config.getProtocol().requestStatus(config, fetcher.getSentIntent()); 89 // Both the fetcher and OmtpMessageReceiver will be triggered, but 90 // OmtpMessageReceiver will just route the SMS back to ActivationTask, which will be 91 // rejected because the task is still running. 92 data = fetcher.get(); 93 } catch (TimeoutException e) { 94 VvmLog.e("StatusCheckTask.onExecuteInBackgroundThread", "timeout requesting status"); 95 return; 96 } catch (CancellationException e) { 97 VvmLog.e("StatusCheckTask.onExecuteInBackgroundThread", "Unable to send status request SMS"); 98 return; 99 } catch (InterruptedException | ExecutionException | IOException e) { 100 VvmLog.e("StatusCheckTask.onExecuteInBackgroundThread", "can't get future STATUS SMS", e); 101 return; 102 } 103 104 StatusMessage message = new StatusMessage(data); 105 VvmLog.i( 106 "StatusCheckTask.onExecuteInBackgroundThread", 107 "STATUS SMS received: st=" 108 + message.getProvisioningStatus() 109 + ", rc=" 110 + message.getReturnCode()); 111 if (message.getProvisioningStatus().equals(OmtpConstants.SUBSCRIBER_READY)) { 112 VvmLog.i( 113 "StatusCheckTask.onExecuteInBackgroundThread", 114 "subscriber ready, no activation required"); 115 LoggerUtils.logImpressionOnMainThread( 116 getContext(), DialerImpression.Type.VVM_STATUS_CHECK_READY); 117 VvmAccountManager.addAccount(getContext(), getPhoneAccountHandle(), message); 118 } else { 119 VvmLog.i( 120 "StatusCheckTask.onExecuteInBackgroundThread", 121 "subscriber not ready, attempting reactivation"); 122 VvmAccountManager.removeAccount(getContext(), getPhoneAccountHandle()); 123 LoggerUtils.logImpressionOnMainThread( 124 getContext(), DialerImpression.Type.VVM_STATUS_CHECK_REACTIVATION); 125 ActivationTask.start(getContext(), getPhoneAccountHandle(), data); 126 } 127 } 128 } 129