1d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian/*
2d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian * Copyright (C) 2017 The Android Open Source Project
3d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian *
4d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian * This file is derived in part from code issued under the following license.
5d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian *
6d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian * Licensed under the Apache License, Version 2.0 (the "License");
7d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian * you may not use this file except in compliance with the License.
8d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian * You may obtain a copy of the License at
9d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian *
10d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian *      http://www.apache.org/licenses/LICENSE-2.0
11d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian *
12d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian * Unless required by applicable law or agreed to in writing, software
13d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian * distributed under the License is distributed on an "AS IS" BASIS,
14d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian * See the License for the specific language governing permissions and
16d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian * limitations under the License.
17d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian *
18d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian */
19d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanianpackage com.android.dialer.oem;
20d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
21d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanianimport android.content.ActivityNotFoundException;
22d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanianimport android.content.Context;
23d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanianimport android.content.Intent;
24d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanianimport android.content.pm.ResolveInfo;
25d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanianimport com.android.dialer.common.LogUtil;
26d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanianimport java.util.regex.Pattern;
27d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
28d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian/**
29d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian * Util class to handle special char sequence and launch corresponding intent based the sequence.
30d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian */
31d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanianpublic class MotorolaHiddenMenuKeySequence {
32d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  private static final String EXTRA_HIDDEN_MENU_CODE = "HiddenMenuCode";
33d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  private static MotorolaHiddenMenuKeySequence instance = null;
34d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
35d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  private static String[] hiddenKeySequenceArray = null;
36d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  private static String[] hiddenKeySequenceIntentArray = null;
37d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  private static String[] hiddenKeyPatternArray = null;
38d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  private static String[] hiddenKeyPatternIntentArray = null;
39d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  private static boolean featureHiddenMenuEnabled = false;
40d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
41d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  /**
42d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian   * Handle input char sequence.
43d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian   *
44d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian   * @param context context
45d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian   * @param input input sequence
46d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian   * @return true if the input matches any pattern
47d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian   */
48d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  static boolean handleCharSequence(Context context, String input) {
49d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    getInstance(context);
50d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    if (!featureHiddenMenuEnabled) {
51d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      return false;
52d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    }
53d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    return handleKeySequence(context, input) || handleKeyPattern(context, input);
54d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  }
55d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
56d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  /**
57d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian   * Public interface to return the Singleton instance
58d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian   *
59d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian   * @param context the Context
60d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian   * @return the MotorolaHiddenMenuKeySequence singleton instance
61d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian   */
62d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  private static synchronized MotorolaHiddenMenuKeySequence getInstance(Context context) {
63d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    if (null == instance) {
64d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      instance = new MotorolaHiddenMenuKeySequence(context);
65d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    }
66d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    return instance;
67d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  }
68d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
69d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  private MotorolaHiddenMenuKeySequence(Context context) {
70d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    featureHiddenMenuEnabled =
719050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian        MotorolaUtils.isSpnMatched(context)
729050823ccf6f512e06ad65c8a741cb17cbc4a833Eric Erfanian            && context.getResources().getBoolean(R.bool.motorola_feature_hidden_menu);
73d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    // In case we do have a SPN from resource we need to match from service; otherwise we are
74d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    // free to go
75d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    if (featureHiddenMenuEnabled) {
76d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
77d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      hiddenKeySequenceArray =
78d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian          context.getResources().getStringArray(R.array.motorola_hidden_menu_key_sequence);
79d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      hiddenKeySequenceIntentArray =
80d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian          context.getResources().getStringArray(R.array.motorola_hidden_menu_key_sequence_intents);
81d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      hiddenKeyPatternArray =
82d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian          context.getResources().getStringArray(R.array.motorola_hidden_menu_key_pattern);
83d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      hiddenKeyPatternIntentArray =
84d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian          context.getResources().getStringArray(R.array.motorola_hidden_menu_key_pattern_intents);
85d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
86d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      if (hiddenKeySequenceArray.length != hiddenKeySequenceIntentArray.length
87d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian          || hiddenKeyPatternArray.length != hiddenKeyPatternIntentArray.length
88d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian          || (hiddenKeySequenceArray.length == 0 && hiddenKeyPatternArray.length == 0)) {
89d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian        LogUtil.e(
90d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian            "MotorolaHiddenMenuKeySequence",
91d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian            "the key sequence array is not matching, turn off feature."
92d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian                + "key sequence: %d != %d, key pattern %d != %d",
93d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian            hiddenKeySequenceArray.length,
94d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian            hiddenKeySequenceIntentArray.length,
95d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian            hiddenKeyPatternArray.length,
96d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian            hiddenKeyPatternIntentArray.length);
97d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian        featureHiddenMenuEnabled = false;
98d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      }
99d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    }
100d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  }
101d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
102d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  private static boolean handleKeyPattern(Context context, String input) {
103d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    int len = input.length();
104d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    if (len <= 3 || hiddenKeyPatternArray == null || hiddenKeyPatternIntentArray == null) {
105d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      return false;
106d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    }
107d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
108d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    for (int i = 0; i < hiddenKeyPatternArray.length; i++) {
109d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      if ((Pattern.compile(hiddenKeyPatternArray[i])).matcher(input).matches()) {
110d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian        return sendIntent(context, input, hiddenKeyPatternIntentArray[i]);
111d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      }
112d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    }
113d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    return false;
114d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  }
115d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
116d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  private static boolean handleKeySequence(Context context, String input) {
117d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    int len = input.length();
118d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    if (len <= 3 || hiddenKeySequenceArray == null || hiddenKeySequenceIntentArray == null) {
119d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      return false;
120d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    }
121d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
122d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    for (int i = 0; i < hiddenKeySequenceArray.length; i++) {
123d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      if (hiddenKeySequenceArray[i].equals(input)) {
124d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian        return sendIntent(context, input, hiddenKeySequenceIntentArray[i]);
125d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      }
126d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    }
127d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    return false;
128d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  }
129d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
130d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  private static boolean sendIntent(
131d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      final Context context, final String input, final String action) {
132d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    LogUtil.d("MotorolaHiddenMenuKeySequence.sendIntent", "input: %s", input);
133d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    try {
134d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      Intent intent = new Intent(action);
135d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
136d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      intent.putExtra(EXTRA_HIDDEN_MENU_CODE, input);
137d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
138d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      ResolveInfo resolveInfo = context.getPackageManager().resolveActivity(intent, 0);
139d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
140d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      if (resolveInfo != null
141d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian          && resolveInfo.activityInfo != null
142d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian          && resolveInfo.activityInfo.enabled) {
143d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian        context.startActivity(intent);
144d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian        return true;
145d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      } else {
146d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian        LogUtil.w("MotorolaHiddenMenuKeySequence.sendIntent", "not able to resolve the intent");
147d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      }
148d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    } catch (ActivityNotFoundException e) {
149d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      LogUtil.e(
150d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian          "MotorolaHiddenMenuKeySequence.sendIntent", "handleHiddenMenu Key Pattern Exception", e);
151d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    }
152d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    return false;
153d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  }
154d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian}
155