blob: 18602c9af96021f32e51b08f47c3e61f830f3f57 [file] [log] [blame]
SongFerngWang154bc962018-10-23 16:47:40 +08001/*
2 * Copyright (C) 2018 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
17package com.android.phone;
18
19import android.content.Context;
20import android.content.res.XmlResourceParser;
SongFerngWang5a0a4e12019-05-10 16:57:29 +080021import android.support.annotation.VisibleForTesting;
SongFerngWang154bc962018-10-23 16:47:40 +080022import android.telephony.TelephonyManager;
23import android.text.TextUtils;
24import android.util.Log;
25
26import org.xmlpull.v1.XmlPullParser;
27import org.xmlpull.v1.XmlPullParserException;
28
29import java.io.IOException;
30import java.util.ArrayList;
31import java.util.HashMap;
32import java.util.Map;
33import java.util.Vector;
34import java.util.regex.Matcher;
35import java.util.regex.Pattern;
36
37/**
38 * CarrierXmlParser is a xml parser. It parses the carrier's ussd format from carrier_ss_string.xml.
39 * The carrier_ss_string.xml defines carrier's ussd structure and meaning in res/xml folder.
40 * Some carrier has specific ussd structure ,developer can add new xml and xml is named
41 * carrier_ss_string_carrierId.xml. The carrierId is a number and is defined in
42 * <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/carrier_list.textpb">here</a>
43 * For example: carrier_ss_string_850.xml
44 * <p>
45 * How do use CarrierXmlParser?
46 * For example:
47 * @see CallForwardEditPreference
48 * TelephonyManager telephonyManager = new TelephonyManager(getContext(),phone.getSubId());
49 * CarrierXmlParser = new CarrierXmlParser(getContext(), telephonyManager.getSimCarrierId());
50 *
51 * //make a ussd command
52 * String newUssdCommand = mCarrierXmlParser.getFeature(
53 * CarrierXmlParser.FEATURE_CALL_FORWARDING).makeCommand(inputAction, inputCfInfo);
54 * //analyze ussd result
55 * HashMap<String, String> analysisResult = mCarrierXmlParser.getFeature(
56 * CarrierXmlParser.FEATURE_CALL_FORWARDING)
57 * .getResponseSet(mSsAction, response.toString());
58 */
59public class CarrierXmlParser {
60 public static final String LOG_TAG = "CarrierXmlParser";
61 private static final boolean DEBUG = true;
62
63 private static final String STAR_SIGN = "*";
64 private static final String POUND_SIGN = "#";
65
66 private static final String TAG_SIGN = "tag_";
67
68 // To define feature's item name in xml
69 public static final String FEATURE_CALL_FORWARDING = "callforwarding";
70 public static final String FEATURE_CALLER_ID = "callerid";
71
72 // COMMAND_NAME is xml's command name.
73 public static final String TAG_COMMAND_NAME_QUERY = "query";
74 public static final String TAG_COMMAND_NAME_ACTIVATE = "activate";
75 public static final String TAG_COMMAND_NAME_DEACTIVATE = "deactivate";
76
77 // To define string level in xml.
78 // level 1
79 private static final String TAG_FEATURE = "feature";
80 private static final String TAG_REGULAR_PARSER = "regular_parser";
81 // level 2
82 private static final String TAG_COMMAND = "command";
83 // level 3
84 private static final String TAG_SERVICE_CODE = "service_code";
85 private static final String TAG_ACTION_CODE = "action_code";
86 private static final String TAG_PARAMETER = "parameter";
87 private static final String TAG_RESPONSE_FORMAT = "response_format";
88 private static final String TAG_COMMAND_RESULT = "command_result";
89 // level 4
90 private static final String TAG_ENTRY = "entry";
91
92 private static final String ATTR_NAME = "name";
93 private static final String ATTR_PARAMETER_NUM = "number";
94 private static final String ATTR_POSITION = "position";
95 private static final String ATTR_RESULT_KEY = "key";
96 private static final String ATTR_DEFINITION_KEY = "definition";
97
98 HashMap<String, SsFeature> mFeatureMaps;
SongFerngWang5a0a4e12019-05-10 16:57:29 +080099
100 @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
101 static String sParserFormat = "";
SongFerngWang154bc962018-10-23 16:47:40 +0800102
103 // TAG_ENTRY_NUMBER and TAG_ENTRY_TIME is xml's entry value.
104 // This is mapping user's input value. For example: number,time ...
105 // When UI makes command ,it will map the value and insert this value at position location.
106 // How to use it?
107 // The UI calls CarrierXmlParser's makeCommand function and inputs the hashmap which
108 // includes tag_name and user's input value.
109 // For example: User calls CarrierXmlParser's makeCommand in call forwarding , and inputs
110 // the hashmap {<TAG_ENTRY_NUMBER,0123456789>,<TAG_ENTRY_TIME,20>}
111 // If developer wants to add new one, xml string should the same as hashmap's name.
112 public static final String TAG_ENTRY_NUMBER = "tag_number";
113 public static final String TAG_ENTRY_TIME = "tag_time";
114
115 // "response_format" key
116 // The key of "response_format" should define as below in xml.
117 // The UI will use it to define value from the response command
118 // and use the data show the screen.
119 public static final String TAG_RESPONSE_STATUS = "status_code";
120 public static final String TAG_RESPONSE_STATUS_ERROR = "RESPONSE_ERROR";
121 public static final String TAG_RESPONSE_NUMBER = "number";
122 public static final String TAG_RESPONSE_TIME = "time";
123
124 // This is the definition for the entry's key in response_format.
125 // Xml's COMMAND_RESULT_DEFINITION should same as below.
126 public static final String TAG_COMMAND_RESULT_DEFINITION_ACTIVATE = "activate";
127 public static final String TAG_COMMAND_RESULT_DEFINITION_DEACTIVATE = "deactivate";
128 public static final String TAG_COMMAND_RESULT_DEFINITION_UNREGISTER = "unregister";
129 public static final String TAG_COMMAND_RESULT_DEFINITION_OK = "ok";
130 public static final String TAG_COMMAND_RESULT_DEFINITION_FAIL = "fail";
131
132 /**
133 * UssdParser is a string parser. It parses the USSD response message.
134 */
135 public static class UssdParser {
136 private Vector<String> mParserStr = new Vector<String>();
137 private Pattern mPatternSuppServiceResponse;
138
139 public UssdParser(String inputParserFormat) {
140 mPatternSuppServiceResponse = Pattern.compile(inputParserFormat);
141 }
142
143 /**
144 * This function is a parser and analyzes the USSD responses message.
145 *
146 * @param responseString The USSD responses message.
147 */
148 public void newFromResponseString(String responseString) {
149 Matcher m;
150 m = mPatternSuppServiceResponse.matcher(responseString);
151 if (m.matches()) {
152 mParserStr.clear();
153 int groupSize = m.groupCount();
154 for (int i = 0; i <= groupSize; i++) {
155 if (!TextUtils.isEmpty(m.group(i))) {
156 mParserStr.add(m.group(i));
SongFerngWang45c6ad52018-11-29 17:29:05 +0800157 } else {
158 mParserStr.add("");
SongFerngWang154bc962018-10-23 16:47:40 +0800159 }
160 }
SongFerngWang5a0a4e12019-05-10 16:57:29 +0800161 } else {
162 Log.d(LOG_TAG, "no match");
SongFerngWang154bc962018-10-23 16:47:40 +0800163 }
164 }
165
166 /**
167 * To get the UssdParser result.
168 */
169 public Vector<String> getResult() {
170 return mParserStr;
171 }
172 }
173
174 /**
175 * CarrierXmlParser parses command from xml and saves in SsEntry class.
176 */
177 public static class SsEntry {
178 public enum SSAction {
179 UNKNOWN,
180 QUERY,
181 UPDATE_ACTIVATE,
182 UPDATE_DEACTIVATE
183 }
184
185 public String serviceCode;
186 public SSAction ssAction = SSAction.UNKNOWN;
187 public String actionCode;
188 public HashMap<Integer, String> commandParameter = new HashMap<Integer, String>();
189 public HashMap<Integer, String> responseFormat = new HashMap<Integer, String>();
190
191 public SsEntry(String action) {
192 if (action.equals(TAG_COMMAND_NAME_QUERY)) {
193 ssAction = SSAction.QUERY;
194 } else if (action.equals(TAG_COMMAND_NAME_ACTIVATE)) {
195 ssAction = SSAction.UPDATE_ACTIVATE;
196 } else if (action.equals(TAG_COMMAND_NAME_DEACTIVATE)) {
197 ssAction = SSAction.UPDATE_DEACTIVATE;
198 }
199 }
200
201 @Override
202 public String toString() {
203 return "SsEntry serviceCode:" + serviceCode
204 + ", ssAction:" + ssAction
205 + ", actionCode:" + actionCode
206 + ", commandParameter:" + commandParameter.toString()
207 + ", responseFormat:" + responseFormat.toString();
208 }
209
210 /**
211 * To get the caller id command by xml's structure.
212 */
213 public String getCommandStructure() {
214 String result = actionCode + serviceCode;
215 int mapSize = commandParameter.size();
216 int parameterIndex = 0;
217 while (parameterIndex < mapSize) {
218 parameterIndex++;
219 if (commandParameter.containsKey(parameterIndex)) {
220 if (commandParameter.get(parameterIndex) != null) {
221 result = result + STAR_SIGN + commandParameter.get(parameterIndex);
222 }
223 }
224 }
225 result = result + POUND_SIGN;
226 Log.d(LOG_TAG, "getCommandStructure result:" + result);
227 return result;
228 }
229
230 /**
231 * To make ussd command by xml's structure.
232 *
233 * @param inputInformationSet This is a map which includes parameters from UI.
234 * The name of map is mapping parameter's key of entry in xml.
235 */
236 public String makeCommand(Map<String, String> inputInformationSet) {
237 String result = actionCode + serviceCode;
238 int mapSize = commandParameter.size();
239 int parameterIndex = 0;
240 int counter = 1;
241 Map<String, String> informationSet = inputInformationSet;
242 while (parameterIndex < mapSize) {
243 if (commandParameter.containsKey(counter)) {
244 String getInputValue = "";
245 // need to handle tag_XXXX
246 if (informationSet != null && informationSet.size() > 0
247 && informationSet.containsKey(commandParameter.get(counter))) {
248 getInputValue = informationSet.get(commandParameter.get(counter));
249 }
250 if (TextUtils.isEmpty(getInputValue)) {
251 result = result + STAR_SIGN + commandParameter.get(counter);
252 } else {
253 result = result + STAR_SIGN + informationSet.get(
254 commandParameter.get(counter));
255 }
256 parameterIndex++;
257 } else {
258 result = result + STAR_SIGN;
259 }
260 counter++;
261 }
262 result = result + POUND_SIGN;
263 return result;
264 }
265
266 /**
267 * To parse the specific key and value from response message.
268 *
269 * @param inputResponse This is a ussd response message from network.
270 * @param responseDefine This is the definition for "command_result" in xml.
271 */
272 public HashMap<String, String> getResponseSet(String inputResponse,
273 HashMap<String, ArrayList<SsResultEntry>> responseDefine) {
274 HashMap<String, String> responseSet = new HashMap<String, String>();
275 if (TextUtils.isEmpty(sParserFormat)) {
276 return responseSet;
277 }
278 UssdParser parserResult = new UssdParser(sParserFormat);
279 parserResult.newFromResponseString(inputResponse);
280 if (parserResult == null) {
281 return responseSet;
282 }
283
284 Vector<String> result = parserResult.getResult();
285
286 if (result == null) {
287 return responseSet;
288 }
289 for (int i = 0; i < result.size(); i++) {
290 if (responseFormat.containsKey(i)) {
291 String defineString = "";
292 if (responseDefine.containsKey(responseFormat.get(i))) {
293 for (int x = 0; x < responseDefine.get(responseFormat.get(i)).size(); x++) {
294 defineString = ((SsResultEntry) responseDefine.get(
295 responseFormat.get(i)).get(x)).getDefinitionByCompareValue(
296 result.get(i));
297 if (!TextUtils.isEmpty(defineString)) {
298 break;
299 }
300 }
301 // if status_code do not match definition value, we will set command error.
302 if (TAG_RESPONSE_STATUS.equals(responseFormat.get(i))) {
303 if (TextUtils.isEmpty(defineString)) {
304 responseSet.put(TAG_RESPONSE_STATUS_ERROR,
305 TAG_RESPONSE_STATUS_ERROR);
306 }
307 }
308 }
309 if (TextUtils.isEmpty(defineString)) {
310 responseSet.put(responseFormat.get(i), result.get(i));
311 } else {
312 responseSet.put(responseFormat.get(i), defineString);
313 }
314 }
315 }
316 return responseSet;
317 }
318 }
319
320 /**
321 * CarrierXmlParser parses command_result from xml and saves in SsResultEntry class.
322 */
323 public static class SsResultEntry {
324 String mDefinition;
325 String mCompareValue;
326
327 public SsResultEntry() {
328 }
329
330 @Override
331 public String toString() {
332 return "SsResultEntry mDefinition:" + mDefinition
333 + ", mCompareValue:" + mCompareValue;
334 }
335
336 /**
337 * If mCompareValue item is the same as compare value,it will return the mDefinition.
338 *
339 * @param inputValue This is the entry of response command's value.
340 * @return mDefinition or null.
341 */
342 public String getDefinitionByCompareValue(String inputValue) {
343 if (mCompareValue.equals(inputValue)) {
344 return mDefinition;
345 }
346 return null;
347 }
348 }
349
350 /**
351 * CarrierXmlParser parses feature from xml and saves in SsFeature class.
352 */
353 public class SsFeature {
354 public HashMap<SsEntry.SSAction, SsEntry> ssEntryHashMap =
355 new HashMap<SsEntry.SSAction, SsEntry>();
356 public HashMap<String, ArrayList<SsResultEntry>> responseCode =
357 new HashMap<String, ArrayList<SsResultEntry>>();
358
359 public SsFeature() {
360 }
361
362 private String getResponseCodeString() {
363 String result = "";
364 for (Map.Entry<String, ArrayList<SsResultEntry>> entry : responseCode.entrySet()) {
365 ArrayList<SsResultEntry> values = entry.getValue();
366 for (int i = 0; i < values.size(); i++) {
367 result += "value of i is " + ((SsResultEntry) values.get(i)).toString();
368 }
369 }
370 return result;
371 }
372
373 @Override
374 public String toString() {
375 return getResponseCodeString();
376 }
377
378 /**
379 * To get the caller id command by xml's structure.
380 *
381 * @param inputAction This is action_code of command item from xml.
382 */
383 public String getCommandStructure(SsEntry.SSAction inputAction) {
384 SsEntry entry = ssEntryHashMap.get(inputAction);
385 return entry.getCommandStructure();
386 }
387
388 /**
389 * To make the ussd command by xml structure
390 *
391 * @param inputAction This is action_code of command item from xml.
392 * @param inputInformationSet This is for parameter of command.
393 * @return The ussd command string.
394 */
395 public String makeCommand(SsEntry.SSAction inputAction,
396 Map<String, String> inputInformationSet) {
397 SsEntry entry = ssEntryHashMap.get(inputAction);
398 return entry.makeCommand(inputInformationSet);
399 }
400
401 /**
402 * To parse the special key and value from response message.
403 *
404 * @param inputAction This is action_code of command item from xml.
405 * @param inputResponse This is response message from network.
406 * @return The set includes specific key and value.
407 */
408 public HashMap<String, String> getResponseSet(SsEntry.SSAction inputAction,
409 String inputResponse) {
410 SsEntry entry = ssEntryHashMap.get(inputAction);
411 return entry.getResponseSet(inputResponse, responseCode);
412 }
413 }
414
415 /**
416 * @param context context to get res's xml
417 * @param carrierId carrier id of the current subscription. The carrier ID is an Android
418 * platform-wide identifier for a carrier. AOSP maintains carrier ID assignments in
419 * <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/carrier_list.textpb">here</a>
420 */
421 public CarrierXmlParser(Context context, int carrierId) {
422 try {
423 int xmlResId = 0;
424 if (carrierId != TelephonyManager.UNKNOWN_CARRIER_ID) {
425 String xmlResIdName = "carrier_ss_string" + "_" + carrierId;
426 xmlResId = context.getResources().getIdentifier(xmlResIdName, "xml",
427 context.getPackageName());
428 }
429 if (xmlResId == 0) {
430 xmlResId = R.xml.carrier_ss_string;
431 }
432 Log.d(LOG_TAG, "carrierId: " + carrierId);
433
434 XmlResourceParser parser = context.getResources().getXml(xmlResId);
435 mFeatureMaps = parseXml(parser);
436 } catch (Exception e) {
437 Log.d(LOG_TAG, "Error parsing XML " + e.toString());
438 }
439 }
440
441 private HashMap<String, SsFeature> parseXml(XmlResourceParser parser) throws IOException {
442 HashMap<String, SsFeature> features = new HashMap<String, SsFeature>();
443 try {
444 int eventType = parser.getEventType();
445 while (eventType != XmlPullParser.END_DOCUMENT) {
446 if (eventType == XmlPullParser.START_TAG) {
447 if (TAG_REGULAR_PARSER.equals(parser.getName())) {
448 sParserFormat = readText(parser);
449 Log.d(LOG_TAG, "sParserFormat " + sParserFormat);
450 } else if (TAG_FEATURE.equals(parser.getName())) {
451 String featureName = getSpecificAttributeValue(parser, ATTR_NAME);
452 if (!TextUtils.isEmpty(featureName)) {
453 SsFeature feature = generateFeatureList(parser);
454 features.put(featureName, feature);
455 Log.d(LOG_TAG, "add " + featureName + " to map:" + feature.toString());
456 }
457 }
458 }
459 parser.next();
460 eventType = parser.getEventType();
461 }
462 } catch (XmlPullParserException e) {
463 e.printStackTrace();
464 }
465 return features;
466 }
467
468 private SsFeature generateFeatureList(XmlResourceParser parser)
469 throws XmlPullParserException, IOException {
470 SsFeature ssfeature = new SsFeature();
471 int outerDepth = parser.getDepth();
472
473 Log.d(LOG_TAG, "generateFeatureList outerDepth" + outerDepth);
474
475 while (parser.next() != XmlPullParser.END_DOCUMENT) {
476 Log.d(LOG_TAG, "generateFeatureList parser.getDepth()" + parser.getDepth());
477
478 int eventType = parser.getEventType();
479 if (eventType == XmlPullParser.END_TAG
480 && outerDepth == parser.getDepth()) {
481 break;
482 }
483
484 if (eventType != XmlPullParser.START_TAG) {
485 continue;
486 }
487 String name = parser.getName();
488 // Starts by looking for the command tag.
489 if (TAG_COMMAND.equals(name)) {
490 SsEntry entry = readCommandEntry(parser);
491 ssfeature.ssEntryHashMap.put(entry.ssAction, entry);
492 } else if (TAG_COMMAND_RESULT.equals(name)) {
493 readCommandResultEntry(parser, ssfeature);
494 }
495 }
496 return ssfeature;
497 }
498
499 private void readCommandResultEntry(XmlResourceParser parser, SsFeature ssFeature)
500 throws XmlPullParserException, IOException {
501 while (parser.next() != XmlPullParser.END_DOCUMENT) {
502 int eventType = parser.getEventType();
503 if (eventType == XmlPullParser.END_TAG
504 && TAG_COMMAND_RESULT.equals(parser.getName())) {
505 break;
506 }
507 if (eventType == XmlPullParser.START_TAG
508 && TAG_ENTRY.equals(parser.getName())) {
509 String key = getSpecificAttributeValue(parser, ATTR_RESULT_KEY);
510 if (!TextUtils.isEmpty(key)) {
511 SsResultEntry entry = new SsResultEntry();
512 entry.mDefinition = getSpecificAttributeValue(parser, ATTR_DEFINITION_KEY);
513 entry.mCompareValue = readText(parser);
514 if (ssFeature.responseCode.containsKey(key)) {
515 ssFeature.responseCode.get(key).add(entry);
516 } else {
517 ArrayList<SsResultEntry> arrayList = new ArrayList<>();
518 arrayList.add(entry);
519 ssFeature.responseCode.put(key, arrayList);
520 }
521 }
522 }
523 }
524 }
525
526 private SsEntry readCommandEntry(XmlResourceParser parser)
527 throws XmlPullParserException, IOException {
528 int outerDepth = parser.getDepth();
529 String command_action = getSpecificAttributeValue(parser, ATTR_NAME);
530 SsEntry entry = new SsEntry(command_action);
531
532 while (parser.next() != XmlPullParser.END_DOCUMENT) {
533 int eventType = parser.getEventType();
534 if (eventType == XmlPullParser.END_TAG
535 && outerDepth == parser.getDepth()) {
536 break;
537 }
538
539 if (eventType != XmlPullParser.START_TAG) {
540 continue;
541 }
542
543 String name = parser.getName();
544 if (TAG_SERVICE_CODE.equals(name)) {
545 entry.serviceCode = readText(parser);
546 } else if (TAG_ACTION_CODE.equals(name)) {
547 entry.actionCode = readText(parser);
548 } else if (TAG_PARAMETER.equals(name)) {
549 String number = getSpecificAttributeValue(parser, ATTR_PARAMETER_NUM);
550 if (!TextUtils.isEmpty(number)) {
551 readParameters(parser, entry, Integer.valueOf(number), TAG_PARAMETER);
552 }
553 } else if (TAG_RESPONSE_FORMAT.equals(name)) {
554 String number = getSpecificAttributeValue(parser, ATTR_PARAMETER_NUM);
555 if (!TextUtils.isEmpty(number)) {
556 readParameters(parser, entry, Integer.valueOf(number), TAG_RESPONSE_FORMAT);
557 }
558 }
559 }
560 Log.d(LOG_TAG, "ssEntry:" + entry.toString());
561 return entry;
562 }
563
564 private void readParameters(XmlResourceParser parser, SsEntry entry, int num, String parentTag)
565 throws IOException, XmlPullParserException {
566 Log.d(LOG_TAG, "readParameters() nume:" + num);
567 int i = 0;
568 while (i < num) {
569 if (parser.next() == XmlPullParser.START_TAG) {
570 String name = parser.getName();
571 if (TAG_ENTRY.equals(name)) {
572 String position = getSpecificAttributeValue(parser, ATTR_POSITION);
573 if (!TextUtils.isEmpty(position)) {
574 if (TAG_PARAMETER.equals(parentTag)) {
575 String value = readText(parser);
576 if (!TextUtils.isEmpty(value)) {
577 entry.commandParameter.put(Integer.valueOf(position), value);
578 }
579 } else if (TAG_RESPONSE_FORMAT.equals(parentTag)) {
580 String key = getSpecificAttributeValue(parser, ATTR_RESULT_KEY);
581 if (!TextUtils.isEmpty(key)) {
582 entry.responseFormat.put(Integer.valueOf(position), key);
583 }
584 }
585 i++;
586 }
587 }
588 }
589 }
590 }
591
592 private String getSpecificAttributeValue(XmlResourceParser parser, String attrTag) {
593 String value = "";
594 for (int i = 0; i < parser.getAttributeCount(); i++) {
595 if (attrTag.equals(parser.getAttributeName(i))) {
596 value = parser.getAttributeValue(i);
597 }
598 }
599 return value;
600 }
601
602 private String readText(XmlResourceParser parser) throws IOException, XmlPullParserException {
603 String result = "";
604 if (parser.next() == XmlPullParser.TEXT) {
605 result = parser.getText();
606 parser.nextTag();
607 }
608 return result;
609 }
610
611 /**
612 * CarrierXmlParser parses the xml and saves in mFeatureMap.
613 * To use this function get feature from the mFeatureMaps.
614 *
615 * @param inputFeatureName This is feature's name from xml.
616 */
617 public SsFeature getFeature(String inputFeatureName) {
618 return mFeatureMaps.get(inputFeatureName);
619 }
620
621 /**
622 * To check the command which is dialed by user is caller id command.
623 * <p>
624 * If it is a caller id command which sets to activate, return the {@code
625 * SsEntry.SSAction.UPDATE_ACTIVATE}.
626 * If it is a caller id command which sets to deactivate, return the {@code
627 * SsEntry.SSAction.UPDATE_DEACTIVATE}.
628 * If it is not a caller id command, return the {@code SsEntry.SSAction.UNKNOWN}.
629 *
630 * @param inputCommand This is caller id's ussd command which is dialed by user.
631 * @return {@link SsEntry.SSAction}
632 */
633 public SsEntry.SSAction getCallerIdUssdCommandAction(String inputCommand) {
634 if (isCallerIdActivate(inputCommand)) {
635 return SsEntry.SSAction.UPDATE_ACTIVATE;
636 }
637 if (isCallerIdDeactivate(inputCommand)) {
638 return SsEntry.SSAction.UPDATE_DEACTIVATE;
639 }
640 return SsEntry.SSAction.UNKNOWN;
641 }
642
643 private String getCallerIdActivateCommandFromXml() {
644 return getFeature(FEATURE_CALLER_ID).getCommandStructure(SsEntry.SSAction.UPDATE_ACTIVATE);
645 }
646
647 private String getCallerIdDeactivateCommandFromXml() {
648 return getFeature(FEATURE_CALLER_ID).getCommandStructure(
649 SsEntry.SSAction.UPDATE_DEACTIVATE);
650 }
651
652 private boolean isCallerIdActivate(String inputStr) {
653 String activateStr = getCallerIdActivateCommandFromXml();
654 return compareCommand(activateStr, inputStr);
655 }
656
657 private boolean isCallerIdDeactivate(String inputStr) {
658 String activateStr = getCallerIdDeactivateCommandFromXml();
659 return compareCommand(activateStr, inputStr);
660 }
661
662 private boolean compareCommand(String activateStr, String inputStr) {
663 String[] activateArray = activateStr.split("\\" + STAR_SIGN);
664 String[] inputArray = inputStr.split("\\" + STAR_SIGN);
665
666 if (activateArray.length == 0 || inputArray.length == 0) {
667 return false;
668 }
669 for (int i = 0; i < activateArray.length; i++) {
670 if (activateArray[i].startsWith(TAG_SIGN)) {
671 continue;
672 }
673 if (!activateArray[i].equals(inputArray[i])) {
674 Log.d(LOG_TAG, "compare fails:" + activateStr + "," + inputStr);
675 return false;
676 }
677 }
678 Log.d(LOG_TAG, "compare success");
679 return true;
680 }
681}