Home | History | Annotate | Download | only in impl
      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.annotation.TargetApi;
     20 import android.content.Context;
     21 import android.content.Intent;
     22 import android.os.Build.VERSION_CODES;
     23 import android.os.UserManager;
     24 import android.preference.PreferenceManager;
     25 import android.support.annotation.MainThread;
     26 import android.support.annotation.NonNull;
     27 import android.telecom.PhoneAccountHandle;
     28 import android.telephony.VisualVoicemailService;
     29 import android.telephony.VisualVoicemailSms;
     30 import com.android.dialer.logging.DialerImpression;
     31 import com.android.dialer.logging.Logger;
     32 import com.android.voicemail.VoicemailComponent;
     33 import com.android.voicemail.impl.settings.VisualVoicemailSettingsUtil;
     34 import com.android.voicemail.impl.sms.LegacyModeSmsHandler;
     35 import com.android.voicemail.impl.sync.VvmAccountManager;
     36 
     37 /** Implements {@link VisualVoicemailService} to receive visual voicemail events */
     38 @TargetApi(VERSION_CODES.O)
     39 public class OmtpService extends VisualVoicemailService {
     40 
     41   private static final String TAG = "VvmOmtpService";
     42 
     43   public static final String ACTION_SMS_RECEIVED = "com.android.vociemailomtp.sms.sms_received";
     44 
     45   public static final String EXTRA_VOICEMAIL_SMS = "extra_voicemail_sms";
     46 
     47   private static final String IS_SHUTTING_DOWN = "com.android.voicemail.impl.is_shutting_down";
     48 
     49   @Override
     50   public void onCellServiceConnected(
     51       VisualVoicemailTask task, final PhoneAccountHandle phoneAccountHandle) {
     52     VvmLog.i(TAG, "onCellServiceConnected");
     53     if (!isModuleEnabled()) {
     54       VvmLog.e(TAG, "onCellServiceConnected received when module is disabled");
     55       task.finish();
     56       return;
     57     }
     58 
     59     if (!isUserUnlocked(this)) {
     60       VvmLog.i(TAG, "onCellServiceConnected: user locked");
     61       task.finish();
     62       return;
     63     }
     64 
     65     if (!isServiceEnabled(phoneAccountHandle)) {
     66       task.finish();
     67       return;
     68     }
     69 
     70     Logger.get(this).logImpression(DialerImpression.Type.VVM_UNBUNDLED_EVENT_RECEIVED);
     71     ActivationTask.start(OmtpService.this, phoneAccountHandle, null);
     72     task.finish();
     73   }
     74 
     75   @Override
     76   public void onSmsReceived(VisualVoicemailTask task, final VisualVoicemailSms sms) {
     77     VvmLog.i(TAG, "onSmsReceived");
     78     if (!isModuleEnabled()) {
     79       VvmLog.e(TAG, "onSmsReceived received when module is disabled");
     80       task.finish();
     81       return;
     82     }
     83 
     84     if (!isUserUnlocked(this)) {
     85       LegacyModeSmsHandler.handle(this, sms);
     86       return;
     87     }
     88 
     89     if (!isServiceEnabled(sms.getPhoneAccountHandle())) {
     90       task.finish();
     91       return;
     92     }
     93 
     94     // isUserUnlocked() is not checked. OmtpMessageReceiver will handle the locked case.
     95 
     96     Logger.get(this).logImpression(DialerImpression.Type.VVM_UNBUNDLED_EVENT_RECEIVED);
     97     Intent intent = new Intent(ACTION_SMS_RECEIVED);
     98     intent.setPackage(getPackageName());
     99     intent.putExtra(EXTRA_VOICEMAIL_SMS, sms);
    100     sendBroadcast(intent);
    101     task.finish();
    102   }
    103 
    104   @Override
    105   public void onSimRemoved(
    106       final VisualVoicemailTask task, final PhoneAccountHandle phoneAccountHandle) {
    107     VvmLog.i(TAG, "onSimRemoved");
    108     if (!isModuleEnabled()) {
    109       VvmLog.e(TAG, "onSimRemoved called when module is disabled");
    110       task.finish();
    111       return;
    112     }
    113 
    114     if (!isUserUnlocked(this)) {
    115       VvmLog.i(TAG, "onSimRemoved: user locked");
    116       task.finish();
    117       return;
    118     }
    119 
    120     if (isShuttingDown(this)) {
    121       VvmLog.i(TAG, "onSimRemoved: system shutting down, ignoring");
    122       task.finish();
    123       return;
    124     }
    125 
    126     Logger.get(this).logImpression(DialerImpression.Type.VVM_UNBUNDLED_EVENT_RECEIVED);
    127     VvmAccountManager.removeAccount(this, phoneAccountHandle);
    128     task.finish();
    129   }
    130 
    131   @Override
    132   public void onStopped(VisualVoicemailTask task) {
    133     VvmLog.i(TAG, "onStopped");
    134     if (!isModuleEnabled()) {
    135       VvmLog.e(TAG, "onStopped called when module is disabled");
    136       task.finish();
    137       return;
    138     }
    139     if (!isUserUnlocked(this)) {
    140       VvmLog.i(TAG, "onStopped: user locked");
    141       task.finish();
    142       return;
    143     }
    144     Logger.get(this).logImpression(DialerImpression.Type.VVM_UNBUNDLED_EVENT_RECEIVED);
    145   }
    146 
    147   @MainThread
    148   static void onBoot(@NonNull Context context) {
    149     VvmLog.i(TAG, "onBoot");
    150     Assert.isTrue(isUserUnlocked(context));
    151     Assert.isMainThread();
    152     setShuttingDown(context, false);
    153   }
    154 
    155   @MainThread
    156   static void onShutdown(@NonNull Context context) {
    157     VvmLog.i(TAG, "onShutdown");
    158     Assert.isTrue(isUserUnlocked(context));
    159     Assert.isMainThread();
    160     setShuttingDown(context, true);
    161   }
    162 
    163   private boolean isModuleEnabled() {
    164     return VoicemailComponent.get(this).getVoicemailClient().isVoicemailModuleEnabled();
    165   }
    166 
    167   private boolean isServiceEnabled(PhoneAccountHandle phoneAccountHandle) {
    168     OmtpVvmCarrierConfigHelper config = new OmtpVvmCarrierConfigHelper(this, phoneAccountHandle);
    169     if (!config.isValid()) {
    170       VvmLog.i(TAG, "VVM not supported on " + phoneAccountHandle);
    171       return false;
    172     }
    173     if (!VisualVoicemailSettingsUtil.isEnabled(this, phoneAccountHandle)
    174         && !config.isLegacyModeEnabled()) {
    175       VvmLog.i(TAG, "VVM is disabled");
    176       return false;
    177     }
    178     return true;
    179   }
    180 
    181   private static boolean isUserUnlocked(@NonNull Context context) {
    182     UserManager userManager = context.getSystemService(UserManager.class);
    183     return userManager.isUserUnlocked();
    184   }
    185 
    186   private static void setShuttingDown(Context context, boolean value) {
    187     PreferenceManager.getDefaultSharedPreferences(context)
    188         .edit()
    189         .putBoolean(IS_SHUTTING_DOWN, value)
    190         .apply();
    191   }
    192 
    193   private static boolean isShuttingDown(Context context) {
    194     return PreferenceManager.getDefaultSharedPreferences(context)
    195         .getBoolean(IS_SHUTTING_DOWN, false);
    196   }
    197 }
    198