aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPreeti Ahuja <preetia@codeaurora.org>2014-02-26 14:09:35 +0530
committerLinux Build Service Account <lnxbuild@localhost>2016-08-24 08:12:24 -0600
commit4f656cd99673cee1f9a8f280dff9da414baec6ae (patch)
tree0126568e098d059803bdf1736ad444706d786f5e
parent74fa06f65f4680fb5ca26cd3f0a9936d19ec4ee4 (diff)
downloadandroid_frameworks_opt_telephony-4f656cd99673cee1f9a8f280dff9da414baec6ae.tar.gz
android_frameworks_opt_telephony-4f656cd99673cee1f9a8f280dff9da414baec6ae.tar.bz2
android_frameworks_opt_telephony-4f656cd99673cee1f9a8f280dff9da414baec6ae.zip
Cat: Add support for Activate cmd and HCI connectivity event
Add FLAG_RECEIVER_FOREGROUND to CatService broadcast intents Stk app is unable to receive broadcasts from CatService until BOOT_COMPLETED intent is received from framework. FLAG_RECEIVER_FOREGROUND flag is added to the intents sent by CatService so that Stk app can receive these broadcasts before BOOT_COMPLETED is received. Change-Id: Ica8e72e354891438dcd6b7e899a2ba78d980d396 Cat: Add support for Activate cmd and HCI connectivity event Add support for Activate proactive command defined in ETSI TS 102 223 [6.4.40] and HCI connectivity event defined in ETSI TS 102 223 [7.5.18]. CRs-Fixed: 618962 Change-Id: I3755cb275a09a346d7b0b799242c818d969f8dff
-rw-r--r--src/java/com/android/internal/telephony/cat/AppInterface.java15
-rw-r--r--src/java/com/android/internal/telephony/cat/CatCmdMessage.java2
-rw-r--r--src/java/com/android/internal/telephony/cat/CatService.java24
-rw-r--r--src/java/com/android/internal/telephony/cat/CommandDetails.java9
-rw-r--r--src/java/com/android/internal/telephony/cat/CommandParams.java10
-rwxr-xr-xsrc/java/com/android/internal/telephony/cat/CommandParamsFactory.java27
-rw-r--r--src/java/com/android/internal/telephony/cat/ComprehensionTlvTag.java3
-rw-r--r--src/java/com/android/internal/telephony/cat/ValueParser.java12
-rw-r--r--tests/telephonytests/src/com/android/internal/telephony/cat/CatServiceTest.java214
9 files changed, 312 insertions, 4 deletions
diff --git a/src/java/com/android/internal/telephony/cat/AppInterface.java b/src/java/com/android/internal/telephony/cat/AppInterface.java
index d48a82b7c..681f069f8 100644
--- a/src/java/com/android/internal/telephony/cat/AppInterface.java
+++ b/src/java/com/android/internal/telephony/cat/AppInterface.java
@@ -49,6 +49,18 @@ public interface AppInterface {
public static final String STK_PERMISSION = "android.permission.RECEIVE_STK_COMMANDS";
/*
+ * Intent action broadcasted by StkAppService when the ACTIVATE proactive command
+ * arrives.
+ */
+ public static final String CAT_ACTIVATE_NOTIFY_ACTION =
+ "org.codeaurora.intent.action.stk.activate_notify";
+ /*
+ * Intent action broadcasted by NfcService when the HCI Connectivity event occurs.
+ */
+ public static final String CAT_HCI_CONNECTIVITY_ACTION =
+ "org.codeaurora.intent.action.stk.hci_connectivity";
+
+ /*
* Callback function from app to telephony to pass a result code and user's
* input back to the ICC.
*/
@@ -81,7 +93,8 @@ public interface AppInterface {
CLOSE_CHANNEL(0x41),
RECEIVE_DATA(0x42),
SEND_DATA(0x43),
- GET_CHANNEL_STATUS(0x44);
+ GET_CHANNEL_STATUS(0x44),
+ ACTIVATE(0x70);
private int mValue;
diff --git a/src/java/com/android/internal/telephony/cat/CatCmdMessage.java b/src/java/com/android/internal/telephony/cat/CatCmdMessage.java
index ac9bb7236..e99473c21 100644
--- a/src/java/com/android/internal/telephony/cat/CatCmdMessage.java
+++ b/src/java/com/android/internal/telephony/cat/CatCmdMessage.java
@@ -68,6 +68,7 @@ public class CatCmdMessage implements Parcelable {
public static final int LANGUAGE_SELECTION_EVENT = 0x07;
public static final int BROWSER_TERMINATION_EVENT = 0x08;
public static final int BROWSING_STATUS_EVENT = 0x0F;
+ public static final int HCI_CONNECTIVITY_EVENT = 0x13;
}
public final class BrowserTerminationCauses {
@@ -126,6 +127,7 @@ public class CatCmdMessage implements Parcelable {
mSetupEventListSettings = new SetupEventListSettings();
mSetupEventListSettings.eventList = ((SetEventListParams) cmdParams).mEventInfo;
break;
+ case ACTIVATE:
case PROVIDE_LOCAL_INFORMATION:
default:
break;
diff --git a/src/java/com/android/internal/telephony/cat/CatService.java b/src/java/com/android/internal/telephony/cat/CatService.java
index 696bfce5e..c3728a78d 100644
--- a/src/java/com/android/internal/telephony/cat/CatService.java
+++ b/src/java/com/android/internal/telephony/cat/CatService.java
@@ -49,6 +49,8 @@ import static com.android.internal.telephony.cat.CatCmdMessage.
SetupEventListConstants.IDLE_SCREEN_AVAILABLE_EVENT;
import static com.android.internal.telephony.cat.CatCmdMessage.
SetupEventListConstants.LANGUAGE_SELECTION_EVENT;
+import static com.android.internal.telephony.cat.CatCmdMessage.
+ SetupEventListConstants.HCI_CONNECTIVITY_EVENT;
class RilMessage {
int mId;
@@ -341,9 +343,13 @@ public class CatService extends Handler implements AppInterface {
CatLog.d(this,"Event: " + eventVal);
switch (eventVal) {
/* Currently android is supporting only the below events in SetupEventList
- * Language Selection. */
+ * Idle Screen Available,
+ * Language Selection and
+ * HCI Connectivity.
+ */
case IDLE_SCREEN_AVAILABLE_EVENT:
case LANGUAGE_SELECTION_EVENT:
+ case HCI_CONNECTIVITY_EVENT:
break;
default:
flag = false;
@@ -499,6 +505,13 @@ public class CatService extends Handler implements AppInterface {
sendTerminalResponse(cmdParams.mCmdDet, ResultCode.OK, false, 0, null);
}
break;
+ case ACTIVATE:
+ // TO DO: Retrieve the target of the ACTIVATE cmd from the cmd.
+ // Target : '01' = UICC-CFL interface according to TS 102 613 [39];
+ // '00' and '02' to 'FF' = RFU (Reserved for Future Use).
+ resultCode = ResultCode.OK;
+ sendTerminalResponse(cmdParams.mCmdDet, resultCode, false, 0 ,null);
+ break;
default:
CatLog.d(this, "Unsupported command");
return;
@@ -527,6 +540,7 @@ public class CatService extends Handler implements AppInterface {
mCurrntCmd = mMenuCmd;
Intent intent = new Intent(AppInterface.CAT_SESSION_END_ACTION);
intent.putExtra("SLOT_ID", mSlotId);
+ intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
mContext.sendBroadcast(intent, AppInterface.STK_PERMISSION);
}
@@ -726,7 +740,9 @@ public class CatService extends Handler implements AppInterface {
/*
* Currently the below events are supported:
- * Language Selection Event.
+ * Idle Screen Available,
+ * Language Selection Event and
+ * HCI Connectivity.
* Other event download commands should be encoded similar way
*/
/* TODO: eventDownload should be extended for other Envelope Commands */
@@ -741,6 +757,9 @@ public class CatService extends Handler implements AppInterface {
// Language length should be 2 byte
buf.write(0x02);
break;
+ case HCI_CONNECTIVITY_EVENT:
+ CatLog.d(this, " Sending HCI Connectivity event download to ICC");
+ break;
default:
break;
}
@@ -867,6 +886,7 @@ public class CatService extends Handler implements AppInterface {
private void broadcastCardStateAndIccRefreshResp(CardState cardState,
IccRefreshResponse iccRefreshState) {
Intent intent = new Intent(AppInterface.CAT_ICC_STATUS_CHANGE);
+ intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
boolean cardPresent = (cardState == CardState.CARDSTATE_PRESENT);
if (iccRefreshState != null) {
diff --git a/src/java/com/android/internal/telephony/cat/CommandDetails.java b/src/java/com/android/internal/telephony/cat/CommandDetails.java
index aaa9d6839..64ba7f51f 100644
--- a/src/java/com/android/internal/telephony/cat/CommandDetails.java
+++ b/src/java/com/android/internal/telephony/cat/CommandDetails.java
@@ -121,3 +121,12 @@ class ItemsIconId extends ValueObject {
return ComprehensionTlvTag.ITEM_ICON_ID_LIST;
}
}
+
+class ActivateDescriptor extends ValueObject {
+ public int target;
+
+ @Override
+ ComprehensionTlvTag getTag() {
+ return ComprehensionTlvTag.ACTIVATE_DESCRIPTOR;
+ }
+}
diff --git a/src/java/com/android/internal/telephony/cat/CommandParams.java b/src/java/com/android/internal/telephony/cat/CommandParams.java
index 7dfedab8f..edb377211 100644
--- a/src/java/com/android/internal/telephony/cat/CommandParams.java
+++ b/src/java/com/android/internal/telephony/cat/CommandParams.java
@@ -224,3 +224,13 @@ class BIPClientParams extends CommandParams {
return false;
}
}
+class ActivateParams extends CommandParams {
+ int mActivateTarget;
+
+
+ ActivateParams(CommandDetails cmdDet, int target) {
+ super(cmdDet);
+ mActivateTarget = target;
+ }
+}
+
diff --git a/src/java/com/android/internal/telephony/cat/CommandParamsFactory.java b/src/java/com/android/internal/telephony/cat/CommandParamsFactory.java
index f220dd823..d2ba2d6e6 100755
--- a/src/java/com/android/internal/telephony/cat/CommandParamsFactory.java
+++ b/src/java/com/android/internal/telephony/cat/CommandParamsFactory.java
@@ -35,6 +35,8 @@ import static com.android.internal.telephony.cat.CatCmdMessage.
SetupEventListConstants.BROWSER_TERMINATION_EVENT;
import static com.android.internal.telephony.cat.CatCmdMessage.
SetupEventListConstants.BROWSING_STATUS_EVENT;
+import static com.android.internal.telephony.cat.CatCmdMessage.
+ SetupEventListConstants.HCI_CONNECTIVITY_EVENT;
/**
* Factory class, used for decoding raw byte arrays, received from baseband,
* into a CommandParams object.
@@ -202,6 +204,9 @@ class CommandParamsFactory extends Handler {
case SEND_DATA:
cmdPending = processBIPClient(cmdDet, ctlvs);
break;
+ case ACTIVATE:
+ cmdPending = processActivate(cmdDet, ctlvs);
+ break;
default:
// unsupported proactive commands
mCmdParams = new CommandParams(cmdDet);
@@ -730,6 +735,7 @@ class CommandParamsFactory extends Handler {
case LANGUAGE_SELECTION_EVENT:
case BROWSER_TERMINATION_EVENT:
case BROWSING_STATUS_EVENT:
+ case HCI_CONNECTIVITY_EVENT:
eventList[i] = eventValue;
i++;
break;
@@ -1010,6 +1016,27 @@ class CommandParamsFactory extends Handler {
return false;
}
+ private boolean processActivate(CommandDetails cmdDet,
+ List<ComprehensionTlv> ctlvs) throws ResultException {
+ AppInterface.CommandType commandType =
+ AppInterface.CommandType.fromInt(cmdDet.typeOfCommand);
+ CatLog.d(this, "process " + commandType.name());
+
+ ComprehensionTlv ctlv = null;
+ int target;
+
+ //parse activate descriptor
+ ctlv = searchForTag(ComprehensionTlvTag.ACTIVATE_DESCRIPTOR, ctlvs);
+ if (ctlv != null) {
+ target = ValueParser.retrieveTarget(ctlv);
+ mCmdParams = new CommandParams(cmdDet);
+ CatLog.d(this, "Activate cmd target = " + target);
+ } else {
+ CatLog.d(this, "ctlv is null");
+ }
+ return false;
+ }
+
public void dispose() {
mIconLoader.dispose();
mIconLoader = null;
diff --git a/src/java/com/android/internal/telephony/cat/ComprehensionTlvTag.java b/src/java/com/android/internal/telephony/cat/ComprehensionTlvTag.java
index 973dbc813..9e31c27c7 100644
--- a/src/java/com/android/internal/telephony/cat/ComprehensionTlvTag.java
+++ b/src/java/com/android/internal/telephony/cat/ComprehensionTlvTag.java
@@ -46,7 +46,8 @@ public enum ComprehensionTlvTag {
LANGUAGE(0x2d),
URL(0x31),
BROWSER_TERMINATION_CAUSE(0x34),
- TEXT_ATTRIBUTE(0x50);
+ TEXT_ATTRIBUTE(0x50),
+ ACTIVATE_DESCRIPTOR(0x7b);
private int mValue;
diff --git a/src/java/com/android/internal/telephony/cat/ValueParser.java b/src/java/com/android/internal/telephony/cat/ValueParser.java
index 91a6fd6fe..c6b16c783 100644
--- a/src/java/com/android/internal/telephony/cat/ValueParser.java
+++ b/src/java/com/android/internal/telephony/cat/ValueParser.java
@@ -354,4 +354,16 @@ abstract class ValueParser {
throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
}
}
+
+ static int retrieveTarget(ComprehensionTlv ctlv) throws ResultException {
+ ActivateDescriptor activateDesc = new ActivateDescriptor();
+ byte[] rawValue = ctlv.getRawValue();
+ int valueIndex = ctlv.getValueIndex();
+ try {
+ activateDesc.target = rawValue[valueIndex] & 0xff;
+ return activateDesc.target;
+ } catch (IndexOutOfBoundsException e) {
+ throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING);
+ }
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/cat/CatServiceTest.java b/tests/telephonytests/src/com/android/internal/telephony/cat/CatServiceTest.java
new file mode 100644
index 000000000..b378e6e3c
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/cat/CatServiceTest.java
@@ -0,0 +1,214 @@
+/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package com.android.internal.telephony;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.HandlerThread;
+import android.telephony.TelephonyManager;
+import android.test.suitebuilder.annotation.SmallTest;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import com.android.internal.telephony.cat.*;
+import com.android.internal.telephony.TelephonyTestUtils;
+import com.android.internal.telephony.uicc.IccFileHandler;
+import com.android.internal.telephony.uicc.UiccCard;
+
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+import java.lang.reflect.Method;
+import junit.framework.Assert;
+
+public class CatServiceTest extends TelephonyTest {
+
+ private static final int SINGLE_SIM = 1;
+
+ private TelephonyManager mTelephonyManager;
+ private CatService mCatService;
+
+ @Mock
+ private UiccCard mMockUiccCard;
+
+ @Mock
+ private IccFileHandler mIccFileHandler;
+
+
+ /* CatService extends handler and to instantiate the object within this test,
+ * we will need a looper to be ready. The HandlerThread here is used for this. The .start()
+ * is invoked in the setUp() call and the CatService is initialized in the
+ * onLooperPrepared() callback.
+ *
+ * This will not be required if the class under test is not extending Handler
+ */
+ private class CatServiceTestHandler extends HandlerThread {
+
+ private CatServiceTestHandler(String name) {
+ super(name);
+ }
+
+ @Override
+ public void onLooperPrepared() {
+ mCatService = CatService.getInstance(
+ mSimulatedCommands, mContext, mMockUiccCard, 0);
+ setReady(true);
+ }
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp(this.getClass().getSimpleName());
+
+ mTelephonyManager = (TelephonyManager) mContext.getSystemService(
+ Context.TELEPHONY_SERVICE);
+
+ /* These are preconditions for the tests, all the APIs that the Class Under Test
+ * will invoke, has to be setup here using dummy values
+ */
+ doReturn(SINGLE_SIM).when(mTelephonyManager).getSimCount();
+ doReturn(SINGLE_SIM).when(mTelephonyManager).getPhoneCount();
+
+ /* Some of the objects are already provided by the base class and a subset of it
+ * which is required for the CatService test will be used as dummy responses
+ * when the Class Under Test will invoke it in its constructor or in the methods
+ * under test
+ */
+ doReturn(mUiccCardApplication3gpp).when(mMockUiccCard).getApplicationIndex(0);
+ doReturn(mIccFileHandler).when(mUiccCardApplication3gpp).getIccFileHandler();
+ doReturn(mSimRecords).when(mUiccCardApplication3gpp).getIccRecords();
+
+ /* Kick off the handler thread, which leads to instantiation of the CatService object */
+ new CatServiceTestHandler(TAG).start();
+ waitUntilReady();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ mTelephonyManager = null;
+ mCatService.dispose();
+ }
+
+ @Test @SmallTest
+ public void isSupportedSetupEventCommand() {
+ assertNotNull(mCatService);
+
+ /* Create a mock object to be sent to method under test */
+ CatCmdMessage mockCatMsg = mock(CatCmdMessage.class);
+
+ /* Create a real object that will returned when getSetEventList() is invoked
+ * on the mock object
+ */
+ CatCmdMessage.SetupEventListSettings eventListSettings =
+ mockCatMsg.new SetupEventListSettings();
+
+ /* Define the mock behavior for getSetEventList(), to return the real object created */
+ Mockito.when(mockCatMsg.getSetEventList()).thenReturn(eventListSettings);
+
+ eventListSettings.eventList =
+ new int[]{CatCmdMessage.SetupEventListConstants.LANGUAGE_SELECTION_EVENT};
+ assertEquals(true, callIsSupportedSetupEventCommand(mockCatMsg));
+
+ eventListSettings.eventList =
+ new int[]{CatCmdMessage.SetupEventListConstants.HCI_CONNECTIVITY_EVENT};
+ assertEquals(true, callIsSupportedSetupEventCommand(mockCatMsg));
+ }
+
+ /* Wrapper function that uses reflection to invoke private methods */
+ private boolean callIsSupportedSetupEventCommand(CatCmdMessage mockCatMsg) {
+ Class clsParams[] = new Class[1];
+ clsParams[0] = CatCmdMessage.class;
+
+ Object params[] = new Object[1];
+ params[0] = mockCatMsg;
+
+ return (boolean)invokeNonStaticMethod(CatService.class, mCatService,
+ "isSupportedSetupEventCommand", clsParams, params);
+ }
+
+ /* In this test the method under test creates an intent,
+ * sets a flag and broadcasts it, this test ensures the flag is set
+ */
+ @Test
+ public void broadcastCatCmdIntent() {
+ CatCmdMessage mockCatMsg = mock(CatCmdMessage.class);
+
+ Class clsParams[] = new Class[1];
+ clsParams[0] = CatCmdMessage.class;
+
+ Object params[] = new Object[1];
+ params[0] = mockCatMsg;
+
+ /* broadcastCatCmdIntent method will get tested and 'sendBroadcast' would get invoked */
+ invokeNonStaticMethod(CatService.class, mCatService,
+ "broadcastCatCmdIntent", clsParams, params);
+
+ /* Since mock Context is used, sendBroadcast method is trapped
+ * and arguments can be examined. In the example below, first argument is an
+ * intent and is captured and examined for the flag. Parameters of no interest can
+ * be left as anyInt() or anyString() based on the method signature
+ */
+ ArgumentCaptor<Intent> intentCapture = ArgumentCaptor.forClass(Intent.class);
+ Mockito.verify(mContext).sendBroadcast(intentCapture.capture(), Mockito.anyString());
+
+ assertEquals(
+ ((Intent)intentCapture.getValue()).getFlags() & Intent.FLAG_RECEIVER_FOREGROUND,
+ Intent.FLAG_RECEIVER_FOREGROUND);
+ }
+
+ @Test
+ public void handleSessionEnd() {
+ invokeNonStaticMethod(CatService.class, mCatService, "handleSessionEnd", null, null);
+
+ ArgumentCaptor<Intent> intentCapture = ArgumentCaptor.forClass(Intent.class);
+ Mockito.verify(mContext).sendBroadcast(intentCapture.capture(), Mockito.anyString());
+
+ assertEquals(
+ ((Intent)intentCapture.getValue()).getFlags() & Intent.FLAG_RECEIVER_FOREGROUND,
+ Intent.FLAG_RECEIVER_FOREGROUND);
+ }
+
+ private Object invokeNonStaticMethod(Class clazz, Object caller, String method,
+ Class[] clsParams, Object[] params) {
+ try {
+ Method methodReflection = clazz.getDeclaredMethod(method, clsParams);
+ methodReflection.setAccessible(true);
+ return methodReflection.invoke(caller, params);
+ } catch (Exception e) {
+ Assert.fail(e.toString());
+ return null;
+ }
+ }
+}