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.PersistableBundle;
     21 import android.provider.VoicemailContract.Status;
     22 import android.provider.VoicemailContract.Voicemails;
     23 import android.support.annotation.MainThread;
     24 import android.support.annotation.NonNull;
     25 import android.support.annotation.Nullable;
     26 import android.support.v4.os.BuildCompat;
     27 import android.telecom.PhoneAccountHandle;
     28 import android.telephony.TelephonyManager;
     29 import com.android.dialer.common.Assert;
     30 import com.android.dialer.common.LogUtil;
     31 import com.android.dialer.configprovider.ConfigProviderBindings;
     32 import com.android.voicemail.VisualVoicemailTypeExtensions;
     33 import com.android.voicemail.VoicemailClient;
     34 import com.android.voicemail.impl.configui.VoicemailSecretCodeActivity;
     35 import com.android.voicemail.impl.settings.VisualVoicemailSettingsUtil;
     36 import com.android.voicemail.impl.settings.VoicemailChangePinActivity;
     37 import com.android.voicemail.impl.settings.VoicemailSettingsFragment;
     38 import com.android.voicemail.impl.sync.VvmAccountManager;
     39 import java.util.List;
     40 import javax.inject.Inject;
     41 
     42 /**
     43  * {@link VoicemailClient} to be used when the voicemail module is activated. May only be used above
     44  * O.
     45  */
     46 public class VoicemailClientImpl implements VoicemailClient {
     47 
     48   /**
     49    * List of legacy OMTP voicemail packages that should be ignored. It could never be the active VVM
     50    * package anymore. For example, voicemails in OC will no longer be handled by telephony, but
     51    * legacy voicemails might still exist in the database due to upgrading from NYC. Dialer will
     52    * fetch these voicemails again so it should be ignored.
     53    */
     54   private static final String[] OMTP_VOICEMAIL_BLACKLIST = {"com.android.phone"};
     55 
     56   // Flag name used for configuration
     57   private static final String ALLOW_VOICEMAIL_ARCHIVE = "allow_voicemail_archive";
     58 
     59   private static final String[] OMTP_VOICEMAIL_TYPE = {
     60     TelephonyManager.VVM_TYPE_OMTP,
     61     TelephonyManager.VVM_TYPE_CVVM,
     62     VisualVoicemailTypeExtensions.VVM_TYPE_VVM3
     63   };
     64 
     65   @Inject
     66   public VoicemailClientImpl() {
     67     Assert.checkArgument(BuildCompat.isAtLeastO());
     68   }
     69 
     70   @Override
     71   public boolean isVoicemailModuleEnabled() {
     72     return true;
     73   }
     74 
     75   @Override
     76   public boolean isVoicemailEnabled(Context context, PhoneAccountHandle phoneAccountHandle) {
     77     return VisualVoicemailSettingsUtil.isEnabled(context, phoneAccountHandle);
     78   }
     79 
     80   @Override
     81   public void setVoicemailEnabled(
     82       Context context, PhoneAccountHandle phoneAccountHandle, boolean enabled) {
     83     VisualVoicemailSettingsUtil.setEnabled(context, phoneAccountHandle, enabled);
     84   }
     85 
     86   @Nullable
     87   @Override
     88   public String getSettingsFragment() {
     89     return VoicemailSettingsFragment.class.getName();
     90   }
     91 
     92   @Override
     93   public boolean isVoicemailArchiveEnabled(Context context, PhoneAccountHandle phoneAccountHandle) {
     94     return VisualVoicemailSettingsUtil.isArchiveEnabled(context, phoneAccountHandle);
     95   }
     96 
     97   @Override
     98   public boolean isVoicemailArchiveAvailable(Context context) {
     99     if (!BuildCompat.isAtLeastO()) {
    100       LogUtil.i("VoicemailClientImpl.isVoicemailArchiveAllowed", "not running on O or later");
    101       return false;
    102     }
    103 
    104     if (!ConfigProviderBindings.get(context).getBoolean(ALLOW_VOICEMAIL_ARCHIVE, false)) {
    105       LogUtil.i(
    106           "VoicemailClientImpl.isVoicemailArchiveAllowed",
    107           "feature disabled by config: %s",
    108           ALLOW_VOICEMAIL_ARCHIVE);
    109       return false;
    110     }
    111 
    112     return true;
    113   }
    114 
    115   @Override
    116   public void setVoicemailArchiveEnabled(
    117       Context context, PhoneAccountHandle phoneAccountHandle, boolean value) {
    118     VisualVoicemailSettingsUtil.setArchiveEnabled(context, phoneAccountHandle, value);
    119   }
    120 
    121   @Override
    122   public Intent getSetPinIntent(Context context, PhoneAccountHandle phoneAccountHandle) {
    123     Intent intent = new Intent(context, VoicemailChangePinActivity.class);
    124     intent.putExtra(VoicemailChangePinActivity.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
    125     return intent;
    126   }
    127 
    128   @Override
    129   public boolean isActivated(Context context, PhoneAccountHandle phoneAccountHandle) {
    130     return VvmAccountManager.isAccountActivated(context, phoneAccountHandle);
    131   }
    132 
    133   @Override
    134   public void showConfigUi(@NonNull Context context) {
    135     Intent intent = new Intent(context, VoicemailSecretCodeActivity.class);
    136     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    137     context.startActivity(intent);
    138   }
    139 
    140   @Override
    141   public PersistableBundle getConfig(Context context, PhoneAccountHandle phoneAccountHandle) {
    142     return new OmtpVvmCarrierConfigHelper(context, phoneAccountHandle).getConfig();
    143   }
    144 
    145   @Override
    146   @MainThread
    147   public void onBoot(@NonNull Context context) {
    148     OmtpService.onBoot(context);
    149     StatusCheckJobService.schedule(context);
    150   }
    151 
    152   @Override
    153   @MainThread
    154   public void onShutdown(@NonNull Context context) {
    155     OmtpService.onShutdown(context);
    156   }
    157 
    158   @TargetApi(VERSION_CODES.O)
    159   @Override
    160   public void appendOmtpVoicemailSelectionClause(
    161       Context context, StringBuilder where, List<String> selectionArgs) {
    162     String omtpSource =
    163         context.getSystemService(TelephonyManager.class).getVisualVoicemailPackageName();
    164     if (where.length() != 0) {
    165       where.append(" AND ");
    166     }
    167     where.append("(");
    168     {
    169       where.append("(");
    170       {
    171         where.append(Voicemails.IS_OMTP_VOICEMAIL).append(" != 1");
    172         where.append(")");
    173       }
    174       where.append(" OR ");
    175       where.append("(");
    176       {
    177         where.append(Voicemails.SOURCE_PACKAGE).append(" = ?");
    178         selectionArgs.add(omtpSource);
    179         where.append(")");
    180       }
    181       where.append(")");
    182     }
    183 
    184     for (String blacklistedPackage : OMTP_VOICEMAIL_BLACKLIST) {
    185       where.append("AND (").append(Voicemails.SOURCE_PACKAGE).append("!= ?)");
    186       selectionArgs.add(blacklistedPackage);
    187     }
    188   }
    189 
    190   @TargetApi(VERSION_CODES.O)
    191   @Override
    192   public void appendOmtpVoicemailStatusSelectionClause(
    193       Context context, StringBuilder where, List<String> selectionArgs) {
    194     String omtpSource =
    195         context.getSystemService(TelephonyManager.class).getVisualVoicemailPackageName();
    196     if (where.length() != 0) {
    197       where.append(" AND ");
    198     }
    199     where.append("(");
    200     {
    201       where.append("(");
    202       {
    203         where.append(Status.SOURCE_PACKAGE).append(" = ? ");
    204         selectionArgs.add(omtpSource);
    205         where.append(")");
    206       }
    207       where.append(" OR NOT (");
    208       {
    209         for (int i = 0; i < OMTP_VOICEMAIL_TYPE.length; i++) {
    210           if (i != 0) {
    211             where.append(" OR ");
    212           }
    213           where.append(" (");
    214           {
    215             where.append(Status.SOURCE_TYPE).append(" IS ?");
    216             selectionArgs.add(OMTP_VOICEMAIL_TYPE[i]);
    217             where.append(")");
    218           }
    219         }
    220         where.append(")");
    221       }
    222       for (String blacklistedPackage : OMTP_VOICEMAIL_BLACKLIST) {
    223         where.append("AND (");
    224         {
    225           where.append(Voicemails.SOURCE_PACKAGE).append("!= ?");
    226           selectionArgs.add(blacklistedPackage);
    227           where.append(")");
    228         }
    229       }
    230       where.append(")");
    231     }
    232   }
    233 }
    234