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 */
16package com.android.dialer.oem;
17
18import android.content.Context;
19import android.content.res.Resources;
20import android.telephony.TelephonyManager;
21import com.android.dialer.common.LogUtil;
22import com.android.dialer.common.PackageUtils;
23import com.android.dialer.configprovider.ConfigProviderBindings;
24import java.lang.reflect.InvocationTargetException;
25import java.lang.reflect.Method;
26
27/** Util class for Motorola OEM devices. */
28public class MotorolaUtils {
29
30  private static final String CONFIG_HD_CODEC_BLINKING_ICON_WHEN_CONNECTING_CALL_ENABLED =
31      "hd_codec_blinking_icon_when_connecting_enabled";
32  private static final String CONFIG_HD_CODEC_SHOW_ICON_IN_NOTIFICATION_ENABLED =
33      "hd_codec_show_icon_in_notification_enabled";
34  private static final String CONFIG_HD_CODEC_SHOW_ICON_IN_CALL_LOG_ENABLED =
35      "hd_codec_show_icon_in_call_log_enabled";
36  private static final String CONFIG_WIFI_CALL_SHOW_ICON_IN_CALL_LOG_ENABLED =
37      "wifi_call_show_icon_in_call_log_enabled";
38
39  // This is used to check if a Motorola device supports HD voice call feature, which comes from
40  // system feature setting.
41  private static final String HD_CALL_FEATRURE = "com.motorola.software.sprint.hd_call";
42  // This is used to check if a Motorola device supports WiFi call feature, by checking if a certain
43  // package is enabled.
44  private static final String WIFI_CALL_PACKAGE_NAME = "com.motorola.sprintwfc";
45  // Thi is used to check if a Motorola device supports hidden menu feature.
46  private static final String HIDDEN_MENU_FEATURE = "com.motorola.software.sprint.hidden_menu";
47
48  // Feature flag indicates it's a HD call, currently this is only used by Motorola system build.
49  // TODO(b/35359461): Use reference to android.provider.CallLog once it's in new SDK.
50  private static final int FEATURES_HD_CALL = 0x4;
51  // Feature flag indicates it's a WiFi call, currently this is only used by Motorola system build.
52  private static final int FEATURES_WIFI = 0x8;
53
54  private static boolean hasCheckedSprintWifiCall;
55  private static boolean supportSprintWifiCall;
56
57  /**
58   * Returns true if SPN is specified and matched the current sim operator name. This is necessary
59   * since mcc310-mnc000 is not sufficient to identify Sprint network.
60   */
61  static boolean isSpnMatched(Context context) {
62    try {
63      String spnResource = context.getResources().getString(R.string.motorola_enabled_spn);
64      return spnResource.equalsIgnoreCase(
65          context.getSystemService(TelephonyManager.class).getSimOperatorName());
66    } catch (Resources.NotFoundException exception) {
67      // If SPN is not specified we consider as not necessary to enable/disable the feature.
68      return true;
69    }
70  }
71
72  static boolean isSupportingHiddenMenu(Context context) {
73    return context.getPackageManager().hasSystemFeature(HIDDEN_MENU_FEATURE);
74  }
75
76  public static boolean shouldBlinkHdIconWhenConnectingCall(Context context) {
77    return ConfigProviderBindings.get(context)
78            .getBoolean(CONFIG_HD_CODEC_BLINKING_ICON_WHEN_CONNECTING_CALL_ENABLED, true)
79        && isSupportingSprintHdCodec(context);
80  }
81
82  public static boolean shouldShowHdIconInNotification(Context context) {
83    return ConfigProviderBindings.get(context)
84            .getBoolean(CONFIG_HD_CODEC_SHOW_ICON_IN_NOTIFICATION_ENABLED, true)
85        && isSupportingSprintHdCodec(context);
86  }
87
88  public static boolean shouldShowHdIconInCallLog(Context context, int features) {
89    return ConfigProviderBindings.get(context)
90            .getBoolean(CONFIG_HD_CODEC_SHOW_ICON_IN_CALL_LOG_ENABLED, true)
91        && (features & FEATURES_HD_CALL) == FEATURES_HD_CALL
92        && isSupportingSprintHdCodec(context);
93  }
94
95  public static boolean shouldShowWifiIconInCallLog(Context context, int features) {
96    return ConfigProviderBindings.get(context)
97            .getBoolean(CONFIG_WIFI_CALL_SHOW_ICON_IN_CALL_LOG_ENABLED, true)
98        && (features & FEATURES_WIFI) == FEATURES_WIFI
99        && isSupportingSprintWifiCall(context);
100  }
101
102  /**
103   * Handle special char sequence entered in dialpad. This may launch special intent based on input.
104   *
105   * @param context context
106   * @param input input string
107   * @return true if the input is consumed and the intent is launched
108   */
109  public static boolean handleSpecialCharSequence(Context context, String input) {
110    // TODO(b/35395377): Add check for Motorola devices.
111    return MotorolaHiddenMenuKeySequence.handleCharSequence(context, input);
112  }
113
114  public static boolean isWifiCallingAvailable(Context context) {
115    if (!isSupportingSprintWifiCall(context)) {
116      return false;
117    }
118    TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class);
119    try {
120      Method method = TelephonyManager.class.getMethod("isWifiCallingAvailable");
121      boolean isWifiCallingAvailable = (boolean) method.invoke(telephonyManager);
122      LogUtil.d("MotorolaUtils.isWifiCallingAvailable", "%b", isWifiCallingAvailable);
123      return isWifiCallingAvailable;
124    } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
125      LogUtil.e("MotorolaUtils.isWifiCallingAvailable", "", e);
126    }
127    return false;
128  }
129
130  private static boolean isSupportingSprintHdCodec(Context context) {
131    return isSpnMatched(context)
132        && context.getResources().getBoolean(R.bool.motorola_sprint_hd_codec)
133        && context.getPackageManager().hasSystemFeature(HD_CALL_FEATRURE);
134  }
135
136  private static boolean isSupportingSprintWifiCall(Context context) {
137    if (!hasCheckedSprintWifiCall) {
138      supportSprintWifiCall = PackageUtils.isPackageEnabled(WIFI_CALL_PACKAGE_NAME, context);
139      hasCheckedSprintWifiCall = true;
140    }
141    return supportSprintWifiCall;
142  }
143}
144