• 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 =
71         MotorolaUtils.isSpnMatched(context)
72             && context.getResources().getBoolean(R.bool.motorola_feature_hidden_menu);
73     // In case we do have a SPN from resource we need to match from service; otherwise we are
74     // free to go
75     if (featureHiddenMenuEnabled) {
76 
77       hiddenKeySequenceArray =
78           context.getResources().getStringArray(R.array.motorola_hidden_menu_key_sequence);
79       hiddenKeySequenceIntentArray =
80           context.getResources().getStringArray(R.array.motorola_hidden_menu_key_sequence_intents);
81       hiddenKeyPatternArray =
82           context.getResources().getStringArray(R.array.motorola_hidden_menu_key_pattern);
83       hiddenKeyPatternIntentArray =
84           context.getResources().getStringArray(R.array.motorola_hidden_menu_key_pattern_intents);
85 
86       if (hiddenKeySequenceArray.length != hiddenKeySequenceIntentArray.length
87           || hiddenKeyPatternArray.length != hiddenKeyPatternIntentArray.length
88           || (hiddenKeySequenceArray.length == 0 && hiddenKeyPatternArray.length == 0)) {
89         LogUtil.e(
90             "MotorolaHiddenMenuKeySequence",
91             "the key sequence array is not matching, turn off feature."
92                 + "key sequence: %d != %d, key pattern %d != %d",
93             hiddenKeySequenceArray.length,
94             hiddenKeySequenceIntentArray.length,
95             hiddenKeyPatternArray.length,
96             hiddenKeyPatternIntentArray.length);
97         featureHiddenMenuEnabled = false;
98       }
99     }
100   }
101 
handleKeyPattern(Context context, String input)102   private static boolean handleKeyPattern(Context context, String input) {
103     int len = input.length();
104     if (len <= 3 || hiddenKeyPatternArray == null || hiddenKeyPatternIntentArray == null) {
105       return false;
106     }
107 
108     for (int i = 0; i < hiddenKeyPatternArray.length; i++) {
109       if ((Pattern.compile(hiddenKeyPatternArray[i])).matcher(input).matches()) {
110         return sendIntent(context, input, hiddenKeyPatternIntentArray[i]);
111       }
112     }
113     return false;
114   }
115 
handleKeySequence(Context context, String input)116   private static boolean handleKeySequence(Context context, String input) {
117     int len = input.length();
118     if (len <= 3 || hiddenKeySequenceArray == null || hiddenKeySequenceIntentArray == null) {
119       return false;
120     }
121 
122     for (int i = 0; i < hiddenKeySequenceArray.length; i++) {
123       if (hiddenKeySequenceArray[i].equals(input)) {
124         return sendIntent(context, input, hiddenKeySequenceIntentArray[i]);
125       }
126     }
127     return false;
128   }
129 
sendIntent( final Context context, final String input, final String action)130   private static boolean sendIntent(
131       final Context context, final String input, final String action) {
132     LogUtil.d("MotorolaHiddenMenuKeySequence.sendIntent", "input: %s", input);
133     try {
134       Intent intent = new Intent(action);
135       intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
136       intent.putExtra(EXTRA_HIDDEN_MENU_CODE, input);
137 
138       ResolveInfo resolveInfo = context.getPackageManager().resolveActivity(intent, 0);
139 
140       if (resolveInfo != null
141           && resolveInfo.activityInfo != null
142           && resolveInfo.activityInfo.enabled) {
143         context.startActivity(intent);
144         return true;
145       } else {
146         LogUtil.w("MotorolaHiddenMenuKeySequence.sendIntent", "not able to resolve the intent");
147       }
148     } catch (ActivityNotFoundException e) {
149       LogUtil.e(
150           "MotorolaHiddenMenuKeySequence.sendIntent", "handleHiddenMenu Key Pattern Exception", e);
151     }
152     return false;
153   }
154 }
155