Merge "Clean up: remove jarjar rule for ArrayUtils"
diff --git a/src/java/com/android/internal/telephony/BaseCommands.java b/src/java/com/android/internal/telephony/BaseCommands.java
index 7004ef2..f0a718a 100644
--- a/src/java/com/android/internal/telephony/BaseCommands.java
+++ b/src/java/com/android/internal/telephony/BaseCommands.java
@@ -101,6 +101,7 @@
protected RegistrantList mPhysicalChannelConfigurationRegistrants = new RegistrantList();
protected RegistrantList mLceInfoRegistrants = new RegistrantList();
protected RegistrantList mEmergencyNumberListRegistrants = new RegistrantList();
+ protected RegistrantList mUiccApplicationsEnablementRegistrants = new RegistrantList();
@UnsupportedAppUsage
protected Registrant mGsmSmsRegistrant;
@@ -952,7 +953,7 @@
@Override
public void registerForModemReset(Handler h, int what, Object obj) {
- mModemResetRegistrants.add(new Registrant(h, what, obj));
+ mModemResetRegistrants.addUnique(h, what, obj);
}
@Override
@@ -962,7 +963,7 @@
@Override
public void registerForPcoData(Handler h, int what, Object obj) {
- mPcoDataRegistrants.add(new Registrant(h, what, obj));
+ mPcoDataRegistrants.addUnique(h, what, obj);
}
@Override
@@ -972,7 +973,7 @@
@Override
public void registerForCarrierInfoForImsiEncryption(Handler h, int what, Object obj) {
- mCarrierInfoForImsiEncryptionRegistrants.add(new Registrant(h, what, obj));
+ mCarrierInfoForImsiEncryptionRegistrants.addUnique(h, what, obj);
}
@Override
@@ -993,4 +994,26 @@
mNattKeepaliveStatusRegistrants.remove(h);
}
}
+
+ /**
+ * Registers the handler for RIL_UNSOL_UICC_APPLICATIONS_ENABLEMENT_CHANGED events.
+ *
+ * @param h Handler for notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ @Override
+ public void registerUiccApplicationEnablementChanged(Handler h, int what, Object obj) {
+ mUiccApplicationsEnablementRegistrants.addUnique(h, what, obj);
+ }
+
+ /**
+ * Unregisters the handler for RIL_UNSOL_UICC_APPLICATIONS_ENABLEMENT_CHANGED events.
+ *
+ * @param h Handler for notification message.
+ */
+ @Override
+ public void unregisterUiccApplicationEnablementChanged(Handler h) {
+ mUiccApplicationsEnablementRegistrants.remove(h);
+ }
}
diff --git a/src/java/com/android/internal/telephony/CommandsInterface.java b/src/java/com/android/internal/telephony/CommandsInterface.java
index 273de72..c67c675 100644
--- a/src/java/com/android/internal/telephony/CommandsInterface.java
+++ b/src/java/com/android/internal/telephony/CommandsInterface.java
@@ -656,6 +656,22 @@
void unregisterForRilConnected(Handler h);
/**
+ * Registers the handler for RIL_UNSOL_SIM_DETACH_FROM_NETWORK_CONFIG_CHANGED events.
+ *
+ * @param h Handler for notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ default void registerUiccApplicationEnablementChanged(Handler h, int what, Object obj) {};
+
+ /**
+ * Unregisters the handler for RIL_UNSOL_SIM_DETACH_FROM_NETWORK_CONFIG_CHANGED events.
+ *
+ * @param h Handler for notification message.
+ */
+ default void unregisterUiccApplicationEnablementChanged(Handler h) {};
+
+ /**
* Supply the ICC PIN to the ICC card
*
* returned message
@@ -2393,6 +2409,28 @@
*/
default void getModemStatus(Message result) {};
+ /**
+ * Enable or disable uicc applications on the SIM.
+ *
+ * @param enable enable or disable UiccApplications on the SIM.
+ * @param onCompleteMessage a Message to return to the requester
+ */
+ default void enableUiccApplications(boolean enable, Message onCompleteMessage) {}
+
+ /**
+ * Whether uicc applications are enabled or not.
+ *
+ * @param onCompleteMessage a Message to return to the requester
+ */
+ default void areUiccApplicationsEnabled(Message onCompleteMessage) {}
+
+ /**
+ * Whether {@link #enableUiccApplications} is supported, based on IRadio version.
+ */
+ default boolean canToggleUiccApplicationsEnablement() {
+ return false;
+ }
+
default List<ClientRequestStats> getClientRequestStats() {
return null;
}
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index 898f7b9..8405e5f 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -88,6 +88,7 @@
import com.android.internal.telephony.gsm.SuppServiceNotification;
import com.android.internal.telephony.test.SimulatedRadioControl;
import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
+import com.android.internal.telephony.uicc.IccCardStatus;
import com.android.internal.telephony.uicc.IccException;
import com.android.internal.telephony.uicc.IccRecords;
import com.android.internal.telephony.uicc.IccVmNotSupportedException;
@@ -152,6 +153,7 @@
private String mMeid;
// string to define how the carrier specifies its own ota sp number
private String mCarrierOtaSpNumSchema;
+ private boolean mUiccApplicationsEnabled = true;
// A runnable which is used to automatically exit from Ecm after a period of time.
private Runnable mExitEcmRunnable = new Runnable() {
@@ -324,6 +326,8 @@
mCi.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
mCi.registerForOn(this, EVENT_RADIO_ON, null);
mCi.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
+ mCi.registerUiccApplicationEnablementChanged(this, EVENT_UICC_APPS_ENABLEMENT_CHANGED,
+ null);
mCi.setOnSuppServiceNotification(this, EVENT_SSN, null);
//GSM
@@ -2404,6 +2408,8 @@
mCi.getDeviceIdentity(obtainMessage(EVENT_GET_DEVICE_IDENTITY_DONE));
mCi.getRadioCapability(obtainMessage(EVENT_GET_RADIO_CAPABILITY));
+ mCi.areUiccApplicationsEnabled(obtainMessage(EVENT_GET_UICC_APPS_ENABLEMENT_DONE));
+
startLceAfterRadioIsAvailable();
}
@@ -2843,6 +2849,18 @@
onComplete.sendToTarget();
}
break;
+ case EVENT_GET_UICC_APPS_ENABLEMENT_DONE:
+ case EVENT_UICC_APPS_ENABLEMENT_CHANGED: {
+ ar = (AsyncResult) msg.obj;
+ if (ar == null) return;
+ if (ar.exception != null) {
+ logd("Received exception on event" + msg.what + " : " + ar.exception);
+ return;
+ }
+
+ mUiccApplicationsEnabled = (boolean) ar.result;
+ break;
+ }
default:
super.handleMessage(msg);
}
@@ -4036,4 +4054,30 @@
Settings.Secure.PREFERRED_TTY_MODE, TelecomManager.TTY_MODE_OFF);
updateUiTtyMode(ttyMode);
}
+
+ // Enable or disable uicc applications.
+ @Override
+ public void enableUiccApplications(boolean enable, Message onCompleteMessage) {
+ // First check if card is present. Otherwise mUiccApplicationsDisabled doesn't make
+ // any sense.
+ UiccSlot slot = mUiccController.getUiccSlotForPhone(mPhoneId);
+ if (slot == null || slot.getCardState() != IccCardStatus.CardState.CARDSTATE_PRESENT) {
+ if (onCompleteMessage != null) {
+ AsyncResult.forMessage(onCompleteMessage, null,
+ new IllegalStateException("No SIM card is present"));
+ onCompleteMessage.sendToTarget();
+ }
+ return;
+ }
+
+ mCi.enableUiccApplications(enable, onCompleteMessage);
+ }
+
+ /**
+ * Whether disabling a physical subscription is supported or not.
+ */
+ @Override
+ public boolean canDisablePhysicalSubscription() {
+ return mCi.canToggleUiccApplicationsEnablement();
+ }
}
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index ae3b778..8184305 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -195,7 +195,9 @@
protected static final int EVENT_DEVICE_PROVISIONING_DATA_SETTING_CHANGE = 50;
protected static final int EVENT_GET_AVAILABLE_NETWORKS_DONE = 51;
- private static final int EVENT_ALL_DATA_DISCONNECTED = 52;
+ private static final int EVENT_ALL_DATA_DISCONNECTED = 52;
+ protected static final int EVENT_UICC_APPS_ENABLEMENT_CHANGED = 53;
+ protected static final int EVENT_GET_UICC_APPS_ENABLEMENT_DONE = 54;
protected static final int EVENT_LAST = EVENT_ALL_DATA_DISCONNECTED;
@@ -4076,6 +4078,20 @@
}
/**
+ * Enable or disable uicc applications.
+ * @param enable whether to enable or disable uicc applications.
+ * @param onCompleteMessage callback for async operation. Ignored if blockingCall is true.
+ */
+ public void enableUiccApplications(boolean enable, Message onCompleteMessage) {}
+
+ /**
+ * Whether disabling a physical subscription is supported or not.
+ */
+ public boolean canDisablePhysicalSubscription() {
+ return false;
+ }
+
+ /**
* Get the HAL version.
*
* @return the current HalVersion
diff --git a/src/java/com/android/internal/telephony/RIL.java b/src/java/com/android/internal/telephony/RIL.java
index f725020..695e1e7 100644
--- a/src/java/com/android/internal/telephony/RIL.java
+++ b/src/java/com/android/internal/telephony/RIL.java
@@ -4843,6 +4843,98 @@
}
/**
+ * Enable or disable uicc applications on the SIM.
+ *
+ * @param enable whether to enable or disable uicc applications.
+ * @param onCompleteMessage a Message to return to the requester
+ */
+ @Override
+ public void enableUiccApplications(boolean enable, Message onCompleteMessage) {
+ IRadio radioProxy = getRadioProxy(onCompleteMessage);
+ if (radioProxy == null) {
+ Rlog.e(RIL.RILJ_LOG_TAG, "Radio Proxy object is null!");
+ if (onCompleteMessage != null) {
+ AsyncResult.forMessage(onCompleteMessage, null,
+ CommandException.fromRilErrno(RADIO_NOT_AVAILABLE));
+ onCompleteMessage.sendToTarget();
+ }
+ }
+
+ if (mRadioVersion.less(RADIO_HAL_VERSION_1_5)) {
+ if (onCompleteMessage != null) {
+ AsyncResult.forMessage(onCompleteMessage, null,
+ CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+ onCompleteMessage.sendToTarget();
+ }
+ return;
+ }
+
+ android.hardware.radio.V1_5.IRadio radioProxy15 =
+ (android.hardware.radio.V1_5.IRadio) radioProxy;
+
+ RILRequest rr = obtainRequest(RIL_REQUEST_ENABLE_UICC_APPLICATIONS,
+ onCompleteMessage, mRILDefaultWorkSource);
+
+ if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+
+ try {
+ radioProxy15.enableUiccApplications(rr.mSerial, enable);
+ } catch (RemoteException | RuntimeException e) {
+ handleRadioProxyExceptionForRR(rr, "enableUiccApplications", e);
+ }
+ }
+
+ /**
+ * Whether uicc applications are enabled or not.
+ *
+ * @param onCompleteMessage a Message to return to the requester
+ */
+ @Override
+ public void areUiccApplicationsEnabled(Message onCompleteMessage) {
+ IRadio radioProxy = getRadioProxy(onCompleteMessage);
+ if (radioProxy == null) {
+ Rlog.e(RIL.RILJ_LOG_TAG, "Radio Proxy object is null!");
+ if (onCompleteMessage != null) {
+ AsyncResult.forMessage(onCompleteMessage, null,
+ CommandException.fromRilErrno(RADIO_NOT_AVAILABLE));
+ onCompleteMessage.sendToTarget();
+ }
+ }
+
+ if (mRadioVersion.less(RADIO_HAL_VERSION_1_5)) {
+ if (onCompleteMessage != null) {
+ AsyncResult.forMessage(onCompleteMessage, null,
+ CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+ onCompleteMessage.sendToTarget();
+ }
+ return;
+ }
+
+ android.hardware.radio.V1_5.IRadio radioProxy15 =
+ (android.hardware.radio.V1_5.IRadio) radioProxy;
+
+ RILRequest rr = obtainRequest(RIL_REQUEST_GET_UICC_APPLICATIONS_ENABLEMENT,
+ onCompleteMessage, mRILDefaultWorkSource);
+
+ if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+
+ try {
+ radioProxy15.areUiccApplicationsEnabled(rr.mSerial);
+ } catch (RemoteException | RuntimeException e) {
+ handleRadioProxyExceptionForRR(rr, "areUiccApplicationsEnabled", e);
+ }
+ }
+
+ /**
+ * Whether {@link #enableUiccApplications} is supported, which is supported in 1.5 version.
+ */
+ @Override
+ public boolean canToggleUiccApplicationsEnablement() {
+ return getRadioProxy(null) != null && mRadioVersion
+ .greaterOrEqual(RADIO_HAL_VERSION_1_5);
+ }
+
+ /**
* Translates EF_SMS status bits to a status value compatible with
* SMS AT commands. See TS 27.005 3.1.
*/
@@ -5764,6 +5856,10 @@
return "RIL_REQUEST_ENABLE_MODEM";
case RIL_REQUEST_GET_MODEM_STATUS:
return "RIL_REQUEST_GET_MODEM_STATUS";
+ case RIL_REQUEST_ENABLE_UICC_APPLICATIONS:
+ return "RIL_REQUEST_ENABLE_UICC_APPLICATIONS";
+ case RIL_REQUEST_GET_UICC_APPLICATIONS_ENABLEMENT:
+ return "RIL_REQUEST_GET_UICC_APPLICATIONS_ENABLEMENT";
default: return "<unknown request>";
}
}
@@ -5877,6 +5973,8 @@
return "RIL_UNSOL_PHYSICAL_CHANNEL_CONFIG";
case RIL_UNSOL_EMERGENCY_NUMBER_LIST:
return "RIL_UNSOL_EMERGENCY_NUMBER_LIST";
+ case RIL_UNSOL_UICC_APPLICATIONS_ENABLEMENT_CHANGED:
+ return "RIL_UNSOL_UICC_APPLICATIONS_ENABLEMENT_CHANGED";
default:
return "<unknown response>";
}
diff --git a/src/java/com/android/internal/telephony/RadioIndication.java b/src/java/com/android/internal/telephony/RadioIndication.java
index 5d00690..5b98070 100644
--- a/src/java/com/android/internal/telephony/RadioIndication.java
+++ b/src/java/com/android/internal/telephony/RadioIndication.java
@@ -63,6 +63,7 @@
import static com.android.internal.telephony.RILConstants.RIL_UNSOL_STK_PROACTIVE_COMMAND;
import static com.android.internal.telephony.RILConstants.RIL_UNSOL_STK_SESSION_END;
import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SUPP_SVC_NOTIFICATION;
+import static com.android.internal.telephony.RILConstants.RIL_UNSOL_UICC_APPLICATIONS_ENABLEMENT_CHANGED;
import static com.android.internal.telephony.RILConstants.RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED;
import static com.android.internal.telephony.RILConstants.RIL_UNSOL_VOICE_RADIO_TECH_CHANGED;
import static com.android.internal.telephony.RILConstants.RIL_UNSOl_CDMA_PRL_CHANGED;
@@ -761,6 +762,17 @@
mRil.mRilCellInfoListRegistrants.notifyRegistrants(new AsyncResult(null, response, null));
}
+ /** Get unsolicited message for uicc applications enablement changes. */
+ public void uiccApplicationsEnablementChanged(int indicationType, boolean enabled) {
+ mRil.processIndication(indicationType);
+
+ if (RIL.RILJ_LOGD) {
+ mRil.unsljLogRet(RIL_UNSOL_UICC_APPLICATIONS_ENABLEMENT_CHANGED, enabled);
+ }
+
+ mRil.mUiccApplicationsEnablementRegistrants.notifyResult(enabled);
+ }
+
/** Incremental network scan results */
public void networkScanResult(int indicationType,
android.hardware.radio.V1_1.NetworkScanResult result) {
diff --git a/src/java/com/android/internal/telephony/RadioResponse.java b/src/java/com/android/internal/telephony/RadioResponse.java
index da68b69..ea14b40 100644
--- a/src/java/com/android/internal/telephony/RadioResponse.java
+++ b/src/java/com/android/internal/telephony/RadioResponse.java
@@ -2363,4 +2363,27 @@
public void setSystemSelectionChannelsResponse(RadioResponseInfo responseInfo) {
responseVoid(responseInfo);
}
+
+ /**
+ * @param responseInfo Response info struct containing response type, serial no. and error.
+ */
+ public void enableUiccApplicationsResponse(RadioResponseInfo responseInfo) {
+ responseVoid(responseInfo);
+ }
+
+ /**
+ * @param responseInfo Response info struct containing response type, serial no. and error.
+ * @param enabled whether Uicc applications are enabled.
+ */
+ public void areUiccApplicationsEnabledResponse(RadioResponseInfo responseInfo,
+ boolean enabled) {
+ RILRequest rr = mRil.processResponse(responseInfo);
+
+ if (rr != null) {
+ if (responseInfo.error == RadioError.NONE) {
+ sendMessageResponse(rr.mResult, enabled);
+ }
+ mRil.processResponseDone(rr, responseInfo, enabled);
+ }
+ }
}
diff --git a/src/java/com/android/internal/telephony/SubscriptionController.java b/src/java/com/android/internal/telephony/SubscriptionController.java
index 08112f0..1ebea33 100644
--- a/src/java/com/android/internal/telephony/SubscriptionController.java
+++ b/src/java/com/android/internal/telephony/SubscriptionController.java
@@ -3055,12 +3055,6 @@
throw new IllegalArgumentException("Invalid groupUuid");
}
- // TODO: Revisit whether we need this restriction in R. There's no technical need for it,
- // but we don't want to change the API behavior at this time.
- if (getSubscriptionsInGroup(groupUuid, callingPackage).isEmpty()) {
- throw new IllegalArgumentException("Cannot add subscriptions to a non-existent group!");
- }
-
// Makes sure calling package matches caller UID.
mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
// If it doesn't have modify phone state permission, or carrier privilege permission,
@@ -3315,6 +3309,9 @@
"setSubscriptionEnabled not usable subId " + subId);
}
+ // Nothing to do if it's already active or inactive.
+ if (enable == isActiveSubscriptionId(subId)) return true;
+
SubscriptionInfo info = SubscriptionController.getInstance()
.getAllSubInfoList(mContext.getOpPackageName())
.stream()
@@ -3327,6 +3324,8 @@
return false;
}
+ // TODO: make sure after slot mapping, we enable the uicc applications for the
+ // subscription we are enabling.
if (info.isEmbedded()) {
return enableEmbeddedSubscription(info, enable);
} else {
@@ -3358,46 +3357,43 @@
// updateEnabledSubscriptionGlobalSetting(subId, physicalSlotIndex);
}
- private static boolean isInactiveInsertedPSim(UiccSlotInfo slotInfo, String cardId) {
- return !slotInfo.getIsEuicc() && !slotInfo.getIsActive()
- && slotInfo.getCardStateInfo() == CARD_STATE_INFO_PRESENT
- && TextUtils.equals(slotInfo.getCardId(), cardId);
- }
-
private boolean enablePhysicalSubscription(SubscriptionInfo info, boolean enable) {
- if (enable && info.getSimSlotIndex() == SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
- UiccSlotInfo[] slotsInfo = mTelephonyManager.getUiccSlotsInfo();
- if (slotsInfo == null) return false;
- boolean foundMatch = false;
- for (int i = 0; i < slotsInfo.length; i++) {
- UiccSlotInfo slotInfo = slotsInfo[i];
- if (isInactiveInsertedPSim(slotInfo, info.getCardString())) {
- // We need to send intents to Euicc if we are turning on an inactive pSIM.
- // Euicc will decide whether to ask user to switch to DSDS, or change SIM
- // slot mapping.
- enableSubscriptionOverEuiccManager(info.getSubscriptionId(), enable, i);
- foundMatch = true;
- break;
- }
- }
-
- if (!foundMatch) {
- logdl("enablePhysicalSubscription subId " + info.getSubscriptionId()
- + " is not inserted.");
- }
- // returning false to indicate state is not changed yet. If intent is sent to LPA and
- // user consents switching, caller needs to listen to subscription info change.
+ if (info == null || !SubscriptionManager.isValidSubscriptionId(info.getSubscriptionId())) {
return false;
- } else {
- return mTelephonyManager.enableModemForSlot(info.getSimSlotIndex(), enable);
}
- // TODO: uncomment or clean up if we decide whether to support standalone CBRS for Q.
- // updateEnabledSubscriptionGlobalSetting(
- // enable ? subId : SubscriptionManager.INVALID_SUBSCRIPTION_ID,
- // physicalSlotIndex);
- // updateModemStackEnabledGlobalSetting(enable, physicalSlotIndex);
- // refreshCachedActiveSubscriptionInfoList();
+ int subId = info.getSubscriptionId();
+
+ UiccSlotInfo slotInfo = null;
+ int physicalSlotIndex = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
+ UiccSlotInfo[] slotsInfo = mTelephonyManager.getUiccSlotsInfo();
+ if (slotsInfo == null) return false;
+ for (int i = 0; i < slotsInfo.length; i++) {
+ UiccSlotInfo curSlotInfo = slotsInfo[i];
+ if (curSlotInfo.getCardStateInfo() == CARD_STATE_INFO_PRESENT
+ && TextUtils.equals(curSlotInfo.getCardId(), info.getCardString())) {
+ slotInfo = curSlotInfo;
+ physicalSlotIndex = i;
+ break;
+ }
+ }
+
+ // Can't find the existing SIM.
+ if (slotInfo == null) return false;
+
+ if (enable && !slotInfo.getIsActive()) {
+ // We need to send intents to Euicc if we are turning on an inactive slot.
+ // Euicc will decide whether to ask user to switch to DSDS, or change SIM
+ // slot mapping.
+ enableSubscriptionOverEuiccManager(subId, enable, physicalSlotIndex);
+ return true;
+ } else {
+ // Enable / disable uicc applications.
+ Phone phone = PhoneFactory.getPhone(slotInfo.getLogicalSlotIdx());
+ if (phone == null) return false;
+ phone.enableUiccApplications(enable, null);
+ return true;
+ }
}
private void enableSubscriptionOverEuiccManager(int subId, boolean enable,
@@ -3776,8 +3772,8 @@
final long identity = Binder.clearCallingIdentity();
try {
- // TODO: b/133379187
- return false;
+ Phone phone = PhoneFactory.getDefaultPhone();
+ return phone != null && phone.canDisablePhysicalSubscription();
} finally {
Binder.restoreCallingIdentity(identity);
}
diff --git a/src/java/com/android/internal/telephony/cat/CatCmdMessage.java b/src/java/com/android/internal/telephony/cat/CatCmdMessage.java
index 313e56f..0033fff 100644
--- a/src/java/com/android/internal/telephony/cat/CatCmdMessage.java
+++ b/src/java/com/android/internal/telephony/cat/CatCmdMessage.java
@@ -138,10 +138,10 @@
}
public CatCmdMessage(Parcel in) {
- mCmdDet = in.readParcelable(null);
- mTextMsg = in.readParcelable(null);
- mMenu = in.readParcelable(null);
- mInput = in.readParcelable(null);
+ mCmdDet = in.readParcelable(CommandDetails.class.getClassLoader());
+ mTextMsg = in.readParcelable(TextMessage.class.getClassLoader());
+ mMenu = in.readParcelable(Menu.class.getClassLoader());
+ mInput = in.readParcelable(Input.class.getClassLoader());
mLoadIconFailed = (in.readByte() == 1);
switch (getCmdType()) {
case LAUNCH_BROWSER:
@@ -150,12 +150,12 @@
mBrowserSettings.mode = LaunchBrowserMode.values()[in.readInt()];
break;
case PLAY_TONE:
- mToneSettings = in.readParcelable(null);
+ mToneSettings = in.readParcelable(ToneSettings.class.getClassLoader());
break;
case SET_UP_CALL:
mCallSettings = new CallSettings();
- mCallSettings.confirmMsg = in.readParcelable(null);
- mCallSettings.callMsg = in.readParcelable(null);
+ mCallSettings.confirmMsg = in.readParcelable(TextMessage.class.getClassLoader());
+ mCallSettings.callMsg = in.readParcelable(TextMessage.class.getClassLoader());
break;
case SET_UP_EVENT_LIST:
mSetupEventListSettings = new SetupEventListSettings();
diff --git a/src/java/com/android/internal/telephony/cat/CatService.java b/src/java/com/android/internal/telephony/cat/CatService.java
index 50ceaac..e24a408 100644
--- a/src/java/com/android/internal/telephony/cat/CatService.java
+++ b/src/java/com/android/internal/telephony/cat/CatService.java
@@ -541,7 +541,7 @@
private void broadcastCatCmdIntent(CatCmdMessage cmdMsg) {
Intent intent = new Intent(AppInterface.CAT_CMD_ACTION);
- intent.putExtra("STK CMD", cmdMsg);
+ intent.putExtra( "STK CMD", cmdMsg);
intent.putExtra("SLOT_ID", mSlotId);
intent.setComponent(AppInterface.getDefaultSTKApplication());
CatLog.d(this, "Sending CmdMsg: " + cmdMsg+ " on slotid:" + mSlotId);
diff --git a/src/java/com/android/internal/telephony/cat/CommandDetails.java b/src/java/com/android/internal/telephony/cat/CommandDetails.java
index d7c511a..dd1bbcf 100644
--- a/src/java/com/android/internal/telephony/cat/CommandDetails.java
+++ b/src/java/com/android/internal/telephony/cat/CommandDetails.java
@@ -28,7 +28,7 @@
* Class for Command Details object of proactive commands from SIM.
* {@hide}
*/
-class CommandDetails extends ValueObject implements Parcelable {
+public class CommandDetails extends ValueObject implements Parcelable {
@UnsupportedAppUsage
public boolean compRequired;
@UnsupportedAppUsage
diff --git a/src/java/com/android/internal/telephony/cat/Input.java b/src/java/com/android/internal/telephony/cat/Input.java
index aaaff43..e9103b8 100644
--- a/src/java/com/android/internal/telephony/cat/Input.java
+++ b/src/java/com/android/internal/telephony/cat/Input.java
@@ -58,7 +58,7 @@
private Input(Parcel in) {
text = in.readString();
defaultText = in.readString();
- icon = in.readParcelable(null);
+ icon = in.readParcelable(Bitmap.class.getClassLoader());
minLen = in.readInt();
maxLen = in.readInt();
ucs2 = in.readInt() == 1 ? true : false;
diff --git a/src/java/com/android/internal/telephony/cat/Item.java b/src/java/com/android/internal/telephony/cat/Item.java
index 456a46f..702ed4b 100644
--- a/src/java/com/android/internal/telephony/cat/Item.java
+++ b/src/java/com/android/internal/telephony/cat/Item.java
@@ -46,7 +46,7 @@
public Item(Parcel in) {
id = in.readInt();
text = in.readString();
- icon = in.readParcelable(null);
+ icon = in.readParcelable(Bitmap.class.getClassLoader());
}
@Override
diff --git a/src/java/com/android/internal/telephony/cat/Menu.java b/src/java/com/android/internal/telephony/cat/Menu.java
index a93fd1f..f1d19b5 100644
--- a/src/java/com/android/internal/telephony/cat/Menu.java
+++ b/src/java/com/android/internal/telephony/cat/Menu.java
@@ -58,12 +58,12 @@
private Menu(Parcel in) {
title = in.readString();
- titleIcon = in.readParcelable(null);
+ titleIcon = in.readParcelable(Bitmap.class.getClassLoader());
// rebuild items list.
items = new ArrayList<Item>();
int size = in.readInt();
for (int i=0; i<size; i++) {
- Item item = in.readParcelable(null);
+ Item item = in.readParcelable(Item.class.getClassLoader());
items.add(item);
}
defaultItem = in.readInt();
diff --git a/src/java/com/android/internal/telephony/cat/TextMessage.java b/src/java/com/android/internal/telephony/cat/TextMessage.java
index eddca4c..e7c2da6 100644
--- a/src/java/com/android/internal/telephony/cat/TextMessage.java
+++ b/src/java/com/android/internal/telephony/cat/TextMessage.java
@@ -40,7 +40,7 @@
private TextMessage(Parcel in) {
title = in.readString();
text = in.readString();
- icon = in.readParcelable(null);
+ icon = in.readParcelable(Bitmap.class.getClassLoader());
iconSelfExplanatory = in.readInt() == 1 ? true : false;
isHighPriority = in.readInt() == 1 ? true : false;
responseNeeded = in.readInt() == 1 ? true : false;
diff --git a/src/java/com/android/internal/telephony/cat/ToneSettings.java b/src/java/com/android/internal/telephony/cat/ToneSettings.java
index 61c1573..4e94ead 100644
--- a/src/java/com/android/internal/telephony/cat/ToneSettings.java
+++ b/src/java/com/android/internal/telephony/cat/ToneSettings.java
@@ -35,8 +35,8 @@
}
private ToneSettings(Parcel in) {
- duration = in.readParcelable(null);
- tone = in.readParcelable(null);
+ duration = in.readParcelable(Duration.class.getClassLoader());
+ tone = in.readParcelable(Tone.class.getClassLoader());
vibrate = in.readInt() == 1;
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
index ae8dd62..e3b325c 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
@@ -24,6 +24,7 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.nullable;
import static org.mockito.Mockito.anyBoolean;
@@ -33,6 +34,7 @@
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -66,6 +68,7 @@
import com.android.internal.telephony.test.SimulatedCommands;
import com.android.internal.telephony.uicc.IccCardApplicationStatus;
+import com.android.internal.telephony.uicc.IccCardStatus;
import com.android.internal.telephony.uicc.IccRecords;
import com.android.internal.telephony.uicc.IccVmNotSupportedException;
import com.android.internal.telephony.uicc.UiccController;
@@ -89,6 +92,10 @@
public class GsmCdmaPhoneTest extends TelephonyTest {
@Mock
private Handler mTestHandler;
+ @Mock
+ private UiccSlot mUiccSlot;
+ @Mock
+ private CommandsInterface mMockCi;
//mPhoneUnderTest
private GsmCdmaPhone mPhoneUT;
@@ -1197,4 +1204,24 @@
CarrierConfigManager.KEY_USE_USIM_BOOL, true);
assertEquals(msisdn, mPhoneUT.getLine1Number());
}
+
+ @Test
+ @SmallTest
+ public void testEnableUiccApplications() throws Exception {
+ mPhoneUT.mCi = mMockCi;
+ // UiccSlot is null. Doing nothing.
+ mPhoneUT.enableUiccApplications(true, null);
+ verify(mMockCi, never()).enableUiccApplications(anyBoolean(), any());
+
+ // Card state is not PRESENT. Doing nothing.
+ doReturn(mUiccSlot).when(mUiccController).getUiccSlotForPhone(anyInt());
+ doReturn(IccCardStatus.CardState.CARDSTATE_ABSENT).when(mUiccSlot).getCardState();
+ mPhoneUT.enableUiccApplications(true, null);
+ verify(mMockCi, never()).enableUiccApplications(anyBoolean(), any());
+
+ doReturn(IccCardStatus.CardState.CARDSTATE_PRESENT).when(mUiccSlot).getCardState();
+ Message message = Message.obtain();
+ mPhoneUT.enableUiccApplications(true, message);
+ verify(mMockCi).enableUiccApplications(eq(true), eq(message));
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/RILTest.java b/tests/telephonytests/src/com/android/internal/telephony/RILTest.java
index fda30f5..cc1cb2c 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/RILTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/RILTest.java
@@ -26,6 +26,7 @@
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_DELETE_SMS_ON_SIM;
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_DEVICE_IDENTITY;
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_DTMF;
+import static com.android.internal.telephony.RILConstants.RIL_REQUEST_ENABLE_UICC_APPLICATIONS;
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION;
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_ENTER_SIM_PIN;
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_ENTER_SIM_PIN2;
@@ -40,6 +41,7 @@
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_RADIO_CAPABILITY;
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SIM_STATUS;
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SMSC_ADDRESS;
+import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_UICC_APPLICATIONS_ENABLEMENT;
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_HANGUP;
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND;
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND;
@@ -82,11 +84,14 @@
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -97,13 +102,13 @@
import android.hardware.radio.V1_0.CdmaSmsMessage;
import android.hardware.radio.V1_0.DataProfileInfo;
import android.hardware.radio.V1_0.GsmSmsMessage;
-import android.hardware.radio.V1_0.IRadio;
import android.hardware.radio.V1_0.ImsSmsMessage;
import android.hardware.radio.V1_0.NvWriteItem;
import android.hardware.radio.V1_0.RadioError;
import android.hardware.radio.V1_0.RadioResponseInfo;
import android.hardware.radio.V1_0.RadioResponseType;
import android.hardware.radio.V1_0.SmsWriteArgs;
+import android.hardware.radio.V1_5.IRadio;
import android.hardware.radio.deprecated.V1_0.IOemHook;
import android.net.ConnectivityManager;
import android.net.LinkAddress;
@@ -177,7 +182,12 @@
@Mock
private IOemHook mOemHookProxy;
- private HalVersion mRadioVersion = new HalVersion(1, 0);
+ private HalVersion mRadioVersionV10 = new HalVersion(1, 0);
+ private HalVersion mRadioVersionV11 = new HalVersion(1, 1);
+ private HalVersion mRadioVersionV12 = new HalVersion(1, 2);
+ private HalVersion mRadioVersionV13 = new HalVersion(1, 3);
+ private HalVersion mRadioVersionV14 = new HalVersion(1, 4);
+ private HalVersion mRadioVersionV15 = new HalVersion(1, 5);
private RIL mRILInstance;
private RIL mRILUnderTest;
@@ -273,7 +283,7 @@
doReturn(mOemHookProxy).when(mRILUnderTest).getOemHookProxy(any());
try {
- replaceInstance(RIL.class, "mRadioVersion", mRILUnderTest, mRadioVersion);
+ replaceInstance(RIL.class, "mRadioVersion", mRILUnderTest, mRadioVersionV10);
} catch (Exception e) {
}
}
@@ -2000,4 +2010,38 @@
assertTrue(result.equals(expected));
}
+
+ @Test
+ public void testEnableUiccApplications() throws Exception {
+ // Not supported on Radio 1.0.
+ mRILUnderTest.enableUiccApplications(false, obtainMessage());
+ verify(mRadioProxy, never()).enableUiccApplications(anyInt(), anyBoolean());
+
+ // Make radio version 1.5 to support the operation.
+ try {
+ replaceInstance(RIL.class, "mRadioVersion", mRILUnderTest, mRadioVersionV15);
+ } catch (Exception e) {
+ }
+ mRILUnderTest.enableUiccApplications(false, obtainMessage());
+ verify(mRadioProxy).enableUiccApplications(mSerialNumberCaptor.capture(), anyBoolean());
+ verifyRILResponse(mRILUnderTest, mSerialNumberCaptor.getValue(),
+ RIL_REQUEST_ENABLE_UICC_APPLICATIONS);
+ }
+
+ @Test
+ public void testAreUiccApplicationsEnabled() throws Exception {
+ // Not supported on Radio 1.0.
+ mRILUnderTest.areUiccApplicationsEnabled(obtainMessage());
+ verify(mRadioProxy, never()).areUiccApplicationsEnabled(mSerialNumberCaptor.capture());
+
+ // Make radio version 1.5 to support the operation.
+ try {
+ replaceInstance(RIL.class, "mRadioVersion", mRILUnderTest, mRadioVersionV15);
+ } catch (Exception e) {
+ }
+ mRILUnderTest.areUiccApplicationsEnabled(obtainMessage());
+ verify(mRadioProxy).areUiccApplicationsEnabled(mSerialNumberCaptor.capture());
+ verifyRILResponse(mRILUnderTest, mSerialNumberCaptor.getValue(),
+ RIL_REQUEST_GET_UICC_APPLICATIONS_ENABLEMENT);
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommandsVerifier.java b/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommandsVerifier.java
index 64b0c38..93077e3 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommandsVerifier.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommandsVerifier.java
@@ -1444,4 +1444,10 @@
@Override
public void stopNattKeepalive(int sessionHandle, Message result) {
}
+
+ @Override
+ public void registerUiccApplicationEnablementChanged(Handler h, int what, Object obj) {}
+
+ @Override
+ public void unregisterUiccApplicationEnablementChanged(Handler h) {}
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
index 609b028..899ffc8 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
@@ -60,6 +60,7 @@
import java.util.Comparator;
import java.util.List;
import java.util.Map;
+import java.util.UUID;
public class SubscriptionControllerTest extends TelephonyTest {
private static final int SINGLE_SIM = 1;
@@ -729,6 +730,57 @@
@Test
@SmallTest
+ public void testAddSubscriptionIntoGroupWithCarrierPrivilegePermission() throws Exception {
+ testInsertSim();
+ // Adding a second profile and mark as embedded.
+ // TODO b/123300875 slot index 1 is not expected to be valid
+ mSubscriptionControllerUT.addSubInfoRecord("test2", 1);
+ ContentValues values = new ContentValues();
+ values.put(SubscriptionManager.IS_EMBEDDED, 1);
+ mFakeTelephonyProvider.update(SubscriptionManager.CONTENT_URI, values,
+ SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + 2, null);
+ mSubscriptionControllerUT.refreshCachedActiveSubscriptionInfoList();
+
+ mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
+ mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE);
+
+ // Create group for sub 1.
+ int[] subIdList = new int[] {1};
+ doReturn(true).when(mTelephonyManager).hasCarrierPrivileges(1);
+ ParcelUuid groupId = mSubscriptionControllerUT.createSubscriptionGroup(
+ subIdList, "packageName1");
+
+ // Try to add sub 2 into group of sub 1.
+ // Should fail as it doesn't have carrier privilege on sub 2.
+ try {
+ mSubscriptionControllerUT.addSubscriptionsIntoGroup(
+ new int[] {2}, groupId, "packageName1");
+ fail("addSubscriptionsIntoGroup should fail with no permission on sub 2.");
+ } catch (SecurityException e) {
+ // Expected result.
+ }
+
+ doReturn(false).when(mTelephonyManager).hasCarrierPrivileges(1);
+ doReturn(true).when(mTelephonyManager).hasCarrierPrivileges(2);
+ // Try to add sub 2 into group of sub 1.
+ // Should fail as it doesn't have carrier privilege on sub 1.
+ try {
+ mSubscriptionControllerUT.addSubscriptionsIntoGroup(
+ new int[] {2}, groupId, "packageName2");
+ fail("addSubscriptionsIntoGroup should fail with no permission on the group (sub 1).");
+ } catch (SecurityException e) {
+ // Expected result.
+ }
+
+ doReturn(true).when(mTelephonyManager).hasCarrierPrivileges(1);
+ mSubscriptionControllerUT.addSubscriptionsIntoGroup(new int[] {2}, groupId, "packageName2");
+ List<SubscriptionInfo> infoList = mSubscriptionControllerUT
+ .getSubscriptionsInGroup(groupId, "packageName2");
+ assertEquals(2, infoList.size());
+ }
+
+ @Test
+ @SmallTest
public void testUpdateSubscriptionGroupWithCarrierPrivilegePermission() throws Exception {
testInsertSim();
// Adding a second profile and mark as embedded.
@@ -893,6 +945,15 @@
.getSubscriptionsInGroup(groupUuid, mContext.getOpPackageName());
assertEquals(1, infoList.size());
assertEquals(2, infoList.get(0).getSubscriptionId());
+
+ // Adding sub 1 into a non-existing UUID, which should be granted.
+ groupUuid = new ParcelUuid(UUID.randomUUID());
+ mSubscriptionControllerUT.addSubscriptionsIntoGroup(
+ subIdList, groupUuid, mContext.getOpPackageName());
+ infoList = mSubscriptionControllerUT
+ .getSubscriptionsInGroup(groupUuid, mContext.getOpPackageName());
+ assertEquals(1, infoList.size());
+ assertEquals(1, infoList.get(0).getSubscriptionId());
}
private void registerMockTelephonyRegistry() {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
index 3b23510..2dce712 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
@@ -27,6 +27,7 @@
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.nullable;
+import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.never;
@@ -806,8 +807,9 @@
SmsBroadcastUndelivered.initialize(mContext, mGsmInboundSmsHandler, mCdmaInboundSmsHandler);
// verify that a broadcast receiver is registered for current user (user == null) based on
- // implementation in ContextFixture
- verify(mContext, times(1)).registerReceiverAsUser(any(BroadcastReceiver.class),
+ // implementation in ContextFixture. registerReceiver may be called more than once (for
+ // example by GsmInboundSmsHandler if TEST_MODE is true)
+ verify(mContext, atLeastOnce()).registerReceiverAsUser(any(BroadcastReceiver.class),
eq((UserHandle)null), any(IntentFilter.class), eq((String)null), eq((Handler)null));
// wait for ScanRawTableThread