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