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