Home | History | Annotate | Download | only in impl
      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 
     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