Home | History | Annotate | Download | only in preferredsim
      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.dialer.preferredsim;
     18 
     19 import android.content.ComponentName;
     20 import android.content.Context;
     21 import android.os.Build.VERSION;
     22 import android.os.Build.VERSION_CODES;
     23 import android.support.annotation.NonNull;
     24 import android.support.annotation.Nullable;
     25 import android.telecom.PhoneAccount;
     26 import android.telecom.PhoneAccountHandle;
     27 import android.telecom.TelecomManager;
     28 import android.telephony.SubscriptionInfo;
     29 import android.telephony.SubscriptionManager;
     30 import android.telephony.TelephonyManager;
     31 import android.text.TextUtils;
     32 import com.android.dialer.common.LogUtil;
     33 import com.android.dialer.configprovider.ConfigProviderComponent;
     34 import com.google.common.base.Optional;
     35 import com.google.common.collect.ImmutableSet;
     36 
     37 /**
     38  * Utilities for looking up and validating preferred {@link PhoneAccountHandle}. Contacts should
     39  * follow the same logic.
     40  */
     41 public class PreferredAccountUtil {
     42 
     43   /**
     44    * Validates {@code componentNameString} and {@code idString} maps to SIM that is present on the
     45    * device.
     46    */
     47   @NonNull
     48   public static Optional<PhoneAccountHandle> getValidPhoneAccount(
     49       @NonNull Context context, @Nullable String componentNameString, @Nullable String idString) {
     50     if (TextUtils.isEmpty(componentNameString) || TextUtils.isEmpty(idString)) {
     51       LogUtil.i("PreferredAccountUtil.getValidPhoneAccount", "empty componentName or id");
     52       return Optional.absent();
     53     }
     54     ComponentName componentName = ComponentName.unflattenFromString(componentNameString);
     55     if (componentName == null) {
     56       LogUtil.e("PreferredAccountUtil.getValidPhoneAccount", "cannot parse component name");
     57       return Optional.absent();
     58     }
     59     PhoneAccountHandle phoneAccountHandle = new PhoneAccountHandle(componentName, idString);
     60 
     61     if (isPhoneAccountValid(context, phoneAccountHandle)) {
     62       return Optional.of(phoneAccountHandle);
     63     }
     64     return Optional.absent();
     65   }
     66 
     67   public static boolean isPhoneAccountValid(
     68       Context context, PhoneAccountHandle phoneAccountHandle) {
     69     if (VERSION.SDK_INT >= VERSION_CODES.O) {
     70       return context
     71               .getSystemService(TelephonyManager.class)
     72               .createForPhoneAccountHandle(phoneAccountHandle)
     73           != null;
     74     }
     75 
     76     PhoneAccount phoneAccount =
     77         context.getSystemService(TelecomManager.class).getPhoneAccount(phoneAccountHandle);
     78     if (phoneAccount == null) {
     79       LogUtil.e("PreferredAccountUtil.isPhoneAccountValid", "invalid phone account");
     80       return false;
     81     }
     82 
     83     if (!phoneAccount.isEnabled()) {
     84       LogUtil.e("PreferredAccountUtil.isPhoneAccountValid", "disabled phone account");
     85       return false;
     86     }
     87     for (SubscriptionInfo info :
     88         SubscriptionManager.from(context).getActiveSubscriptionInfoList()) {
     89       if (phoneAccountHandle.getId().startsWith(info.getIccId())) {
     90         LogUtil.i("PreferredAccountUtil.isPhoneAccountValid", "sim found");
     91         return true;
     92       }
     93     }
     94     return false;
     95   }
     96 
     97   /**
     98    * Return a set of {@link android.accounts.Account#type} that is known to have writable contacts.
     99    * This is a light weight implementation of {@link
    100    * com.android.contacts.common.model.AccountTypeManager#getAccountTypes(boolean)}. External
    101    * accounts are not supported.
    102    */
    103   public static ImmutableSet<String> getValidAccountTypes(Context context) {
    104     return ImmutableSet.copyOf(
    105         ConfigProviderComponent.get(context)
    106             .getConfigProvider()
    107             .getString(
    108                 "preferred_sim_valid_account_types",
    109                 "com.google;"
    110                     + "com.osp.app.signin;"
    111                     + "com.android.exchange;"
    112                     + "com.google.android.exchange;"
    113                     + "com.google.android.gm.exchange")
    114             .split(";"));
    115   }
    116 }
    117