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 */ 14package com.android.voicemail.impl; 15 16import android.annotation.TargetApi; 17import android.content.Context; 18import android.content.Intent; 19import android.os.Build.VERSION_CODES; 20import android.os.Bundle; 21import android.telecom.PhoneAccountHandle; 22import android.telephony.ServiceState; 23import android.telephony.TelephonyManager; 24import com.android.dialer.logging.DialerImpression; 25import com.android.dialer.proguard.UsedByReflection; 26import com.android.voicemail.impl.scheduling.BaseTask; 27import com.android.voicemail.impl.sms.StatusMessage; 28import com.android.voicemail.impl.sms.StatusSmsFetcher; 29import com.android.voicemail.impl.sync.VvmAccountManager; 30import com.android.voicemail.impl.utils.LoggerUtils; 31import java.io.IOException; 32import java.util.concurrent.CancellationException; 33import java.util.concurrent.ExecutionException; 34import 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") 46public class StatusCheckTask extends BaseTask { 47 48 public StatusCheckTask() { 49 super(TASK_STATUS_CHECK); 50 } 51 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 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