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.assisteddialing;
18 
19 import android.content.Context;
20 import android.os.Build;
21 import android.preference.PreferenceManager;
22 import android.support.annotation.NonNull;
23 import android.support.v4.os.UserManagerCompat;
24 import android.telephony.TelephonyManager;
25 import com.android.dialer.common.LogUtil;
26 import com.android.dialer.configprovider.ConfigProvider;
27 import com.android.dialer.configprovider.ConfigProviderComponent;
28 import com.android.dialer.strictmode.StrictModeUtils;
29 
30 /**
31  * A Creator for AssistedDialingMediators.
32  *
33  * <p>This helps keep the dependencies required by AssistedDialingMediator for assisted dialing
34  * explicit.
35  */
36 public final class ConcreteCreator {
37 
38   // Ceiling set at P (version code 28) because this feature will ship as part of the framework in
39   // Q.
40   public static final int BUILD_CODE_CEILING = 28;
41 
42   /**
43    * Creates a new AssistedDialingMediator
44    *
45    * @param telephonyManager The telephony manager used to determine user location.
46    * @param context The context used to determine whether or not a provided number is an emergency
47    *     number.
48    * @return An AssistedDialingMediator
49    */
createNewAssistedDialingMediator( @onNull TelephonyManager telephonyManager, @NonNull Context context)50   public static AssistedDialingMediator createNewAssistedDialingMediator(
51       @NonNull TelephonyManager telephonyManager, @NonNull Context context) {
52 
53     ConfigProvider configProvider = ConfigProviderComponent.get(context).getConfigProvider();
54 
55     if (telephonyManager == null) {
56       LogUtil.i(
57           "ConcreteCreator.createNewAssistedDialingMediator", "provided TelephonyManager was null");
58       throw new NullPointerException("Provided TelephonyManager was null");
59     }
60     if (context == null) {
61       LogUtil.i("ConcreteCreator.createNewAssistedDialingMediator", "provided context was null");
62       throw new NullPointerException("Provided context was null");
63     }
64 
65     if (!UserManagerCompat.isUserUnlocked(context)) {
66       // To avoid any issues reading preferences, we disable the feature when the user is in a
67       // locked state.
68       LogUtil.i("ConcreteCreator.createNewAssistedDialingMediator", "user is locked");
69       return new AssistedDialingMediatorStub();
70     }
71 
72     if (!isAssistedDialingEnabled(configProvider)) {
73       LogUtil.i("ConcreteCreator.createNewAssistedDialingMediator", "feature not enabled");
74       return new AssistedDialingMediatorStub();
75     }
76 
77     if (!PreferenceManager.getDefaultSharedPreferences(context)
78         .getBoolean(context.getString(R.string.assisted_dialing_setting_toggle_key), true)) {
79       LogUtil.i("ConcreteCreator.createNewAssistedDialingMediator", "disabled by local setting");
80 
81       return new AssistedDialingMediatorStub();
82     }
83 
84     Constraints constraints = new Constraints(context, getCountryCodeProvider(configProvider));
85     return new AssistedDialingMediatorImpl(
86         new LocationDetector(
87             telephonyManager,
88             StrictModeUtils.bypass(
89                 () ->
90                     PreferenceManager.getDefaultSharedPreferences(context)
91                         .getString(
92                             context.getString(R.string.assisted_dialing_setting_cc_key), null))),
93         new NumberTransformer(constraints));
94   }
95 
96   /** Returns a boolean indicating whether or not the assisted dialing feature is enabled. */
isAssistedDialingEnabled(@onNull ConfigProvider configProvider)97   public static boolean isAssistedDialingEnabled(@NonNull ConfigProvider configProvider) {
98     if (configProvider == null) {
99       LogUtil.i("ConcreteCreator.isAssistedDialingEnabled", "provided configProvider was null");
100       throw new NullPointerException("Provided configProvider was null");
101     }
102 
103     return Build.VERSION.SDK_INT <= BUILD_CODE_CEILING
104         && configProvider.getBoolean("assisted_dialing_enabled", false);
105   }
106 
107   /**
108    * Returns a CountryCodeProvider responsible for providing countries eligible for assisted Dialing
109    */
getCountryCodeProvider(ConfigProvider configProvider)110   public static CountryCodeProvider getCountryCodeProvider(ConfigProvider configProvider) {
111     if (configProvider == null) {
112       LogUtil.i("ConcreteCreator.getCountryCodeProvider", "provided configProvider was null");
113       throw new NullPointerException("Provided configProvider was null");
114     }
115 
116     return new CountryCodeProvider(configProvider);
117   }
118 }
119